3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
5 This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
6 Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
7 Linux compatibility. It was provided by BusLogic in the form of 16 separate
8 source files, which would have unnecessarily cluttered the scsi directory, so
9 the individual files have been combined into this single file.
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
19 #include <linux/config.h>
22 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
36 #define CRCMASK 0xA001
40 #define FAILURE 0xFFFFFFFFL
43 typedef unsigned int UINT;
44 typedef unsigned long ULONG;
47 typedef unsigned short * ushort_ptr;
54 #define u08bits unsigned s08bits
55 #define u16bits unsigned s16bits
56 #define u32bits unsigned s32bits
60 #define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
61 #define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
66 typedef struct _SCCB *PSCCB;
67 typedef void (*CALL_BK_FN)(PSCCB);
70 typedef struct SCCBMgr_info {
72 unsigned char si_present;
73 unsigned char si_intvect;
76 unsigned short si_fw_revision;
77 unsigned short si_per_targ_init_sync;
78 unsigned short si_per_targ_fast_nego;
79 unsigned short si_per_targ_ultra_nego;
80 unsigned short si_per_targ_no_disc;
81 unsigned short si_per_targ_wide_nego;
82 unsigned short si_flags;
83 unsigned char si_card_family;
84 unsigned char si_bustype;
85 unsigned char si_card_model[3];
86 unsigned char si_relative_cardnum;
87 unsigned char si_reserved[4];
89 unsigned char si_XlatInfo[4];
90 ULONG si_reserved2[5];
91 ULONG si_secondary_range;
94 typedef SCCBMGR_INFO * PSCCBMGR_INFO;
97 #define SCSI_PARITY_ENA 0x0001
98 #define LOW_BYTE_TERM 0x0010
99 #define HIGH_BYTE_TERM 0x0020
100 #define BUSTYPE_PCI 0x3
102 #define SUPPORT_16TAR_32LUN 0x0002
103 #define SOFT_RESET 0x0004
104 #define EXTENDED_TRANSLATION 0x0008
105 #define POST_ALL_UNDERRRUNS 0x0040
106 #define FLAG_SCAM_ENABLED 0x0080
107 #define FLAG_SCAM_LEVEL2 0x0100
112 #define HARPOON_FAMILY 0x02
116 /* SCCB struct used for both SCCB and UCB manager compiles!
117 * The UCB Manager treats the SCCB as it's 'native hardware structure'
122 typedef struct _SCCB {
123 unsigned char OperationCode;
124 unsigned char ControlByte;
125 unsigned char CdbLength;
126 unsigned char RequestSenseLength;
129 unsigned char CcbRes[2];
130 unsigned char HostStatus;
131 unsigned char TargetStatus;
132 unsigned char TargID;
134 unsigned char Cdb[12];
135 unsigned char CcbRes1;
136 unsigned char Reserved1;
141 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
142 ULONG SccbIOPort; /* Identifies board base port */
143 unsigned char SccbStatus;
144 unsigned char SCCBRes2;
145 unsigned short SccbOSFlags;
148 ULONG Sccb_XferCnt; /* actual transfer count */
150 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
152 unsigned short Sccb_MGRFlags;
153 unsigned short Sccb_sgseg;
154 unsigned char Sccb_scsimsg; /* identify msg for selection */
155 unsigned char Sccb_tag;
156 unsigned char Sccb_scsistat;
157 unsigned char Sccb_idmsg; /* image of last msg in */
158 PSCCB Sccb_forwardlink;
161 unsigned char Save_Cdb[6];
162 unsigned char Save_CdbLen;
163 unsigned char Sccb_XferState;
172 #define SCATTER_GATHER_COMMAND 0x02
173 #define RESIDUAL_COMMAND 0x03
174 #define RESIDUAL_SG_COMMAND 0x04
175 #define RESET_COMMAND 0x81
178 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
179 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
180 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
181 #define SCCB_DATA_XFER_IN 0x08 /* Read */
184 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
187 #define BUS_FREE_ST 0
189 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
190 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
191 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
192 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
194 #define DATA_OUT_ST 7
196 #define DISCONNECT_ST 9
200 #define F_HOST_XFER_DIR 0x01
201 #define F_ALL_XFERRED 0x02
202 #define F_SG_XFER 0x04
203 #define F_AUTO_SENSE 0x08
204 #define F_ODD_BALL_CNT 0x10
205 #define F_NO_DATA_YET 0x80
208 #define F_STATUSLOADED 0x01
209 #define F_DEV_SELECTED 0x04
212 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
213 #define SCCB_DATA_UNDER_RUN 0x0C
214 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
215 #define SCCB_DATA_OVER_RUN 0x12
216 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
218 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
219 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
220 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
226 #define SCCB_IN_PROCESS 0x00
227 #define SCCB_SUCCESS 0x01
228 #define SCCB_ABORT 0x02
229 #define SCCB_ERROR 0x04
233 #define ORION_FW_REV 3110
237 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
239 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
242 #define MAX_SCSI_TAR 16
244 #define LUN_MASK 0x1f
246 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
248 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
251 #define RD_HARPOON(ioport) inb((u32bits)ioport)
252 #define RDW_HARPOON(ioport) inw((u32bits)ioport)
253 #define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
254 #define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
255 #define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
256 #define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
259 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
260 #define SYNC_TRYING BIT(6)
261 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
263 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
264 #define WIDE_ENABLED BIT(4)
265 #define WIDE_NEGOCIATED BIT(5)
267 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
268 #define TAG_Q_TRYING BIT(2)
269 #define TAG_Q_REJECT BIT(3)
271 #define TAR_ALLOW_DISC BIT(0)
274 #define EE_SYNC_MASK (BIT(0)+BIT(1))
275 #define EE_SYNC_5MB BIT(0)
276 #define EE_SYNC_10MB BIT(1)
277 #define EE_SYNC_20MB (BIT(0)+BIT(1))
279 #define EE_WIDE_SCSI BIT(7)
282 typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
285 typedef struct SCCBMgr_tar_info {
289 unsigned char TarLUN_CA; /*Contingent Allgiance */
290 unsigned char TarTagQ_Cnt;
291 unsigned char TarSelQ_Cnt;
292 unsigned char TarStatus;
293 unsigned char TarEEValue;
294 unsigned char TarSyncCtrl;
295 unsigned char TarReserved[2]; /* for alignment */
296 unsigned char LunDiscQ_Idx[MAX_LUN];
297 unsigned char TarLUNBusy[MAX_LUN];
300 typedef struct NVRAMInfo {
301 unsigned char niModel; /* Model No. of card */
302 unsigned char niCardNo; /* Card no. */
303 ULONG niBaseAddr; /* Port Address of card */
304 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
305 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
306 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
307 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
308 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
309 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
312 typedef NVRAMINFO *PNVRamInfo;
320 typedef struct SCCBcard {
322 PSCCBMGR_INFO cardInfo;
326 unsigned short cmdCounter;
327 unsigned char discQCount;
328 unsigned char tagQ_Lst;
329 unsigned char cardIndex;
330 unsigned char scanIndex;
331 unsigned char globalFlags;
333 PNVRamInfo pNvRamInfo;
334 PSCCB discQ_Tbl[QUEUE_DEPTH];
338 typedef struct SCCBcard *PSCCBcard;
341 #define F_TAG_STARTED 0x01
342 #define F_CONLUN_IO 0x02
343 #define F_DO_RENEGO 0x04
344 #define F_NO_FILTER 0x08
345 #define F_GREEN_PC 0x10
346 #define F_HOST_XFER_ACT 0x20
347 #define F_NEW_SCCB_CMD 0x40
348 #define F_UPDATE_EEPROM 0x80
351 #define ID_STRING_LENGTH 32
352 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
355 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
357 #define ASSIGN_ID 0x00
358 #define SET_P_FLAG 0x01
359 #define CFG_CMPLT 0x03
360 #define DOM_MSTR 0x0F
361 #define SYNC_PTRN 0x1F
365 #define MISC_CODE 0x14
366 #define CLR_P_FLAG 0x18
370 #define INIT_SELTD 0x01
371 #define LEVEL2_TAR 0x02
374 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
375 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
376 CLR_PRIORITY,NO_ID_AVAIL };
378 typedef struct SCCBscam_info {
380 unsigned char id_string[ID_STRING_LENGTH];
381 enum scam_id_st state;
386 #define SCSI_REQUEST_SENSE 0x03
387 #define SCSI_READ 0x08
388 #define SCSI_WRITE 0x0A
389 #define SCSI_START_STOP_UNIT 0x1B
390 #define SCSI_READ_EXTENDED 0x28
391 #define SCSI_WRITE_EXTENDED 0x2A
392 #define SCSI_WRITE_AND_VERIFY 0x2E
398 #define SSQ_FULL 0x28
403 #define SMCMD_COMP 0x00
405 #define SMSAVE_DATA_PTR 0x02
406 #define SMREST_DATA_PTR 0x03
409 #define SMREJECT 0x07
411 #define SMPARITY 0x09
412 #define SMDEV_RESET 0x0C
413 #define SMABORT_TAG 0x0D
414 #define SMINIT_RECOVERY 0x0F
415 #define SMREL_RECOVERY 0x10
418 #define DISC_PRIV 0x40
425 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
434 #define SIX_BYTE_CMD 0x06
435 #define TWELVE_BYTE_CMD 0x0C
438 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
441 #define EEPROM_WD_CNT 256
443 #define EEPROM_CHECK_SUM 0
444 #define FW_SIGNATURE 2
445 #define MODEL_NUMB_0 4
446 #define MODEL_NUMB_2 6
447 #define MODEL_NUMB_4 8
448 #define SYSTEM_CONFIG 16
449 #define SCSI_CONFIG 17
450 #define BIOS_CONFIG 18
451 #define SCAM_CONFIG 20
452 #define ADAPTER_SCSI_ID 24
455 #define IGNORE_B_SCAN 32
456 #define SEND_START_ENA 34
457 #define DEVICE_ENABLE 36
459 #define SYNC_RATE_TBL 38
460 #define SYNC_RATE_TBL01 38
461 #define SYNC_RATE_TBL23 40
462 #define SYNC_RATE_TBL45 42
463 #define SYNC_RATE_TBL67 44
464 #define SYNC_RATE_TBL89 46
465 #define SYNC_RATE_TBLab 48
466 #define SYNC_RATE_TBLcd 50
467 #define SYNC_RATE_TBLef 52
471 #define EE_SCAMBASE 256
475 #define SCAM_ENABLED BIT(2)
476 #define SCAM_LEVEL2 BIT(3)
479 #define RENEGO_ENA BITW(10)
480 #define CONNIO_ENA BITW(11)
481 #define GREEN_PC_ENA BITW(12)
484 #define AUTO_RATE_00 00
485 #define AUTO_RATE_05 01
486 #define AUTO_RATE_10 02
487 #define AUTO_RATE_20 03
489 #define WIDE_NEGO_BIT BIT(7)
490 #define DISC_ENABLE_BIT BIT(6)
494 #define hp_vendor_id_0 0x00 /* LSB */
495 #define ORION_VEND_0 0x4B
497 #define hp_vendor_id_1 0x01 /* MSB */
498 #define ORION_VEND_1 0x10
500 #define hp_device_id_0 0x02 /* LSB */
501 #define ORION_DEV_0 0x30
503 #define hp_device_id_1 0x03 /* MSB */
504 #define ORION_DEV_1 0x81
506 /* Sub Vendor ID and Sub Device ID only available in
507 Harpoon Version 2 and higher */
509 #define hp_sub_device_id_0 0x06 /* LSB */
513 #define hp_semaphore 0x0C
514 #define SCCB_MGR_ACTIVE BIT(0)
515 #define TICKLE_ME BIT(1)
516 #define SCCB_MGR_PRESENT BIT(3)
517 #define BIOS_IN_USE BIT(4)
521 #define hp_sys_ctrl 0x0F
523 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
524 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
525 #define HALT_MACH BIT(3) /*Halt State Machine */
526 #define HARD_ABORT BIT(4) /*Hard Abort */
536 #define hp_host_blk_cnt 0x13
538 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
540 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
544 #define hp_int_mask 0x17
546 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
547 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
550 #define hp_xfer_cnt_lo 0x18
551 #define hp_xfer_cnt_hi 0x1A
552 #define hp_xfer_cmd 0x1B
554 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
555 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
558 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
560 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
562 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
564 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
565 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
567 #define hp_host_addr_lo 0x1C
568 #define hp_host_addr_hmi 0x1E
570 #define hp_ee_ctrl 0x22
572 #define EXT_ARB_ACK BIT(7)
573 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
574 #define SEE_MS BIT(5)
575 #define SEE_CS BIT(3)
576 #define SEE_CLK BIT(2)
577 #define SEE_DO BIT(1)
578 #define SEE_DI BIT(0)
581 #define EE_WRITE 0x05
583 #define EWEN_ADDR 0x03C0
585 #define EWDS_ADDR 0x0000
593 #define hp_bm_ctrl 0x26
595 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
596 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
597 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
598 #define FAST_SINGLE BIT(6) /*?? */
600 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
603 #define hp_sg_addr 0x28
604 #define hp_page_ctrl 0x29
606 #define SCATTER_EN BIT(0)
607 #define SGRAM_ARAM BIT(1)
608 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
609 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
614 #define hp_pci_stat_cfg 0x2D
616 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
625 #define hp_rev_num 0x33
628 #define hp_stack_data 0x34
629 #define hp_stack_addr 0x35
631 #define hp_ext_status 0x36
633 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
634 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
635 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
636 #define CMD_ABORTED BIT(4) /*Command aborted */
637 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
638 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
639 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
640 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
641 BM_PARITY_ERR | PIO_OVERRUN)
643 #define hp_int_status 0x37
645 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
646 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
647 #define INT_ASSERTED BIT(5) /* */
650 #define hp_fifo_cnt 0x38
655 #define hp_intena 0x40
657 #define RESET BITW(7)
658 #define PROG_HLT BITW(6)
659 #define PARITY BITW(5)
662 #define SCAM_SEL BITW(2)
664 #define TIMEOUT BITW(0)
665 #define BUS_FREE BITW(15)
666 #define XFER_CNT_0 BITW(14)
667 #define PHASE BITW(13)
668 #define IUNKWN BITW(12)
669 #define ICMD_COMP BITW(11)
670 #define ITICKLE BITW(10)
671 #define IDO_STRT BITW(9)
672 #define ITAR_DISC BITW(8)
673 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
674 #define CLR_ALL_INT 0xFFFF
675 #define CLR_ALL_INT_1 0xFF00
677 #define hp_intstat 0x42
679 #define hp_scsisig 0x44
681 #define SCSI_SEL BIT(7)
682 #define SCSI_BSY BIT(6)
683 #define SCSI_REQ BIT(5)
684 #define SCSI_ACK BIT(4)
685 #define SCSI_ATN BIT(3)
686 #define SCSI_CD BIT(2)
687 #define SCSI_MSG BIT(1)
688 #define SCSI_IOBIT BIT(0)
690 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
691 #define S_MSGO_PH (BIT(2)+BIT(1) )
692 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
693 #define S_DATAI_PH ( BIT(0))
694 #define S_DATAO_PH 0x00
695 #define S_ILL_PH ( BIT(1) )
697 #define hp_scsictrl_0 0x45
699 #define SEL_TAR BIT(6)
700 #define ENA_ATN BIT(4)
701 #define ENA_RESEL BIT(2)
702 #define SCSI_RST BIT(1)
703 #define ENA_SCAM_SEL BIT(0)
707 #define hp_portctrl_0 0x46
709 #define SCSI_PORT BIT(7)
710 #define SCSI_INBIT BIT(6)
711 #define DMA_PORT BIT(5)
712 #define DMA_RD BIT(4)
713 #define HOST_PORT BIT(3)
714 #define HOST_WRT BIT(2)
715 #define SCSI_BUS_EN BIT(1)
716 #define START_TO BIT(0)
718 #define hp_scsireset 0x47
720 #define SCSI_INI BIT(6)
721 #define SCAM_EN BIT(5)
722 #define DMA_RESET BIT(3)
723 #define HPSCSI_RESET BIT(2)
724 #define PROG_RESET BIT(1)
725 #define FIFO_CLR BIT(0)
727 #define hp_xfercnt_0 0x48
728 #define hp_xfercnt_2 0x4A
730 #define hp_fifodata_0 0x4C
731 #define hp_addstat 0x4E
733 #define SCAM_TIMER BIT(7)
734 #define SCSI_MODE8 BIT(3)
735 #define SCSI_PAR_ERR BIT(0)
737 #define hp_prgmcnt_0 0x4F
740 #define hp_selfid_0 0x50
741 #define hp_selfid_1 0x51
742 #define hp_arb_id 0x52
745 #define hp_select_id 0x53
748 #define hp_synctarg_base 0x54
749 #define hp_synctarg_12 0x54
750 #define hp_synctarg_13 0x55
751 #define hp_synctarg_14 0x56
752 #define hp_synctarg_15 0x57
754 #define hp_synctarg_8 0x58
755 #define hp_synctarg_9 0x59
756 #define hp_synctarg_10 0x5A
757 #define hp_synctarg_11 0x5B
759 #define hp_synctarg_4 0x5C
760 #define hp_synctarg_5 0x5D
761 #define hp_synctarg_6 0x5E
762 #define hp_synctarg_7 0x5F
764 #define hp_synctarg_0 0x60
765 #define hp_synctarg_1 0x61
766 #define hp_synctarg_2 0x62
767 #define hp_synctarg_3 0x63
769 #define NARROW_SCSI BIT(4)
770 #define DEFAULT_OFFSET 0x0F
772 #define hp_autostart_0 0x64
773 #define hp_autostart_1 0x65
774 #define hp_autostart_3 0x67
778 #define AUTO_IMMED BIT(5)
779 #define SELECT BIT(6)
780 #define END_DATA (BIT(7)+BIT(6))
782 #define hp_gp_reg_0 0x68
783 #define hp_gp_reg_1 0x69
784 #define hp_gp_reg_3 0x6B
786 #define hp_seltimeout 0x6C
789 #define TO_4ms 0x67 /* 3.9959ms */
791 #define TO_5ms 0x03 /* 4.9152ms */
792 #define TO_10ms 0x07 /* 11.xxxms */
793 #define TO_250ms 0x99 /* 250.68ms */
794 #define TO_290ms 0xB1 /* 289.99ms */
796 #define hp_clkctrl_0 0x6D
798 #define PWR_DWN BIT(6)
799 #define ACTdeassert BIT(4)
800 #define CLK_40MHZ (BIT(1) + BIT(0))
802 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
804 #define hp_fiforead 0x6E
805 #define hp_fifowrite 0x6F
807 #define hp_offsetctr 0x70
808 #define hp_xferstat 0x71
810 #define FIFO_EMPTY BIT(6)
812 #define hp_portctrl_1 0x72
814 #define CHK_SCSI_P BIT(3)
815 #define HOST_MODE8 BIT(0)
817 #define hp_xfer_pad 0x73
819 #define ID_UNLOCK BIT(3)
821 #define hp_scsidata_0 0x74
822 #define hp_scsidata_1 0x75
826 #define hp_aramBase 0x80
827 #define BIOS_DATA_OFFSET 0x60
828 #define BIOS_RELATIVE_CARD 0x64
833 #define AR3 (BITW(9) + BITW(8))
834 #define SDATA BITW(10)
837 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
839 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
843 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
845 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
848 #define ADATA_OUT 0x00
849 #define ADATA_IN BITW(8)
850 #define ACOMMAND BITW(10)
851 #define ASTATUS (BITW(10)+BITW(8))
852 #define AMSG_OUT (BITW(10)+BITW(9))
853 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
856 #define BRH_OP BITW(13) /* Branch */
860 #define EQUAL BITW(8)
861 #define NOT_EQ BITW(9)
863 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
866 #define FIFO_0 BITW(10)
869 #define MPM_OP BITW(15) /* Match phase and move data */
872 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
875 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
880 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
890 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
892 #define SSI_OP (BITW(15)+BITW(11))
895 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
896 #define SSI_IDO_STRT (IDO_STRT >> 8)
898 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
899 #define SSI_ITICKLE (ITICKLE >> 8)
901 #define SSI_IUNKWN (IUNKWN >> 8)
902 #define SSI_INO_CC (IUNKWN >> 8)
903 #define SSI_IRFAIL (IUNKWN >> 8)
906 #define NP 0x10 /*Next Phase */
907 #define NTCMD 0x02 /*Non- Tagged Command start */
908 #define CMDPZ 0x04 /*Command phase */
909 #define DINT 0x12 /*Data Out/In interrupt */
910 #define DI 0x13 /*Data Out */
911 #define DC 0x19 /*Disconnect Message */
912 #define ST 0x1D /*Status Phase */
913 #define UNKNWN 0x24 /*Unknown bus action */
914 #define CC 0x25 /*Command Completion failure */
915 #define TICK 0x26 /*New target reselected us. */
916 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
919 #define ID_MSG_STRT hp_aramBase + 0x00
920 #define NON_TAG_ID_MSG hp_aramBase + 0x06
921 #define CMD_STRT hp_aramBase + 0x08
922 #define SYNC_MSGS hp_aramBase + 0x08
928 #define TAG_STRT 0x00
929 #define DISCONNECT_START 0x10/2
930 #define END_DATA_START 0x14/2
931 #define CMD_ONLY_STRT CMDPZ/2
932 #define SELCHK_STRT SELCHK/2
942 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
943 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
945 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
947 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
949 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
950 WR_HARP32(port,hp_xfercnt_0,count),\
951 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
953 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
955 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
956 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
959 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
960 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
964 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
965 WR_HARPOON(port+hp_scsireset, 0x00))
967 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
968 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
970 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
971 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
973 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
974 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
976 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
977 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
982 static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag);
983 static void FPT_ssel(ULONG port, unsigned char p_card);
984 static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard);
985 static void FPT_shandem(ULONG port, unsigned char p_card,PSCCB pCurrSCCB);
986 static void FPT_stsyncn(ULONG port, unsigned char p_card);
987 static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset);
988 static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
989 PSCCBMgr_tar_info currTar_Info);
990 static void FPT_sresb(ULONG port, unsigned char p_card);
991 static void FPT_sxfrp(ULONG p_port, unsigned char p_card);
992 static void FPT_schkdd(ULONG port, unsigned char p_card);
993 static unsigned char FPT_RdStack(ULONG port, unsigned char index);
994 static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data);
995 static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort);
997 static void FPT_SendMsg(ULONG port, unsigned char message);
998 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
999 unsigned char error_code);
1001 static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
1002 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
1004 static unsigned char FPT_siwidn(ULONG port, unsigned char p_card);
1005 static void FPT_stwidn(ULONG port, unsigned char p_card);
1006 static void FPT_siwidr(ULONG port, unsigned char width);
1009 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1010 static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
1011 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1012 unsigned char p_card);
1013 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1014 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1015 static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1016 static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
1017 static void FPT_utilUpdateResidual(PSCCB p_SCCB);
1018 static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
1019 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
1022 static void FPT_Wait1Second(ULONG p_port);
1023 static void FPT_Wait(ULONG p_port, unsigned char p_delay);
1024 static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode);
1025 static void FPT_utilEEWrite(ULONG p_port, unsigned short ee_data, unsigned short ee_addr);
1026 static unsigned short FPT_utilEERead(ULONG p_port, unsigned short ee_addr);
1027 static unsigned short FPT_utilEEReadOrg(ULONG p_port, unsigned short ee_addr);
1028 static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, unsigned short ee_addr);
1032 static void FPT_phaseDataOut(ULONG port, unsigned char p_card);
1033 static void FPT_phaseDataIn(ULONG port, unsigned char p_card);
1034 static void FPT_phaseCommand(ULONG port, unsigned char p_card);
1035 static void FPT_phaseStatus(ULONG port, unsigned char p_card);
1036 static void FPT_phaseMsgOut(ULONG port, unsigned char p_card);
1037 static void FPT_phaseMsgIn(ULONG port, unsigned char p_card);
1038 static void FPT_phaseIllegal(ULONG port, unsigned char p_card);
1040 static void FPT_phaseDecode(ULONG port, unsigned char p_card);
1041 static void FPT_phaseChkFifo(ULONG port, unsigned char p_card);
1042 static void FPT_phaseBusFree(ULONG p_port, unsigned char p_card);
1047 static void FPT_XbowInit(ULONG port, unsigned char scamFlg);
1048 static void FPT_BusMasterInit(ULONG p_port);
1049 static void FPT_DiagEEPROM(ULONG p_port);
1054 static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1055 static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1056 static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
1057 static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB);
1058 static void FPT_hostDataXferRestart(PSCCB currSCCB);
1061 static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
1062 PSCCBcard pCurrCard, unsigned short p_int);
1064 static void FPT_SccbMgrTableInitAll(void);
1065 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1066 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
1070 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
1072 static int FPT_scarb(ULONG p_port, unsigned char p_sel_type);
1073 static void FPT_scbusf(ULONG p_port);
1074 static void FPT_scsel(ULONG p_port);
1075 static void FPT_scasid(unsigned char p_card, ULONG p_port);
1076 static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data);
1077 static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[]);
1078 static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[]);
1079 static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit);
1080 static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit);
1081 static unsigned char FPT_scvalq(unsigned char p_quintet);
1082 static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id);
1083 static void FPT_scwtsel(ULONG p_port);
1084 static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id);
1085 static void FPT_scsavdi(unsigned char p_card, ULONG p_port);
1086 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
1089 static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card);
1090 static void FPT_autoLoadDefaultMap(ULONG p_port);
1095 static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1096 static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1097 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1098 static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1101 static unsigned char FPT_mbCards = 0;
1102 static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1103 ' ', 'B', 'T', '-', '9', '3', '0', \
1104 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1105 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1107 static unsigned short FPT_default_intena = 0;
1110 static void (*FPT_s_PhaseTbl[8]) (ULONG, unsigned char)= { 0 };
1113 /*---------------------------------------------------------------------
1115 * Function: FlashPoint_ProbeHostAdapter
1117 * Description: Setup and/or Search for cards and return info to caller.
1119 *---------------------------------------------------------------------*/
1121 static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
1123 static unsigned char first_time = 1;
1125 unsigned char i,j,id,ScamFlg;
1126 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
1128 PNVRamInfo pCurrNvRam;
1130 ioport = pCardInfo->si_baseaddr;
1133 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1134 return((int)FAILURE);
1136 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1137 return((int)FAILURE);
1139 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1140 return((int)FAILURE);
1142 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1143 return((int)FAILURE);
1146 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1148 /* For new Harpoon then check for sub_device ID LSB
1149 the bits(0-3) must be all ZERO for compatible with
1150 current version of SCCBMgr, else skip this Harpoon
1153 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1154 return((int)FAILURE);
1159 FPT_SccbMgrTableInitAll();
1164 if(FPT_RdStack(ioport, 0) != 0x00) {
1165 if(FPT_ChkIfChipInitialized(ioport) == 0)
1168 WR_HARPOON(ioport+hp_semaphore, 0x00);
1169 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1170 FPT_DiagEEPROM(ioport);
1174 if(FPT_mbCards < MAX_MB_CARDS) {
1175 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1177 pCurrNvRam->niBaseAddr = ioport;
1178 FPT_RNVRamData(pCurrNvRam);
1180 return((int) FAILURE);
1185 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1186 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1189 pCardInfo->si_id = pCurrNvRam->niAdapId;
1191 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1192 (unsigned char)0x0FF);
1194 pCardInfo->si_lun = 0x00;
1195 pCardInfo->si_fw_revision = ORION_FW_REV;
1202 for (id = 0; id < (16/2); id++) {
1205 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1206 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1207 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1209 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1211 for (i = 0; i < 2; temp >>=8,i++) {
1220 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1221 temp6 |= 0x8000; /* Fall through */
1222 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1223 temp5 |= 0x8000; /* Fall through */
1224 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1225 temp2 |= 0x8000; /* Fall through */
1226 case AUTO_RATE_00: /* Asynchronous */
1230 if (temp & DISC_ENABLE_BIT)
1233 if (temp & WIDE_NEGO_BIT)
1239 pCardInfo->si_per_targ_init_sync = temp2;
1240 pCardInfo->si_per_targ_no_disc = temp3;
1241 pCardInfo->si_per_targ_wide_nego = temp4;
1242 pCardInfo->si_per_targ_fast_nego = temp5;
1243 pCardInfo->si_per_targ_ultra_nego = temp6;
1246 i = pCurrNvRam->niSysConf;
1248 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1251 ScamFlg = pCurrNvRam->niScamConf;
1253 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1255 pCardInfo->si_flags = 0x0000;
1258 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1261 pCardInfo->si_flags |= SOFT_RESET;
1264 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1266 if (ScamFlg & SCAM_ENABLED)
1267 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1269 if (ScamFlg & SCAM_LEVEL2)
1270 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1272 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1274 j |= SCSI_TERM_ENA_L;
1276 WR_HARPOON(ioport+hp_bm_ctrl, j );
1278 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1280 j |= SCSI_TERM_ENA_H;
1282 WR_HARPOON(ioport+hp_ee_ctrl, j );
1284 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1286 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1288 pCardInfo->si_card_family = HARPOON_FAMILY;
1289 pCardInfo->si_bustype = BUSTYPE_PCI;
1292 pCardInfo->si_card_model[0] = '9';
1293 switch(pCurrNvRam->niModel & 0x0f){
1295 pCardInfo->si_card_model[1] = '3';
1296 pCardInfo->si_card_model[2] = '0';
1299 pCardInfo->si_card_model[1] = '5';
1300 pCardInfo->si_card_model[2] = '0';
1303 pCardInfo->si_card_model[1] = '3';
1304 pCardInfo->si_card_model[2] = '2';
1307 pCardInfo->si_card_model[1] = '5';
1308 pCardInfo->si_card_model[2] = '2';
1312 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1313 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1314 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1316 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1317 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1320 if (pCardInfo->si_card_model[1] == '3')
1322 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1323 pCardInfo->si_flags |= LOW_BYTE_TERM;
1325 else if (pCardInfo->si_card_model[2] == '0')
1327 temp = RD_HARPOON(ioport+hp_xfer_pad);
1328 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1329 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1330 pCardInfo->si_flags |= LOW_BYTE_TERM;
1331 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1332 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1333 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1334 WR_HARPOON(ioport+hp_xfer_pad, temp);
1338 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1339 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1340 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1341 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1343 for (i = 0; i < 8; i++)
1346 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1348 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1349 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1351 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1352 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1353 if (!(temp3 & BIT(7)))
1354 pCardInfo->si_flags |= LOW_BYTE_TERM;
1355 if (!(temp3 & BIT(6)))
1356 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1360 ARAM_ACCESS(ioport);
1362 for ( i = 0; i < 4; i++ ) {
1364 pCardInfo->si_XlatInfo[i] =
1365 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1368 /* return with -1 if no sort, else return with
1369 logical card number sorted by BIOS (zero-based) */
1371 pCardInfo->si_relative_cardnum =
1372 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1374 SGRAM_ACCESS(ioport);
1376 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1377 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1378 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1379 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1380 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1381 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1382 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1383 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1385 pCardInfo->si_present = 0x01;
1391 /*---------------------------------------------------------------------
1393 * Function: FlashPoint_HardwareResetHostAdapter
1395 * Description: Setup adapter for normal operation (hard reset).
1397 *---------------------------------------------------------------------*/
1399 static ULONG FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
1401 PSCCBcard CurrCard = NULL;
1402 PNVRamInfo pCurrNvRam;
1403 unsigned char i,j,thisCard, ScamFlg;
1404 unsigned short temp,sync_bit_map,id;
1407 ioport = pCardInfo->si_baseaddr;
1409 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1411 if (thisCard == MAX_CARDS) {
1416 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1418 CurrCard = &FPT_BL_Card[thisCard];
1419 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1423 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1425 FPT_BL_Card[thisCard].ioPort = ioport;
1426 CurrCard = &FPT_BL_Card[thisCard];
1429 for(i = 0; i < FPT_mbCards; i++){
1430 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1431 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1433 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1434 CurrCard->cardIndex = thisCard;
1435 CurrCard->cardInfo = pCardInfo;
1441 pCurrNvRam = CurrCard->pNvRamInfo;
1444 ScamFlg = pCurrNvRam->niScamConf;
1447 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1451 FPT_BusMasterInit(ioport);
1452 FPT_XbowInit(ioport, ScamFlg);
1454 FPT_autoLoadDefaultMap(ioport);
1457 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1459 WR_HARPOON(ioport+hp_selfid_0, id);
1460 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1461 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1462 CurrCard->ourId = pCardInfo->si_id;
1464 i = (unsigned char) pCardInfo->si_flags;
1465 if (i & SCSI_PARITY_ENA)
1466 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1468 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1469 if (i & LOW_BYTE_TERM)
1470 j |= SCSI_TERM_ENA_L;
1471 WR_HARPOON(ioport+hp_bm_ctrl, j);
1473 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1474 if (i & HIGH_BYTE_TERM)
1475 j |= SCSI_TERM_ENA_H;
1476 WR_HARPOON(ioport+hp_ee_ctrl, j );
1479 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1481 FPT_sresb(ioport,thisCard);
1483 FPT_scini(thisCard, pCardInfo->si_id, 0);
1488 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1489 CurrCard->globalFlags |= F_NO_FILTER;
1492 if(pCurrNvRam->niSysConf & 0x10)
1493 CurrCard->globalFlags |= F_GREEN_PC;
1496 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1497 CurrCard->globalFlags |= F_GREEN_PC;
1500 /* Set global flag to indicate Re-Negotiation to be done on all
1503 if(pCurrNvRam->niScsiConf & 0x04)
1504 CurrCard->globalFlags |= F_DO_RENEGO;
1507 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1508 CurrCard->globalFlags |= F_DO_RENEGO;
1512 if(pCurrNvRam->niScsiConf & 0x08)
1513 CurrCard->globalFlags |= F_CONLUN_IO;
1516 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1517 CurrCard->globalFlags |= F_CONLUN_IO;
1521 temp = pCardInfo->si_per_targ_no_disc;
1523 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1526 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1529 sync_bit_map = 0x0001;
1531 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1534 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1535 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1536 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1538 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1540 for (i = 0; i < 2; temp >>=8,i++) {
1542 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1544 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
1548 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1549 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1550 (unsigned char)(temp & ~EE_SYNC_MASK);
1553 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1556 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1558 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1562 else { /* NARROW SCSI */
1563 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1574 WR_HARPOON((ioport+hp_semaphore),
1575 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1577 return((ULONG)CurrCard);
1580 static void FlashPoint_ReleaseHostAdapter(ULONG pCurrCard)
1587 PNVRamInfo pCurrNvRam;
1589 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1592 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1593 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1594 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1595 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1596 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1598 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1599 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
1601 portBase = pCurrNvRam->niBaseAddr;
1603 for(i = 0; i < MAX_SCSI_TAR; i++){
1604 regOffset = hp_aramBase + 64 + i*4;
1605 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
1606 scamData = *pScamTbl;
1607 WR_HARP32(portBase, regOffset, scamData);
1611 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1616 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1624 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1625 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1626 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1627 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1628 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1630 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1631 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
1633 portBase = pNvRamInfo->niBaseAddr;
1635 for(i = 0; i < MAX_SCSI_TAR; i++){
1636 regOffset = hp_aramBase + 64 + i*4;
1637 RD_HARP32(portBase, regOffset, scamData);
1638 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
1639 *pScamTbl = scamData;
1644 static unsigned char FPT_RdStack(ULONG portBase, unsigned char index)
1646 WR_HARPOON(portBase + hp_stack_addr, index);
1647 return(RD_HARPOON(portBase + hp_stack_data));
1650 static void FPT_WrStack(ULONG portBase, unsigned char index, unsigned char data)
1652 WR_HARPOON(portBase + hp_stack_addr, index);
1653 WR_HARPOON(portBase + hp_stack_data, data);
1657 static unsigned char FPT_ChkIfChipInitialized(ULONG ioPort)
1659 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1661 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1664 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1665 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1670 /*---------------------------------------------------------------------
1672 * Function: FlashPoint_StartCCB
1674 * Description: Start a command pointed to by p_Sccb. When the
1675 * command is completed it will be returned via the
1676 * callback function.
1678 *---------------------------------------------------------------------*/
1679 static void FlashPoint_StartCCB(ULONG pCurrCard, PSCCB p_Sccb)
1682 unsigned char thisCard, lun;
1684 CALL_BK_FN callback;
1686 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1687 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1689 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1692 p_Sccb->HostStatus = SCCB_COMPLETE;
1693 p_Sccb->SccbStatus = SCCB_ERROR;
1694 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1701 FPT_sinits(p_Sccb,thisCard);
1704 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1706 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1707 | SCCB_MGR_ACTIVE));
1709 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1711 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1712 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1716 ((PSCCBcard)pCurrCard)->cmdCounter++;
1718 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1720 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1722 if(p_Sccb->OperationCode == RESET_COMMAND)
1724 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1725 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1726 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1727 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1731 FPT_queueAddSccb(p_Sccb,thisCard);
1735 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1737 if(p_Sccb->OperationCode == RESET_COMMAND)
1739 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1740 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1741 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1742 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1746 FPT_queueAddSccb(p_Sccb,thisCard);
1752 MDISABLE_INT(ioport);
1754 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
1755 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1759 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
1760 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1761 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1764 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1765 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1770 if(p_Sccb->OperationCode == RESET_COMMAND)
1772 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1773 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1774 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1775 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1779 FPT_queueAddSccb(p_Sccb,thisCard);
1784 MENABLE_INT(ioport);
1790 /*---------------------------------------------------------------------
1792 * Function: FlashPoint_AbortCCB
1794 * Description: Abort the command pointed to by p_Sccb. When the
1795 * command is completed it will be returned via the
1796 * callback function.
1798 *---------------------------------------------------------------------*/
1799 static int FlashPoint_AbortCCB(ULONG pCurrCard, PSCCB p_Sccb)
1803 unsigned char thisCard;
1804 CALL_BK_FN callback;
1807 PSCCBMgr_tar_info currTar_Info;
1810 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1812 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1814 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1817 if (FPT_queueFindSccb(p_Sccb,thisCard))
1820 ((PSCCBcard)pCurrCard)->cmdCounter--;
1822 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1823 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1824 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1826 p_Sccb->SccbStatus = SCCB_ABORT;
1827 callback = p_Sccb->SccbCallback;
1835 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1837 p_Sccb->SccbStatus = SCCB_ABORT;
1845 TID = p_Sccb->TargID;
1848 if(p_Sccb->Sccb_tag)
1850 MDISABLE_INT(ioport);
1851 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1853 p_Sccb->SccbStatus = SCCB_ABORT;
1854 p_Sccb->Sccb_scsistat = ABORT_ST;
1855 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1857 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1859 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1860 FPT_ssel(ioport, thisCard);
1864 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1865 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1866 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1867 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1870 MENABLE_INT(ioport);
1875 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1877 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1880 p_Sccb->SccbStatus = SCCB_ABORT;
1891 /*---------------------------------------------------------------------
1893 * Function: FlashPoint_InterruptPending
1895 * Description: Do a quick check to determine if there is a pending
1896 * interrupt for this card and disable the IRQ Pin if so.
1898 *---------------------------------------------------------------------*/
1899 static unsigned char FlashPoint_InterruptPending(ULONG pCurrCard)
1903 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1905 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1917 /*---------------------------------------------------------------------
1919 * Function: FlashPoint_HandleInterrupt
1921 * Description: This is our entry point when an interrupt is generated
1922 * by the card and the upper level driver passes it on to
1925 *---------------------------------------------------------------------*/
1926 static int FlashPoint_HandleInterrupt(ULONG pCurrCard)
1929 unsigned char thisCard,result,bm_status, bm_int_st;
1930 unsigned short hp_int;
1931 unsigned char i, target;
1934 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1935 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1937 MDISABLE_INT(ioport);
1939 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1940 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
1944 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1946 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1950 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1952 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1953 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1954 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1959 MENABLE_INT(ioport);
1965 else if (hp_int & ICMD_COMP) {
1967 if ( !(hp_int & BUS_FREE) ) {
1968 /* Wait for the BusFree before starting a new command. We
1969 must also check for being reselected since the BusFree
1970 may not show up if another device reselects us in 1.5us or
1971 less. SRR Wednesday, 3/8/1995.
1973 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1976 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1978 FPT_phaseChkFifo(ioport, thisCard);
1980 /* WRW_HARPOON((ioport+hp_intstat),
1981 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1984 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1986 FPT_autoCmdCmplt(ioport,thisCard);
1991 else if (hp_int & ITAR_DISC)
1994 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1996 FPT_phaseChkFifo(ioport, thisCard);
2000 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2002 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2003 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2005 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2008 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2009 FPT_queueDisconnect(currSCCB,thisCard);
2011 /* Wait for the BusFree before starting a new command. We
2012 must also check for being reselected since the BusFree
2013 may not show up if another device reselects us in 1.5us or
2014 less. SRR Wednesday, 3/8/1995.
2016 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2017 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2018 RD_HARPOON((ioport+hp_scsisig)) ==
2019 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2022 The additional loop exit condition above detects a timing problem
2023 with the revision D/E harpoon chips. The caller should reset the
2024 host adapter to recover when 0xFE is returned.
2026 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2028 MENABLE_INT(ioport);
2032 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2035 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2040 else if (hp_int & RSEL) {
2042 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2044 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2046 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2048 FPT_phaseChkFifo(ioport, thisCard);
2051 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2053 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2054 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2055 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2058 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2059 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2060 FPT_queueDisconnect(currSCCB,thisCard);
2063 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2064 FPT_phaseDecode(ioport,thisCard);
2069 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2072 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2073 FPT_phaseDecode(ioport,thisCard);
2078 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2080 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2081 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
2083 FPT_phaseDecode(ioport,thisCard);
2087 /* Harpoon problem some SCSI target device respond to selection
2088 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2089 to latch the correct Target ID into reg. x53.
2090 The work around require to correct this reg. But when write to this
2091 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2092 need to read this reg first then restore it later. After update to 0x53 */
2094 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2095 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2096 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2097 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2098 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
2099 WR_HARPOON(ioport+hp_fifowrite, i);
2100 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2104 else if (hp_int & XFER_CNT_0) {
2106 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2108 FPT_schkdd(ioport,thisCard);
2113 else if (hp_int & BUS_FREE) {
2115 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2117 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2119 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
2122 FPT_phaseBusFree(ioport,thisCard);
2126 else if (hp_int & ITICKLE) {
2128 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2129 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2134 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2137 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2140 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2142 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
2145 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2146 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2147 FPT_ssel(ioport,thisCard);
2156 MENABLE_INT(ioport);
2161 /*---------------------------------------------------------------------
2163 * Function: Sccb_bad_isr
2165 * Description: Some type of interrupt has occurred which is slightly
2166 * out of the ordinary. We will now decode it fully, in
2167 * this routine. This is broken up in an attempt to save
2170 *---------------------------------------------------------------------*/
2171 static unsigned char FPT_SccbMgr_bad_isr(ULONG p_port, unsigned char p_card,
2172 PSCCBcard pCurrCard, unsigned short p_int)
2174 unsigned char temp, ScamFlg;
2175 PSCCBMgr_tar_info currTar_Info;
2176 PNVRamInfo pCurrNvRam;
2179 if (RD_HARPOON(p_port+hp_ext_status) &
2180 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2183 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2186 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2189 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2192 WR_HARPOON(p_port+hp_pci_stat_cfg,
2193 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2195 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2199 if (pCurrCard->currentSCCB != NULL)
2202 if (!pCurrCard->currentSCCB->HostStatus)
2203 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2205 FPT_sxfrp(p_port,p_card);
2207 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
2208 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2209 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
2210 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2212 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2214 FPT_phaseDecode(p_port,p_card);
2220 else if (p_int & RESET)
2223 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2224 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2225 if (pCurrCard->currentSCCB != NULL) {
2227 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2229 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2233 DISABLE_AUTO(p_port);
2235 FPT_sresb(p_port,p_card);
2237 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2239 pCurrNvRam = pCurrCard->pNvRamInfo;
2241 ScamFlg = pCurrNvRam->niScamConf;
2244 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
2247 FPT_XbowInit(p_port, ScamFlg);
2249 FPT_scini(p_card, pCurrCard->ourId, 0);
2255 else if (p_int & FIFO) {
2257 WRW_HARPOON((p_port+hp_intstat), FIFO);
2259 if (pCurrCard->currentSCCB != NULL)
2260 FPT_sxfrp(p_port,p_card);
2263 else if (p_int & TIMEOUT)
2266 DISABLE_AUTO(p_port);
2268 WRW_HARPOON((p_port+hp_intstat),
2269 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2271 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2274 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2275 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2276 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2277 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
2279 currTar_Info->TarLUNBusy[0] = 0;
2282 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2284 currTar_Info->TarSyncCtrl = 0;
2285 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2288 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2290 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2293 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
2295 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2299 else if (p_int & SCAM_SEL)
2302 FPT_scarb(p_port,LEVEL2_TAR);
2304 FPT_scasid(p_card, p_port);
2308 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2315 /*---------------------------------------------------------------------
2317 * Function: SccbMgrTableInit
2319 * Description: Initialize all Sccb manager data structures.
2321 *---------------------------------------------------------------------*/
2323 static void FPT_SccbMgrTableInitAll()
2325 unsigned char thisCard;
2327 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2329 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
2331 FPT_BL_Card[thisCard].ioPort = 0x00;
2332 FPT_BL_Card[thisCard].cardInfo = NULL;
2333 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2334 FPT_BL_Card[thisCard].ourId = 0x00;
2335 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2340 /*---------------------------------------------------------------------
2342 * Function: SccbMgrTableInit
2344 * Description: Initialize all Sccb manager data structures.
2346 *---------------------------------------------------------------------*/
2348 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
2350 unsigned char scsiID, qtag;
2352 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2354 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2357 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2359 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2360 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2361 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2364 pCurrCard->scanIndex = 0x00;
2365 pCurrCard->currentSCCB = NULL;
2366 pCurrCard->globalFlags = 0x00;
2367 pCurrCard->cmdCounter = 0x00;
2368 pCurrCard->tagQ_Lst = 0x01;
2369 pCurrCard->discQCount = 0;
2375 /*---------------------------------------------------------------------
2377 * Function: SccbMgrTableInit
2379 * Description: Initialize all Sccb manager data structures.
2381 *---------------------------------------------------------------------*/
2383 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
2386 unsigned char lun, qtag;
2387 PSCCBMgr_tar_info currTar_Info;
2389 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2391 currTar_Info->TarSelQ_Cnt = 0;
2392 currTar_Info->TarSyncCtrl = 0;
2394 currTar_Info->TarSelQ_Head = NULL;
2395 currTar_Info->TarSelQ_Tail = NULL;
2396 currTar_Info->TarTagQ_Cnt = 0;
2397 currTar_Info->TarLUN_CA = 0;
2400 for (lun = 0; lun < MAX_LUN; lun++)
2402 currTar_Info->TarLUNBusy[lun] = 0;
2403 currTar_Info->LunDiscQ_Idx[lun] = 0;
2406 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2408 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
2410 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
2412 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2413 FPT_BL_Card[p_card].discQCount--;
2420 /*---------------------------------------------------------------------
2424 * Description: Read in a message byte from the SCSI bus, and check
2425 * for a parity error.
2427 *---------------------------------------------------------------------*/
2429 static unsigned char FPT_sfm(ULONG port, PSCCB pCurrSCCB)
2431 unsigned char message;
2432 unsigned short TimeOutLoop;
2435 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2436 (TimeOutLoop++ < 20000) ){}
2439 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2441 message = RD_HARPOON(port+hp_scsidata_0);
2443 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2446 if (TimeOutLoop > 20000)
2447 message = 0x00; /* force message byte = 0 if Time Out on Req */
2449 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2450 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2452 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2453 WR_HARPOON(port+hp_xferstat, 0);
2454 WR_HARPOON(port+hp_fiforead, 0);
2455 WR_HARPOON(port+hp_fifowrite, 0);
2456 if (pCurrSCCB != NULL)
2458 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2463 ACCEPT_MSG_ATN(port);
2465 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2466 (TimeOutLoop++ < 20000) ){}
2467 if (TimeOutLoop > 20000)
2469 WRW_HARPOON((port+hp_intstat), PARITY);
2472 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2474 WRW_HARPOON((port+hp_intstat), PARITY);
2477 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2479 RD_HARPOON(port+hp_scsidata_0);
2481 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2486 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2487 WR_HARPOON(port+hp_xferstat, 0);
2488 WR_HARPOON(port+hp_fiforead, 0);
2489 WR_HARPOON(port+hp_fifowrite, 0);
2494 /*---------------------------------------------------------------------
2496 * Function: FPT_ssel
2498 * Description: Load up automation and select target device.
2500 *---------------------------------------------------------------------*/
2502 static void FPT_ssel(ULONG port, unsigned char p_card)
2505 unsigned char auto_loaded, i, target, *theCCB;
2510 PSCCBMgr_tar_info currTar_Info;
2511 unsigned char lastTag, lun;
2513 CurrCard = &FPT_BL_Card[p_card];
2514 currSCCB = CurrCard->currentSCCB;
2515 target = currSCCB->TargID;
2516 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2517 lastTag = CurrCard->tagQ_Lst;
2522 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2523 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2525 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2526 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2528 lun = currSCCB->Lun;
2533 if (CurrCard->globalFlags & F_TAG_STARTED)
2535 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2537 if ((currTar_Info->TarLUN_CA == 0)
2538 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2542 if (currTar_Info->TarTagQ_Cnt !=0)
2544 currTar_Info->TarLUNBusy[lun] = 1;
2545 FPT_queueSelectFail(CurrCard,p_card);
2551 currTar_Info->TarLUNBusy[lun] = 1;
2554 } /*End non-tagged */
2557 currTar_Info->TarLUNBusy[lun] = 1;
2560 } /*!Use cmd Q Tagged */
2563 if (currTar_Info->TarLUN_CA == 1)
2565 FPT_queueSelectFail(CurrCard,p_card);
2570 currTar_Info->TarLUNBusy[lun] = 1;
2572 } /*else use cmd Q tagged */
2574 } /*if glob tagged started */
2577 currTar_Info->TarLUNBusy[lun] = 1;
2582 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2583 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2584 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2586 if(CurrCard->discQCount >= QUEUE_DEPTH)
2588 currTar_Info->TarLUNBusy[lun] = 1;
2589 FPT_queueSelectFail(CurrCard,p_card);
2593 for (i = 1; i < QUEUE_DEPTH; i++)
2595 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2596 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2598 CurrCard->tagQ_Lst = lastTag;
2599 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2600 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2601 CurrCard->discQCount++;
2605 if(i == QUEUE_DEPTH)
2607 currTar_Info->TarLUNBusy[lun] = 1;
2608 FPT_queueSelectFail(CurrCard,p_card);
2618 WR_HARPOON(port+hp_select_id, target);
2619 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2621 if (currSCCB->OperationCode == RESET_COMMAND) {
2622 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2623 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2625 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2627 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2629 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2631 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2633 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2635 currTar_Info->TarSyncCtrl = 0;
2636 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2639 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2641 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2644 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2645 FPT_SccbMgrTableInitTarget(p_card, target);
2649 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2651 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2652 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2654 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2656 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2657 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2658 >> 6) | (unsigned char)0x20)));
2659 WRW_HARPOON((port+SYNC_MSGS+2),
2660 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2661 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2663 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2668 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2669 auto_loaded = FPT_siwidn(port,p_card);
2670 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2673 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2674 == SYNC_SUPPORTED)) {
2675 auto_loaded = FPT_sisyncn(port,p_card, 0);
2676 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2683 if (currSCCB->ControlByte & F_USE_CMD_Q)
2686 CurrCard->globalFlags |= F_TAG_STARTED;
2688 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2691 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2693 /* Fix up the start instruction with a jump to
2694 Non-Tag-CMD handling */
2695 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2697 WRW_HARPOON((port+NON_TAG_ID_MSG),
2698 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2700 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2702 /* Setup our STATE so we know what happend when
2703 the wheels fall off. */
2704 currSCCB->Sccb_scsistat = SELECT_ST;
2706 currTar_Info->TarLUNBusy[lun] = 1;
2711 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2713 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2714 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2715 >> 6) | (unsigned char)0x20)));
2717 for (i = 1; i < QUEUE_DEPTH; i++)
2719 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2720 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2722 WRW_HARPOON((port+ID_MSG_STRT+6),
2723 (MPM_OP+AMSG_OUT+lastTag));
2724 CurrCard->tagQ_Lst = lastTag;
2725 currSCCB->Sccb_tag = lastTag;
2726 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2727 CurrCard->discQCount++;
2733 if ( i == QUEUE_DEPTH )
2735 currTar_Info->TarLUNBusy[lun] = 1;
2736 FPT_queueSelectFail(CurrCard,p_card);
2741 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2743 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2750 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2752 WRW_HARPOON((port+NON_TAG_ID_MSG),
2753 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2755 currSCCB->Sccb_scsistat = SELECT_ST;
2757 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2761 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2763 cdb_reg = port + CMD_STRT;
2765 for (i=0; i < currSCCB->CdbLength; i++)
2767 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2772 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2773 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2777 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2778 WR_HARPOON(port+hp_xferstat, 0x00);
2780 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2782 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2785 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2787 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2792 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2793 auto_loaded |= AUTO_IMMED; */
2794 auto_loaded = AUTO_IMMED;
2798 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2805 /*---------------------------------------------------------------------
2807 * Function: FPT_sres
2809 * Description: Hookup the correct CCB and handle the incoming messages.
2811 *---------------------------------------------------------------------*/
2813 static void FPT_sres(ULONG port, unsigned char p_card, PSCCBcard pCurrCard)
2816 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2819 PSCCBMgr_tar_info currTar_Info;
2825 if(pCurrCard->currentSCCB != NULL)
2827 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2831 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2834 currSCCB = pCurrCard->currentSCCB;
2835 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2837 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2838 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2840 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2842 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2843 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2845 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2846 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2848 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2849 if(currSCCB->Sccb_scsistat != ABORT_ST)
2851 pCurrCard->discQCount--;
2852 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2858 currTar_Info->TarLUNBusy[0] = 0;
2859 if(currSCCB->Sccb_tag)
2861 if(currSCCB->Sccb_scsistat != ABORT_ST)
2863 pCurrCard->discQCount--;
2864 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2868 if(currSCCB->Sccb_scsistat != ABORT_ST)
2870 pCurrCard->discQCount--;
2871 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2876 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
2879 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2882 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
2883 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2890 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2894 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2896 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2899 WRW_HARPOON((port+hp_intstat), PHASE);
2904 WRW_HARPOON((port+hp_intstat), PHASE);
2905 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2908 message = FPT_sfm(port,pCurrCard->currentSCCB);
2912 if (message <= (0x80 | LUN_MASK))
2914 lun = message & (unsigned char)LUN_MASK;
2916 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2918 if (currTar_Info->TarTagQ_Cnt != 0)
2921 if (!(currTar_Info->TarLUN_CA))
2923 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2926 message = FPT_sfm(port,pCurrCard->currentSCCB);
2937 tag = FPT_sfm(port,pCurrCard->currentSCCB);
2945 } /*End Q cnt != 0 */
2947 } /*End Tag cmds supported! */
2949 } /*End valid ID message. */
2954 ACCEPT_MSG_ATN(port);
2957 } /* End good id message. */
2967 ACCEPT_MSG_ATN(port);
2969 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2970 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2971 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2979 if(msgRetryCount == 1)
2981 FPT_SendMsg(port, SMPARITY);
2985 FPT_SendMsg(port, SMDEV_RESET);
2987 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
2989 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
2992 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
2996 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
2999 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
3003 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3004 FPT_SccbMgrTableInitTarget(p_card,our_target);
3008 }while(message == 0);
3012 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3013 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3015 currTar_Info->TarLUNBusy[lun] = 1;
3016 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3017 if(pCurrCard->currentSCCB != NULL)
3023 ACCEPT_MSG_ATN(port);
3028 currTar_Info->TarLUNBusy[0] = 1;
3033 if (pCurrCard->discQ_Tbl[tag] != NULL)
3035 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3036 currTar_Info->TarTagQ_Cnt--;
3041 ACCEPT_MSG_ATN(port);
3045 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3046 if(pCurrCard->currentSCCB != NULL)
3052 ACCEPT_MSG_ATN(port);
3057 if(pCurrCard->currentSCCB != NULL)
3059 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3061 /* During Abort Tag command, the target could have got re-selected
3062 and completed the command. Check the select Q and remove the CCB
3063 if it is in the Select Q */
3064 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
3069 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3070 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3071 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3074 static void FPT_SendMsg(ULONG port, unsigned char message)
3076 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3078 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3081 WRW_HARPOON((port+hp_intstat), PHASE);
3086 WRW_HARPOON((port+hp_intstat), PHASE);
3087 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3089 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3092 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3094 WR_HARPOON(port+hp_scsidata_0,message);
3096 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3100 WR_HARPOON(port+hp_portctrl_0, 0x00);
3102 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3103 (message == SMABORT_TAG) )
3105 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3107 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3109 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3115 /*---------------------------------------------------------------------
3117 * Function: FPT_sdecm
3119 * Description: Determine the proper responce to the message from the
3122 *---------------------------------------------------------------------*/
3123 static void FPT_sdecm(unsigned char message, ULONG port, unsigned char p_card)
3127 PSCCBMgr_tar_info currTar_Info;
3129 CurrCard = &FPT_BL_Card[p_card];
3130 currSCCB = CurrCard->currentSCCB;
3132 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3134 if (message == SMREST_DATA_PTR)
3136 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3138 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3140 FPT_hostDataXferRestart(currSCCB);
3144 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3147 else if (message == SMCMD_COMP)
3151 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3153 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3154 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
3161 else if ((message == SMNO_OP) || (message >= SMIDENT)
3162 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3166 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3169 else if (message == SMREJECT)
3172 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3173 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3174 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3175 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3178 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3183 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3184 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3186 if(currSCCB->Lun == 0x00)
3188 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3191 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3193 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3196 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3200 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3201 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3203 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3207 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3209 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3210 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3213 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3214 CurrCard->discQCount--;
3215 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3216 currSCCB->Sccb_tag = 0x00;
3221 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3225 if(currSCCB->Lun == 0x00)
3227 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3228 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3235 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3236 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3237 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
3239 currTar_Info->TarLUNBusy[0] = 1;
3242 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
3244 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3253 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3254 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3256 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3258 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3263 else if (message == SMEXT)
3267 FPT_shandem(port,p_card,currSCCB);
3270 else if (message == SMIGNORWR)
3273 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3275 message = FPT_sfm(port,currSCCB);
3277 if(currSCCB->Sccb_scsimsg != SMPARITY)
3279 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3286 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3287 currSCCB->Sccb_scsimsg = SMREJECT;
3289 ACCEPT_MSG_ATN(port);
3290 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3295 /*---------------------------------------------------------------------
3297 * Function: FPT_shandem
3299 * Description: Decide what to do with the extended message.
3301 *---------------------------------------------------------------------*/
3302 static void FPT_shandem(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
3304 unsigned char length,message;
3306 length = FPT_sfm(port,pCurrSCCB);
3311 message = FPT_sfm(port,pCurrSCCB);
3315 if (message == SMSYNC)
3322 FPT_stsyncn(port,p_card);
3327 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3328 ACCEPT_MSG_ATN(port);
3331 else if (message == SMWDTR)
3338 FPT_stwidn(port,p_card);
3343 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3344 ACCEPT_MSG_ATN(port);
3346 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3352 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3353 ACCEPT_MSG_ATN(port);
3355 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3360 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3362 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3366 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3367 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3372 /*---------------------------------------------------------------------
3374 * Function: FPT_sisyncn
3376 * Description: Read in a message byte from the SCSI bus, and check
3377 * for a parity error.
3379 *---------------------------------------------------------------------*/
3381 static unsigned char FPT_sisyncn(ULONG port, unsigned char p_card, unsigned char syncFlag)
3384 PSCCBMgr_tar_info currTar_Info;
3386 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3387 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3389 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3392 WRW_HARPOON((port+ID_MSG_STRT),
3393 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3395 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3397 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3398 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3399 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3402 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3404 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3406 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3408 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3410 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3412 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3415 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3418 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3419 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3420 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3425 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3426 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3427 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
3431 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3440 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3441 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3448 /*---------------------------------------------------------------------
3450 * Function: FPT_stsyncn
3452 * Description: The has sent us a Sync Nego message so handle it as
3455 *---------------------------------------------------------------------*/
3456 static void FPT_stsyncn(ULONG port, unsigned char p_card)
3458 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
3460 PSCCBMgr_tar_info currTar_Info;
3462 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3463 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3465 sync_msg = FPT_sfm(port,currSCCB);
3467 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3469 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3476 offset = FPT_sfm(port,currSCCB);
3478 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3480 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3484 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3486 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3488 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3490 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3492 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3494 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3497 our_sync_msg = 0; /* Message = Async */
3499 if (sync_msg < our_sync_msg) {
3500 sync_msg = our_sync_msg; /*if faster, then set to max. */
3503 if (offset == ASYNC)
3506 if (offset > MAX_OFFSET)
3507 offset = MAX_OFFSET;
3513 sync_reg = 0x20; /* Use 10MB/s */
3517 sync_reg = 0x40; /* Use 6.6MB/s */
3521 sync_reg = 0x60; /* Use 5MB/s */
3525 sync_reg = 0x80; /* Use 4MB/s */
3529 sync_reg = 0xA0; /* Use 3.33MB/s */
3533 sync_reg = 0xC0; /* Use 2.85MB/s */
3537 sync_reg = 0xE0; /* Use 2.5MB/s */
3539 if (sync_msg > 100) {
3541 sync_reg = 0x00; /* Use ASYNC */
3546 if (currTar_Info->TarStatus & WIDE_ENABLED)
3552 sync_reg |= (offset | NARROW_SCSI);
3554 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
3557 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3562 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3563 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3565 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3571 ACCEPT_MSG_ATN(port);
3573 FPT_sisyncr(port,sync_msg,offset);
3575 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3576 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3581 /*---------------------------------------------------------------------
3583 * Function: FPT_sisyncr
3585 * Description: Answer the targets sync message.
3587 *---------------------------------------------------------------------*/
3588 static void FPT_sisyncr(ULONG port,unsigned char sync_pulse, unsigned char offset)
3591 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3592 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3593 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3594 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3595 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3596 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3597 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3600 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3601 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3603 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3605 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3610 /*---------------------------------------------------------------------
3612 * Function: FPT_siwidn
3614 * Description: Read in a message byte from the SCSI bus, and check
3615 * for a parity error.
3617 *---------------------------------------------------------------------*/
3619 static unsigned char FPT_siwidn(ULONG port, unsigned char p_card)
3622 PSCCBMgr_tar_info currTar_Info;
3624 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3625 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3627 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3630 WRW_HARPOON((port+ID_MSG_STRT),
3631 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3633 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3635 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3636 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3637 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3638 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3639 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3640 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3642 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3645 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3646 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
3653 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3654 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3656 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3663 /*---------------------------------------------------------------------
3665 * Function: FPT_stwidn
3667 * Description: The has sent us a Wide Nego message so handle it as
3670 *---------------------------------------------------------------------*/
3671 static void FPT_stwidn(ULONG port, unsigned char p_card)
3673 unsigned char width;
3675 PSCCBMgr_tar_info currTar_Info;
3677 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3678 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3680 width = FPT_sfm(port,currSCCB);
3682 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3684 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3689 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3693 currTar_Info->TarStatus |= WIDE_ENABLED;
3697 width = NARROW_SCSI;
3698 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3702 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
3705 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3710 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3712 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3714 ACCEPT_MSG_ATN(port);
3716 FPT_sisyncn(port,p_card, 1);
3717 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3723 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3730 ACCEPT_MSG_ATN(port);
3732 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3737 FPT_siwidr(port,width);
3739 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3744 /*---------------------------------------------------------------------
3746 * Function: FPT_siwidr
3748 * Description: Answer the targets Wide nego message.
3750 *---------------------------------------------------------------------*/
3751 static void FPT_siwidr(ULONG port, unsigned char width)
3754 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3755 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3756 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3757 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3758 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3759 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3762 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3763 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3765 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3767 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3772 /*---------------------------------------------------------------------
3774 * Function: FPT_sssyncv
3776 * Description: Write the desired value to the Sync Register for the
3779 *---------------------------------------------------------------------*/
3780 static void FPT_sssyncv(ULONG p_port, unsigned char p_id, unsigned char p_sync_value,
3781 PSCCBMgr_tar_info currTar_Info)
3783 unsigned char index;
3790 index = 12; /* hp_synctarg_0 */
3793 index = 13; /* hp_synctarg_1 */
3796 index = 14; /* hp_synctarg_2 */
3799 index = 15; /* hp_synctarg_3 */
3802 index = 8; /* hp_synctarg_4 */
3805 index = 9; /* hp_synctarg_5 */
3808 index = 10; /* hp_synctarg_6 */
3811 index = 11; /* hp_synctarg_7 */
3814 index = 4; /* hp_synctarg_8 */
3817 index = 5; /* hp_synctarg_9 */
3820 index = 6; /* hp_synctarg_10 */
3823 index = 7; /* hp_synctarg_11 */
3826 index = 0; /* hp_synctarg_12 */
3829 index = 1; /* hp_synctarg_13 */
3832 index = 2; /* hp_synctarg_14 */
3835 index = 3; /* hp_synctarg_15 */
3839 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3841 currTar_Info->TarSyncCtrl = p_sync_value;
3845 /*---------------------------------------------------------------------
3847 * Function: FPT_sresb
3849 * Description: Reset the desired card's SCSI bus.
3851 *---------------------------------------------------------------------*/
3852 static void FPT_sresb(ULONG port, unsigned char p_card)
3854 unsigned char scsiID, i;
3856 PSCCBMgr_tar_info currTar_Info;
3858 WR_HARPOON(port+hp_page_ctrl,
3859 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3860 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3862 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3864 scsiID = RD_HARPOON(port+hp_seltimeout);
3865 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3866 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3868 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3870 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3872 WR_HARPOON(port+hp_seltimeout,scsiID);
3874 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3876 FPT_Wait(port, TO_5ms);
3878 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3880 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3882 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3884 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3886 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3888 currTar_Info->TarSyncCtrl = 0;
3889 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3892 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3894 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3897 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
3899 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3902 FPT_BL_Card[p_card].scanIndex = 0x00;
3903 FPT_BL_Card[p_card].currentSCCB = NULL;
3904 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3906 FPT_BL_Card[p_card].cmdCounter = 0x00;
3907 FPT_BL_Card[p_card].discQCount = 0x00;
3908 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3910 for(i = 0; i < QUEUE_DEPTH; i++)
3911 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3913 WR_HARPOON(port+hp_page_ctrl,
3914 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3918 /*---------------------------------------------------------------------
3920 * Function: FPT_ssenss
3922 * Description: Setup for the Auto Sense command.
3924 *---------------------------------------------------------------------*/
3925 static void FPT_ssenss(PSCCBcard pCurrCard)
3930 currSCCB = pCurrCard->currentSCCB;
3933 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3935 for (i = 0; i < 6; i++) {
3937 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3940 currSCCB->CdbLength = SIX_BYTE_CMD;
3941 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3942 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3943 currSCCB->Cdb[2] = 0x00;
3944 currSCCB->Cdb[3] = 0x00;
3945 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3946 currSCCB->Cdb[5] = 0x00;
3948 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3950 currSCCB->Sccb_ATC = 0x00;
3952 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3954 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3956 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3958 currSCCB->ControlByte = 0x00;
3960 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3965 /*---------------------------------------------------------------------
3967 * Function: FPT_sxfrp
3969 * Description: Transfer data into the bit bucket until the device
3970 * decides to switch phase.
3972 *---------------------------------------------------------------------*/
3974 static void FPT_sxfrp(ULONG p_port, unsigned char p_card)
3976 unsigned char curr_phz;
3979 DISABLE_AUTO(p_port);
3981 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3983 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
3987 /* If the Automation handled the end of the transfer then do not
3988 match the phase or we will get out of sync with the ISR. */
3990 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3993 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3995 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3997 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
4000 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4002 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
4003 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
4005 if (curr_phz & (unsigned char)SCSI_IOBIT)
4007 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4009 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4011 RD_HARPOON(p_port+hp_fifodata_0);
4016 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4017 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4019 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4022 } /* End of While loop for padding data I/O phase */
4024 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4026 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4030 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4031 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4033 RD_HARPOON(p_port+hp_fifodata_0);
4036 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4038 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4039 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4041 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4042 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4047 /*---------------------------------------------------------------------
4049 * Function: FPT_schkdd
4051 * Description: Make sure data has been flushed from both FIFOs and abort
4052 * the operations if necessary.
4054 *---------------------------------------------------------------------*/
4056 static void FPT_schkdd(ULONG port, unsigned char p_card)
4058 unsigned short TimeOutLoop;
4059 unsigned char sPhase;
4063 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4066 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4067 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4073 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4076 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4078 currSCCB->Sccb_XferCnt = 1;
4080 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4081 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
4082 WR_HARPOON(port+hp_xferstat, 0x00);
4088 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4090 currSCCB->Sccb_XferCnt = 0;
4093 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4094 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4096 currSCCB->HostStatus = SCCB_PARITY_ERR;
4097 WRW_HARPOON((port+hp_intstat), PARITY);
4101 FPT_hostDataXferAbort(port,p_card,currSCCB);
4104 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4108 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4110 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4113 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
4116 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4119 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4123 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4124 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4125 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
4126 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4127 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4130 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4132 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4134 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4135 FPT_phaseDataIn(port,p_card);
4139 FPT_phaseDataOut(port,p_card);
4144 FPT_sxfrp(port,p_card);
4145 if (!(RDW_HARPOON((port+hp_intstat)) &
4146 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4148 WRW_HARPOON((port+hp_intstat), AUTO_INT);
4149 FPT_phaseDecode(port,p_card);
4156 WR_HARPOON(port+hp_portctrl_0, 0x00);
4161 /*---------------------------------------------------------------------
4163 * Function: FPT_sinits
4165 * Description: Setup SCCB manager fields in this SCCB.
4167 *---------------------------------------------------------------------*/
4169 static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
4171 PSCCBMgr_tar_info currTar_Info;
4173 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4177 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
4179 p_sccb->Sccb_XferState = 0x00;
4180 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4182 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4183 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4185 p_sccb->Sccb_SGoffset = 0;
4186 p_sccb->Sccb_XferState = F_SG_XFER;
4187 p_sccb->Sccb_XferCnt = 0x00;
4190 if (p_sccb->DataLength == 0x00)
4192 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4194 if (p_sccb->ControlByte & F_USE_CMD_Q)
4196 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4197 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4200 currTar_Info->TarStatus |= TAG_Q_TRYING;
4203 /* For !single SCSI device in system & device allow Disconnect
4204 or command is tag_q type then send Cmd with Disconnect Enable
4205 else send Cmd with Disconnect Disable */
4208 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4209 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4210 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4212 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4213 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4214 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4219 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
4222 p_sccb->HostStatus = 0x00;
4223 p_sccb->TargetStatus = 0x00;
4224 p_sccb->Sccb_tag = 0x00;
4225 p_sccb->Sccb_MGRFlags = 0x00;
4226 p_sccb->Sccb_sgseg = 0x00;
4227 p_sccb->Sccb_ATC = 0x00;
4228 p_sccb->Sccb_savedATC = 0x00;
4230 p_sccb->SccbVirtDataPtr = 0x00;
4231 p_sccb->Sccb_forwardlink = NULL;
4232 p_sccb->Sccb_backlink = NULL;
4234 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4235 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4236 p_sccb->Sccb_scsimsg = SMNO_OP;
4241 /*---------------------------------------------------------------------
4243 * Function: Phase Decode
4245 * Description: Determine the phase and call the appropriate function.
4247 *---------------------------------------------------------------------*/
4249 static void FPT_phaseDecode(ULONG p_port, unsigned char p_card)
4251 unsigned char phase_ref;
4252 void (*phase) (ULONG, unsigned char);
4255 DISABLE_AUTO(p_port);
4257 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4259 phase = FPT_s_PhaseTbl[phase_ref];
4261 (*phase)(p_port, p_card); /* Call the correct phase func */
4266 /*---------------------------------------------------------------------
4268 * Function: Data Out Phase
4270 * Description: Start up both the BusMaster and Xbow.
4272 *---------------------------------------------------------------------*/
4274 static void FPT_phaseDataOut(ULONG port, unsigned char p_card)
4279 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4280 if (currSCCB == NULL)
4282 return; /* Exit if No SCCB record */
4285 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4286 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4288 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4290 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4292 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4294 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4296 if (currSCCB->Sccb_XferCnt == 0) {
4299 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4300 (currSCCB->HostStatus == SCCB_COMPLETE))
4301 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4303 FPT_sxfrp(port,p_card);
4304 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4305 FPT_phaseDecode(port,p_card);
4310 /*---------------------------------------------------------------------
4312 * Function: Data In Phase
4314 * Description: Startup the BusMaster and the XBOW.
4316 *---------------------------------------------------------------------*/
4318 static void FPT_phaseDataIn(ULONG port, unsigned char p_card)
4323 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4325 if (currSCCB == NULL)
4327 return; /* Exit if No SCCB record */
4331 currSCCB->Sccb_scsistat = DATA_IN_ST;
4332 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4333 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4335 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4337 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4339 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4341 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4343 if (currSCCB->Sccb_XferCnt == 0) {
4346 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4347 (currSCCB->HostStatus == SCCB_COMPLETE))
4348 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4350 FPT_sxfrp(port,p_card);
4351 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4352 FPT_phaseDecode(port,p_card);
4357 /*---------------------------------------------------------------------
4359 * Function: Command Phase
4361 * Description: Load the CDB into the automation and start it up.
4363 *---------------------------------------------------------------------*/
4365 static void FPT_phaseCommand(ULONG p_port, unsigned char p_card)
4371 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4373 if (currSCCB->OperationCode == RESET_COMMAND) {
4375 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4376 currSCCB->CdbLength = SIX_BYTE_CMD;
4379 WR_HARPOON(p_port+hp_scsisig, 0x00);
4381 ARAM_ACCESS(p_port);
4384 cdb_reg = p_port + CMD_STRT;
4386 for (i=0; i < currSCCB->CdbLength; i++) {
4388 if (currSCCB->OperationCode == RESET_COMMAND)
4390 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4393 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4397 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4398 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4400 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4402 currSCCB->Sccb_scsistat = COMMAND_ST;
4404 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4405 SGRAM_ACCESS(p_port);
4409 /*---------------------------------------------------------------------
4411 * Function: Status phase
4413 * Description: Bring in the status and command complete message bytes
4415 *---------------------------------------------------------------------*/
4417 static void FPT_phaseStatus(ULONG port, unsigned char p_card)
4419 /* Start-up the automation to finish off this command and let the
4420 isr handle the interrupt for command complete when it comes in.
4421 We could wait here for the interrupt to be generated?
4424 WR_HARPOON(port+hp_scsisig, 0x00);
4426 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4430 /*---------------------------------------------------------------------
4432 * Function: Phase Message Out
4434 * Description: Send out our message (if we have one) and handle whatever
4437 *---------------------------------------------------------------------*/
4439 static void FPT_phaseMsgOut(ULONG port, unsigned char p_card)
4441 unsigned char message,scsiID;
4443 PSCCBMgr_tar_info currTar_Info;
4445 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4447 if (currSCCB != NULL) {
4449 message = currSCCB->Sccb_scsimsg;
4450 scsiID = currSCCB->TargID;
4452 if (message == SMDEV_RESET)
4456 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4457 currTar_Info->TarSyncCtrl = 0;
4458 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
4460 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
4463 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
4467 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
4470 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
4474 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4475 FPT_SccbMgrTableInitTarget(p_card,scsiID);
4477 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4479 currSCCB->HostStatus = SCCB_COMPLETE;
4480 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
4482 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4483 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4488 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4492 if(message == SMNO_OP)
4494 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4496 FPT_ssel(port,p_card);
4504 if (message == SMABORT)
4506 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4515 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4518 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4520 WR_HARPOON(port+hp_scsidata_0,message);
4522 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4526 WR_HARPOON(port+hp_portctrl_0, 0x00);
4528 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4529 (message == SMABORT_TAG) )
4532 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4534 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4536 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4538 if (currSCCB != NULL)
4541 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4542 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4543 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4545 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4547 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
4552 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4559 FPT_sxfrp(port,p_card);
4566 if(message == SMPARITY)
4568 currSCCB->Sccb_scsimsg = SMNO_OP;
4569 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4573 FPT_sxfrp(port,p_card);
4579 /*---------------------------------------------------------------------
4581 * Function: Message In phase
4583 * Description: Bring in the message and determine what to do with it.
4585 *---------------------------------------------------------------------*/
4587 static void FPT_phaseMsgIn(ULONG port, unsigned char p_card)
4589 unsigned char message;
4592 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4594 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
4597 FPT_phaseChkFifo(port, p_card);
4600 message = RD_HARPOON(port+hp_scsidata_0);
4601 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4604 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4611 message = FPT_sfm(port,currSCCB);
4616 FPT_sdecm(message,port,p_card);
4621 if(currSCCB->Sccb_scsimsg != SMPARITY)
4623 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4630 /*---------------------------------------------------------------------
4632 * Function: Illegal phase
4634 * Description: Target switched to some illegal phase, so all we can do
4635 * is report an error back to the host (if that is possible)
4636 * and send an ABORT message to the misbehaving target.
4638 *---------------------------------------------------------------------*/
4640 static void FPT_phaseIllegal(ULONG port, unsigned char p_card)
4644 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4646 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4647 if (currSCCB != NULL) {
4649 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4650 currSCCB->Sccb_scsistat = ABORT_ST;
4651 currSCCB->Sccb_scsimsg = SMABORT;
4654 ACCEPT_MSG_ATN(port);
4659 /*---------------------------------------------------------------------
4661 * Function: Phase Check FIFO
4663 * Description: Make sure data has been flushed from both FIFOs and abort
4664 * the operations if necessary.
4666 *---------------------------------------------------------------------*/
4668 static void FPT_phaseChkFifo(ULONG port, unsigned char p_card)
4673 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4675 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4678 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4679 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4682 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4684 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4686 currSCCB->Sccb_XferCnt = 0;
4688 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4689 (currSCCB->HostStatus == SCCB_COMPLETE))
4691 currSCCB->HostStatus = SCCB_PARITY_ERR;
4692 WRW_HARPOON((port+hp_intstat), PARITY);
4695 FPT_hostDataXferAbort(port,p_card,currSCCB);
4697 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4699 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4700 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4703 } /*End Data In specific code. */
4707 GET_XFER_CNT(port,xfercnt);
4710 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4713 WR_HARPOON(port+hp_portctrl_0, 0x00);
4715 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4717 currSCCB->Sccb_XferCnt = xfercnt;
4719 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4720 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4722 currSCCB->HostStatus = SCCB_PARITY_ERR;
4723 WRW_HARPOON((port+hp_intstat), PARITY);
4727 FPT_hostDataXferAbort(port,p_card,currSCCB);
4730 WR_HARPOON(port+hp_fifowrite, 0x00);
4731 WR_HARPOON(port+hp_fiforead, 0x00);
4732 WR_HARPOON(port+hp_xferstat, 0x00);
4734 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4738 /*---------------------------------------------------------------------
4740 * Function: Phase Bus Free
4742 * Description: We just went bus free so figure out if it was
4743 * because of command complete or from a disconnect.
4745 *---------------------------------------------------------------------*/
4746 static void FPT_phaseBusFree(ULONG port, unsigned char p_card)
4750 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4752 if (currSCCB != NULL)
4758 if (currSCCB->OperationCode == RESET_COMMAND)
4761 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4762 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4763 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4765 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4767 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4769 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
4773 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4775 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4776 (unsigned char)SYNC_SUPPORTED;
4777 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4780 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4782 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4783 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4784 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4786 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
4789 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4791 /* Make sure this is not a phony BUS_FREE. If we were
4792 reselected or if BUSY is NOT on then this is a
4793 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4795 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4796 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4798 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4799 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
4811 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4813 if (!currSCCB->HostStatus)
4815 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4818 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4819 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4820 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4822 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4824 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4829 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4831 } /*end if !=null */
4837 /*---------------------------------------------------------------------
4839 * Function: Auto Load Default Map
4841 * Description: Load the Automation RAM with the defualt map values.
4843 *---------------------------------------------------------------------*/
4844 static void FPT_autoLoadDefaultMap(ULONG p_port)
4848 ARAM_ACCESS(p_port);
4849 map_addr = p_port + hp_aramBase;
4851 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4853 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4855 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4857 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4859 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4861 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4863 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4865 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4867 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4869 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4871 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4873 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4875 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4877 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4879 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4881 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4883 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4885 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4886 map_addr +=2; /*This means AYNC DATA IN */
4887 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4889 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4891 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4893 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4895 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4897 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4899 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4901 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4903 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4905 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4907 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4909 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4911 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4913 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4915 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4917 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4919 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4921 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4924 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4926 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4928 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4930 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4931 map_addr +=2; /* DIDN'T GET ONE */
4932 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4934 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4936 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4940 SGRAM_ACCESS(p_port);
4943 /*---------------------------------------------------------------------
4945 * Function: Auto Command Complete
4947 * Description: Post command back to host and find another command
4950 *---------------------------------------------------------------------*/
4952 static void FPT_autoCmdCmplt(ULONG p_port, unsigned char p_card)
4955 unsigned char status_byte;
4957 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4959 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4961 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4963 if (status_byte != SSGOOD) {
4965 if (status_byte == SSQ_FULL) {
4968 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4969 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4971 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4972 if(FPT_BL_Card[p_card].discQCount != 0)
4973 FPT_BL_Card[p_card].discQCount--;
4974 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
4978 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
4979 if(currSCCB->Sccb_tag)
4981 if(FPT_BL_Card[p_card].discQCount != 0)
4982 FPT_BL_Card[p_card].discQCount--;
4983 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4986 if(FPT_BL_Card[p_card].discQCount != 0)
4987 FPT_BL_Card[p_card].discQCount--;
4988 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
4992 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4994 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
4999 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5001 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
5002 (unsigned char)SYNC_SUPPORTED;
5004 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5005 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5007 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5008 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5010 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5011 if(FPT_BL_Card[p_card].discQCount != 0)
5012 FPT_BL_Card[p_card].discQCount--;
5013 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5017 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5018 if(currSCCB->Sccb_tag)
5020 if(FPT_BL_Card[p_card].discQCount != 0)
5021 FPT_BL_Card[p_card].discQCount--;
5022 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5025 if(FPT_BL_Card[p_card].discQCount != 0)
5026 FPT_BL_Card[p_card].discQCount--;
5027 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5034 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5037 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5038 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
5039 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5041 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5042 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5044 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5045 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5047 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5048 if(FPT_BL_Card[p_card].discQCount != 0)
5049 FPT_BL_Card[p_card].discQCount--;
5050 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5054 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5055 if(currSCCB->Sccb_tag)
5057 if(FPT_BL_Card[p_card].discQCount != 0)
5058 FPT_BL_Card[p_card].discQCount--;
5059 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5062 if(FPT_BL_Card[p_card].discQCount != 0)
5063 FPT_BL_Card[p_card].discQCount--;
5064 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5071 if (status_byte == SSCHECK)
5073 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
5075 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
5077 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
5079 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
5081 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
5086 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5088 currSCCB->SccbStatus = SCCB_ERROR;
5089 currSCCB->TargetStatus = status_byte;
5091 if (status_byte == SSCHECK) {
5093 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5097 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5099 if (currSCCB->RequestSenseLength == 0)
5100 currSCCB->RequestSenseLength = 14;
5102 FPT_ssenss(&FPT_BL_Card[p_card]);
5103 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5105 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5106 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5108 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5109 if(FPT_BL_Card[p_card].discQCount != 0)
5110 FPT_BL_Card[p_card].discQCount--;
5111 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5115 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5116 if(currSCCB->Sccb_tag)
5118 if(FPT_BL_Card[p_card].discQCount != 0)
5119 FPT_BL_Card[p_card].discQCount--;
5120 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5123 if(FPT_BL_Card[p_card].discQCount != 0)
5124 FPT_BL_Card[p_card].discQCount--;
5125 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5135 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5136 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5137 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
5139 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5142 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
5145 #define SHORT_WAIT 0x0000000F
5146 #define LONG_WAIT 0x0000FFFFL
5149 /*---------------------------------------------------------------------
5151 * Function: Data Transfer Processor
5153 * Description: This routine performs two tasks.
5154 * (1) Start data transfer by calling HOST_DATA_XFER_START
5155 * function. Once data transfer is started, (2) Depends
5156 * on the type of data transfer mode Scatter/Gather mode
5157 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5158 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5159 * data transfer done. In Scatter/Gather mode, this routine
5160 * checks bus master command complete and dual rank busy
5161 * bit to keep chaining SC transfer command. Similarly,
5162 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5163 * (F_HOST_XFER_ACT bit) for data transfer done.
5165 *---------------------------------------------------------------------*/
5167 static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
5171 currSCCB = pCurrCard->currentSCCB;
5173 if (currSCCB->Sccb_XferState & F_SG_XFER)
5175 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5178 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
5179 currSCCB->Sccb_SGoffset = 0x00;
5181 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5183 FPT_busMstrSGDataXferStart(port, currSCCB);
5188 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5190 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5192 FPT_busMstrDataXferStart(port, currSCCB);
5198 /*---------------------------------------------------------------------
5200 * Function: BusMaster Scatter Gather Data Transfer Start
5204 *---------------------------------------------------------------------*/
5205 static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
5207 ULONG count,addr,tmpSGCnt;
5209 unsigned char sg_count, i;
5213 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5215 count = ((ULONG) HOST_RD_CMD)<<24;
5219 count = ((ULONG) HOST_WRT_CMD)<<24;
5224 sg_index = pcurrSCCB->Sccb_sgseg;
5225 reg_offset = hp_aramBase;
5228 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5231 WR_HARPOON(p_port+hp_page_ctrl, i);
5233 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
5234 ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5236 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5239 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5242 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5243 ((sg_index * 2) + 1));
5246 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5248 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5249 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5251 tmpSGCnt = count & 0x00FFFFFFL;
5254 WR_HARP32(p_port,reg_offset,addr);
5257 WR_HARP32(p_port,reg_offset,count);
5260 count &= 0xFF000000L;
5266 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5268 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5270 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5272 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5275 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5276 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5282 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5283 (tmpSGCnt & 0x000000001))
5286 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5291 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5293 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5294 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5298 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
5303 /*---------------------------------------------------------------------
5305 * Function: BusMaster Data Transfer Start
5309 *---------------------------------------------------------------------*/
5310 static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
5314 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5316 count = pcurrSCCB->Sccb_XferCnt;
5318 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5322 addr = pcurrSCCB->SensePointer;
5323 count = pcurrSCCB->RequestSenseLength;
5327 HP_SETUP_ADDR_CNT(p_port,addr,count);
5330 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5332 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5333 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5335 WR_HARPOON(p_port+hp_xfer_cmd,
5336 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5341 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5342 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5344 WR_HARPOON(p_port+hp_xfer_cmd,
5345 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5351 /*---------------------------------------------------------------------
5353 * Function: BusMaster Timeout Handler
5355 * Description: This function is called after a bus master command busy time
5356 * out is detected. This routines issue halt state machine
5357 * with a software time out for command busy. If command busy
5358 * is still asserted at the end of the time out, it issues
5359 * hard abort with another software time out. It hard abort
5360 * command busy is also time out, it'll just give up.
5362 *---------------------------------------------------------------------*/
5363 static unsigned char FPT_busMstrTimeOut(ULONG p_port)
5367 timeout = LONG_WAIT;
5369 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5371 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5375 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5376 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5378 timeout = LONG_WAIT;
5379 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5382 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5384 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5394 /*---------------------------------------------------------------------
5396 * Function: Host Data Transfer Abort
5398 * Description: Abort any in progress transfer.
5400 *---------------------------------------------------------------------*/
5401 static void FPT_hostDataXferAbort(ULONG port, unsigned char p_card, PSCCB pCurrSCCB)
5408 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5410 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5413 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5415 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5416 timeout = LONG_WAIT;
5418 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5420 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5422 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5424 if (FPT_busMstrTimeOut(port)) {
5426 if (pCurrSCCB->HostStatus == 0x00)
5428 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5432 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5434 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5436 if (pCurrSCCB->HostStatus == 0x00)
5439 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5445 else if (pCurrSCCB->Sccb_XferCnt) {
5447 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5450 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5453 WR_HARPOON(port+hp_sg_addr,0x00);
5455 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5457 if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5459 sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5462 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5464 while (remain_cnt < 0x01000000L) {
5468 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5469 DataPointer) + (sg_ptr * 2)))) {
5471 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5472 DataPointer) + (sg_ptr * 2)));
5483 if (remain_cnt < 0x01000000L) {
5486 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5488 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5491 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5492 && (remain_cnt == 0))
5494 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5500 if (pCurrSCCB->HostStatus == 0x00) {
5502 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5508 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5511 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5513 FPT_busMstrTimeOut(port);
5518 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5520 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5522 if (pCurrSCCB->HostStatus == 0x00) {
5524 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5535 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5537 timeout = SHORT_WAIT;
5539 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5540 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5544 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5546 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5549 timeout = LONG_WAIT;
5551 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5554 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5558 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5560 if (pCurrSCCB->HostStatus == 0x00) {
5562 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5565 FPT_busMstrTimeOut(port);
5569 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5571 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5573 if (pCurrSCCB->HostStatus == 0x00) {
5575 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5586 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5588 timeout = LONG_WAIT;
5590 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5592 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5594 if (pCurrSCCB->HostStatus == 0x00) {
5596 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5599 FPT_busMstrTimeOut(port);
5604 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5606 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5608 if (pCurrSCCB->HostStatus == 0x00) {
5610 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5616 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5618 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5621 WR_HARPOON(port+hp_sg_addr,0x00);
5623 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5625 pCurrSCCB->Sccb_SGoffset = 0x00;
5628 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5629 pCurrSCCB->DataLength) {
5631 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5633 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5640 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5642 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5646 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5651 /*---------------------------------------------------------------------
5653 * Function: Host Data Transfer Restart
5655 * Description: Reset the available count due to a restore data
5658 *---------------------------------------------------------------------*/
5659 static void FPT_hostDataXferRestart(PSCCB currSCCB)
5665 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5667 currSCCB->Sccb_XferCnt = 0;
5669 sg_index = 0xffff; /*Index by long words into sg list. */
5670 data_count = 0; /*Running count of SG xfer counts. */
5672 sg_ptr = (ULONG *)currSCCB->DataPointer;
5674 while (data_count < currSCCB->Sccb_ATC) {
5677 data_count += *(sg_ptr+(sg_index * 2));
5680 if (data_count == currSCCB->Sccb_ATC) {
5682 currSCCB->Sccb_SGoffset = 0;
5687 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5690 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5694 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5700 /*---------------------------------------------------------------------
5702 * Function: FPT_scini
5704 * Description: Setup all data structures necessary for SCAM selection.
5706 *---------------------------------------------------------------------*/
5708 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
5711 unsigned char loser,assigned_id;
5714 unsigned char i,k,ScamFlg ;
5716 PNVRamInfo pCurrNvRam;
5718 currCard = &FPT_BL_Card[p_card];
5719 p_port = currCard->ioPort;
5720 pCurrNvRam = currCard->pNvRamInfo;
5724 ScamFlg = pCurrNvRam->niScamConf;
5725 i = pCurrNvRam->niSysConf;
5728 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5729 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
5731 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5734 FPT_inisci(p_card,p_port, p_our_id);
5736 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5737 too slow to return to SCAM selection */
5740 FPT_Wait1Second(p_port);
5742 FPT_Wait(p_port, TO_250ms); */
5744 FPT_Wait1Second(p_port);
5746 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5748 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5753 FPT_scxferc(p_port,SYNC_PTRN);
5754 FPT_scxferc(p_port,DOM_MSTR);
5755 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
5756 } while ( loser == 0xFF );
5760 if ((p_power_up) && (!loser))
5762 FPT_sresb(p_port,p_card);
5763 FPT_Wait(p_port, TO_250ms);
5765 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5770 FPT_scxferc(p_port, SYNC_PTRN);
5771 FPT_scxferc(p_port, DOM_MSTR);
5772 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
5774 } while ( loser == 0xFF );
5789 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5792 if (ScamFlg & SCAM_ENABLED)
5795 for (i=0; i < MAX_SCSI_TAR; i++)
5797 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5798 (FPT_scamInfo[i].state == ID_UNUSED))
5800 if (FPT_scsell(p_port,i))
5802 FPT_scamInfo[i].state = LEGACY;
5803 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5804 (FPT_scamInfo[i].id_string[1] != 0xFA))
5807 FPT_scamInfo[i].id_string[0] = 0xFF;
5808 FPT_scamInfo[i].id_string[1] = 0xFA;
5809 if(pCurrNvRam == NULL)
5810 currCard->globalFlags |= F_UPDATE_EEPROM;
5816 FPT_sresb(p_port,p_card);
5817 FPT_Wait1Second(p_port);
5818 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5820 FPT_scasid(p_card, p_port);
5825 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5827 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5829 FPT_scwtsel(p_port);
5832 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
5834 i = FPT_scxferc(p_port,0x00);
5837 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
5839 i = FPT_scxferc(p_port,0x00);
5842 k = FPT_scxferc(p_port,0x00);
5847 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
5848 FPT_inisci(p_card, p_port, p_our_id);
5849 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5850 FPT_scamInfo[currCard->ourId].id_string[0]
5858 else if (i == SET_P_FLAG)
5860 if (!(FPT_scsendi(p_port,
5861 &FPT_scamInfo[p_our_id].id_string[0])))
5862 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
5864 }while (!assigned_id);
5866 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
5869 if (ScamFlg & SCAM_ENABLED)
5872 if (currCard->globalFlags & F_UPDATE_EEPROM)
5874 FPT_scsavdi(p_card, p_port);
5875 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5881 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5883 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5884 (FPT_scamInfo[i].state == LEGACY))
5889 currCard->globalFlags |= F_SINGLE_DEVICE;
5891 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5896 /*---------------------------------------------------------------------
5898 * Function: FPT_scarb
5900 * Description: Gain control of the bus and wait SCAM select time (250ms)
5902 *---------------------------------------------------------------------*/
5904 static int FPT_scarb(ULONG p_port, unsigned char p_sel_type)
5906 if (p_sel_type == INIT_SELTD)
5909 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5912 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
5915 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
5918 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5920 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5922 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5928 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5930 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5932 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5933 ~(SCSI_BSY | SCSI_SEL)));
5939 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5941 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5942 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5943 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
5944 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5946 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5948 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5951 FPT_Wait(p_port,TO_250ms);
5957 /*---------------------------------------------------------------------
5959 * Function: FPT_scbusf
5961 * Description: Release the SCSI bus and disable SCAM selection.
5963 *---------------------------------------------------------------------*/
5965 static void FPT_scbusf(ULONG p_port)
5967 WR_HARPOON(p_port+hp_page_ctrl,
5968 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5971 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5973 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5976 WR_HARPOON(p_port+hp_scsisig, 0x00);
5979 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5982 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5985 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5987 WR_HARPOON(p_port+hp_page_ctrl,
5988 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5993 /*---------------------------------------------------------------------
5995 * Function: FPT_scasid
5997 * Description: Assign an ID to all the SCAM devices.
5999 *---------------------------------------------------------------------*/
6001 static void FPT_scasid(unsigned char p_card, ULONG p_port)
6003 unsigned char temp_id_string[ID_STRING_LENGTH];
6005 unsigned char i,k,scam_id;
6006 unsigned char crcBytes[3];
6007 PNVRamInfo pCurrNvRam;
6008 ushort_ptr pCrcBytes;
6010 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6017 for (k=0; k < ID_STRING_LENGTH; k++)
6019 temp_id_string[k] = (unsigned char) 0x00;
6022 FPT_scxferc(p_port,SYNC_PTRN);
6023 FPT_scxferc(p_port,ASSIGN_ID);
6025 if (!(FPT_sciso(p_port,&temp_id_string[0])))
6028 pCrcBytes = (ushort_ptr)&crcBytes[0];
6029 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6030 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
6031 temp_id_string[1] = crcBytes[2];
6032 temp_id_string[2] = crcBytes[0];
6033 temp_id_string[3] = crcBytes[1];
6034 for(k = 4; k < ID_STRING_LENGTH; k++)
6035 temp_id_string[k] = (unsigned char) 0x00;
6037 i = FPT_scmachid(p_card,temp_id_string);
6039 if (i == CLR_PRIORITY)
6041 FPT_scxferc(p_port,MISC_CODE);
6042 FPT_scxferc(p_port,CLR_P_FLAG);
6043 i = 0; /*Not the last ID yet. */
6046 else if (i != NO_ID_AVAIL)
6049 FPT_scxferc(p_port,ID_0_7);
6051 FPT_scxferc(p_port,ID_8_F);
6053 scam_id = (i & (unsigned char) 0x07);
6056 for (k=1; k < 0x08; k <<= 1)
6058 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6060 FPT_scxferc(p_port,scam_id);
6062 i = 0; /*Not the last ID yet. */
6073 FPT_scxferc(p_port,SYNC_PTRN);
6074 FPT_scxferc(p_port,CFG_CMPLT);
6081 /*---------------------------------------------------------------------
6083 * Function: FPT_scsel
6085 * Description: Select all the SCAM devices.
6087 *---------------------------------------------------------------------*/
6089 static void FPT_scsel(ULONG p_port)
6092 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6093 FPT_scwiros(p_port, SCSI_MSG);
6095 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6098 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6099 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6100 (unsigned char)(BIT(7)+BIT(6))));
6103 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6104 FPT_scwiros(p_port, SCSI_SEL);
6106 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6107 ~(unsigned char)BIT(6)));
6108 FPT_scwirod(p_port, BIT(6));
6110 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6115 /*---------------------------------------------------------------------
6117 * Function: FPT_scxferc
6119 * Description: Handshake the p_data (DB4-0) across the bus.
6121 *---------------------------------------------------------------------*/
6123 static unsigned char FPT_scxferc(ULONG p_port, unsigned char p_data)
6125 unsigned char curr_data, ret_data;
6127 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6129 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6131 curr_data &= ~BIT(7);
6133 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6135 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
6136 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6138 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
6140 curr_data |= BIT(6);
6142 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6144 curr_data &= ~BIT(5);
6146 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6148 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
6150 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6151 curr_data |= BIT(7);
6153 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6155 curr_data &= ~BIT(6);
6157 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6159 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
6165 /*---------------------------------------------------------------------
6167 * Function: FPT_scsendi
6169 * Description: Transfer our Identification string to determine if we
6170 * will be the dominant master.
6172 *---------------------------------------------------------------------*/
6174 static unsigned char FPT_scsendi(ULONG p_port, unsigned char p_id_string[])
6176 unsigned char ret_data,byte_cnt,bit_cnt,defer;
6180 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6182 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6185 ret_data = FPT_scxferc(p_port,00);
6187 else if (p_id_string[byte_cnt] & bit_cnt)
6189 ret_data = FPT_scxferc(p_port,02);
6193 ret_data = FPT_scxferc(p_port,01);
6198 if ((ret_data & 0x1C) == 0x10)
6199 return(0x00); /*End of isolation stage, we won! */
6201 if (ret_data & 0x1C)
6204 if ((defer) && (!(ret_data & 0x1F)))
6205 return(0x01); /*End of isolation stage, we lost. */
6212 return(0x01); /*We lost */
6214 return(0); /*We WON! Yeeessss! */
6219 /*---------------------------------------------------------------------
6221 * Function: FPT_sciso
6223 * Description: Transfer the Identification string.
6225 *---------------------------------------------------------------------*/
6227 static unsigned char FPT_sciso(ULONG p_port, unsigned char p_id_string[])
6229 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
6233 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6235 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6237 ret_data = FPT_scxferc(p_port,0);
6239 if (ret_data & 0xFC)
6245 if (ret_data & BIT(1)) {
6250 if ((ret_data & 0x1F) == 0)
6253 if(bit_cnt != 0 || bit_cnt != 8)
6257 FPT_scxferc(p_port, SYNC_PTRN);
6258 FPT_scxferc(p_port, ASSIGN_ID);
6270 p_id_string[byte_cnt] = the_data;
6279 /*---------------------------------------------------------------------
6281 * Function: FPT_scwirod
6283 * Description: Sample the SCSI data bus making sure the signal has been
6284 * deasserted for the correct number of consecutive samples.
6286 *---------------------------------------------------------------------*/
6288 static void FPT_scwirod(ULONG p_port, unsigned char p_data_bit)
6293 while ( i < MAX_SCSI_TAR ) {
6295 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6308 /*---------------------------------------------------------------------
6310 * Function: FPT_scwiros
6312 * Description: Sample the SCSI Signal lines making sure the signal has been
6313 * deasserted for the correct number of consecutive samples.
6315 *---------------------------------------------------------------------*/
6317 static void FPT_scwiros(ULONG p_port, unsigned char p_data_bit)
6322 while ( i < MAX_SCSI_TAR ) {
6324 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6336 /*---------------------------------------------------------------------
6338 * Function: FPT_scvalq
6340 * Description: Make sure we received a valid data byte.
6342 *---------------------------------------------------------------------*/
6344 static unsigned char FPT_scvalq(unsigned char p_quintet)
6346 unsigned char count;
6348 for (count=1; count < 0x08; count<<=1) {
6349 if (!(p_quintet & count))
6353 if (p_quintet & 0x18)
6361 /*---------------------------------------------------------------------
6363 * Function: FPT_scsell
6365 * Description: Select the specified device ID using a selection timeout
6366 * less than 4ms. If somebody responds then it is a legacy
6367 * drive and this ID must be marked as such.
6369 *---------------------------------------------------------------------*/
6371 static unsigned char FPT_scsell(ULONG p_port, unsigned char targ_id)
6375 WR_HARPOON(p_port+hp_page_ctrl,
6376 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6378 ARAM_ACCESS(p_port);
6380 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6381 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6384 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6385 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6387 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6389 WRW_HARPOON((p_port+hp_intstat),
6390 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6392 WR_HARPOON(p_port+hp_select_id, targ_id);
6394 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6395 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6396 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6399 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6400 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6402 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6403 FPT_Wait(p_port, TO_250ms);
6405 DISABLE_AUTO(p_port);
6407 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6408 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6410 SGRAM_ACCESS(p_port);
6412 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6414 WRW_HARPOON((p_port+hp_intstat),
6415 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6417 WR_HARPOON(p_port+hp_page_ctrl,
6418 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6420 return(0); /*No legacy device */
6425 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6426 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6428 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6433 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6435 WR_HARPOON(p_port+hp_page_ctrl,
6436 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6438 return(1); /*Found one of them oldies! */
6442 /*---------------------------------------------------------------------
6444 * Function: FPT_scwtsel
6446 * Description: Wait to be selected by another SCAM initiator.
6448 *---------------------------------------------------------------------*/
6450 static void FPT_scwtsel(ULONG p_port)
6452 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6456 /*---------------------------------------------------------------------
6458 * Function: FPT_inisci
6460 * Description: Setup the data Structure with the info from the EEPROM.
6462 *---------------------------------------------------------------------*/
6464 static void FPT_inisci(unsigned char p_card, ULONG p_port, unsigned char p_our_id)
6466 unsigned char i,k,max_id;
6467 unsigned short ee_data;
6468 PNVRamInfo pCurrNvRam;
6470 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6472 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6479 for(i = 0; i < max_id; i++){
6481 for(k = 0; k < 4; k++)
6482 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
6483 for(k = 4; k < ID_STRING_LENGTH; k++)
6484 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
6486 if(FPT_scamInfo[i].id_string[0] == 0x00)
6487 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6489 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6493 for (i=0; i < max_id; i++)
6495 for (k=0; k < ID_STRING_LENGTH; k+=2)
6497 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6498 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6499 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
6501 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
6504 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6505 (FPT_scamInfo[i].id_string[0] == 0xFF))
6507 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6510 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6514 for(k = 0; k < ID_STRING_LENGTH; k++)
6515 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6519 /*---------------------------------------------------------------------
6521 * Function: FPT_scmachid
6523 * Description: Match the Device ID string with our values stored in
6526 *---------------------------------------------------------------------*/
6528 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
6531 unsigned char i,k,match;
6534 for (i=0; i < MAX_SCSI_TAR; i++) {
6538 for (k=0; k < ID_STRING_LENGTH; k++)
6540 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6546 FPT_scamInfo[i].state = ID_ASSIGNED;
6554 if (p_id_string[0] & BIT(5))
6559 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6560 match = p_id_string[1] & (unsigned char) 0x1F;
6568 if (FPT_scamInfo[match].state == ID_UNUSED)
6570 for (k=0; k < ID_STRING_LENGTH; k++)
6572 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6575 FPT_scamInfo[match].state = ID_ASSIGNED;
6577 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6578 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6588 if (p_id_string[0] & BIT(5))
6591 match = MAX_SCSI_TAR-1;
6597 if (p_id_string[0] & BIT(7))
6599 return(CLR_PRIORITY);
6603 if (p_id_string[0] & BIT(5))
6608 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6609 match = p_id_string[1] & (unsigned char) 0x1F;
6618 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
6620 for (k=0; k < ID_STRING_LENGTH; k++)
6622 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6625 FPT_scamInfo[match].id_string[0] |= BIT(7);
6626 FPT_scamInfo[match].state = ID_ASSIGNED;
6627 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6628 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6638 if (p_id_string[0] & BIT(5))
6641 match = MAX_SCSI_TAR-1;
6645 return(NO_ID_AVAIL);
6649 /*---------------------------------------------------------------------
6651 * Function: FPT_scsavdi
6653 * Description: Save off the device SCAM ID strings.
6655 *---------------------------------------------------------------------*/
6657 static void FPT_scsavdi(unsigned char p_card, ULONG p_port)
6659 unsigned char i,k,max_id;
6660 unsigned short ee_data,sum_data;
6665 for (i = 1; i < EE_SCAMBASE/2; i++)
6667 sum_data += FPT_utilEERead(p_port, i);
6671 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
6673 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6679 for (i=0; i < max_id; i++)
6682 for (k=0; k < ID_STRING_LENGTH; k+=2)
6684 ee_data = FPT_scamInfo[i].id_string[k+1];
6686 ee_data |= FPT_scamInfo[i].id_string[k];
6687 sum_data += ee_data;
6688 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6689 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6694 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6695 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
6698 /*---------------------------------------------------------------------
6700 * Function: FPT_XbowInit
6702 * Description: Setup the Xbow for normal operation.
6704 *---------------------------------------------------------------------*/
6706 static void FPT_XbowInit(ULONG port, unsigned char ScamFlg)
6710 i = RD_HARPOON(port+hp_page_ctrl);
6711 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
6713 WR_HARPOON(port+hp_scsireset,0x00);
6714 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6716 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6719 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6721 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6723 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6724 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6726 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6728 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6729 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6731 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6732 FPT_default_intena |= SCAM_SEL;
6734 WRW_HARPOON((port+hp_intena), FPT_default_intena);
6736 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6738 /* Turn on SCSI_MODE8 for narrow cards to fix the
6739 strapping issue with the DUAL CHANNEL card */
6740 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6741 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6743 WR_HARPOON(port+hp_page_ctrl, i);
6748 /*---------------------------------------------------------------------
6750 * Function: FPT_BusMasterInit
6752 * Description: Initialize the BusMaster for normal operations.
6754 *---------------------------------------------------------------------*/
6756 static void FPT_BusMasterInit(ULONG p_port)
6760 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6761 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6763 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6766 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6768 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6771 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6772 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6773 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6778 /*---------------------------------------------------------------------
6780 * Function: FPT_DiagEEPROM
6782 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6785 *---------------------------------------------------------------------*/
6787 static void FPT_DiagEEPROM(ULONG p_port)
6789 unsigned short index,temp,max_wd_cnt;
6791 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6792 max_wd_cnt = EEPROM_WD_CNT;
6794 max_wd_cnt = EEPROM_WD_CNT * 2;
6796 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
6798 if (temp == 0x4641) {
6800 for (index = 2; index < max_wd_cnt; index++) {
6802 temp += FPT_utilEERead(p_port, index);
6806 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
6808 return; /*EEPROM is Okay so return now! */
6813 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
6815 for (index = 0; index < max_wd_cnt; index++) {
6817 FPT_utilEEWrite(p_port, 0x0000, index);
6822 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
6824 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
6826 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
6828 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
6830 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
6832 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
6834 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
6836 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
6839 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
6841 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
6843 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
6846 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
6848 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
6850 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
6852 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
6854 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
6856 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
6858 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
6860 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
6864 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
6866 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
6868 FPT_utilEEWrite(p_port, 0x5068, 68/2);
6870 FPT_utilEEWrite(p_port, 0x696F, 70/2);
6872 FPT_utilEEWrite(p_port, 0x746E, 72/2);
6874 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
6876 FPT_utilEEWrite(p_port, 0x2054, 76/2);
6878 FPT_utilEEWrite(p_port, 0x2020, 78/2);
6881 index = ((EE_SCAMBASE/2)+(7*16));
6882 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
6883 temp += (0x0700+TYPE_CODE0);
6885 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6886 temp += 0x5542; /* BUSLOGIC */
6888 FPT_utilEEWrite(p_port, 0x4C53, index);
6891 FPT_utilEEWrite(p_port, 0x474F, index);
6894 FPT_utilEEWrite(p_port, 0x4349, index);
6897 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6898 temp += 0x5442; /* BT- 930 */
6900 FPT_utilEEWrite(p_port, 0x202D, index);
6903 FPT_utilEEWrite(p_port, 0x3339, index);
6905 index++; /*Serial # */
6906 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6909 FPT_utilEEWrite(p_port, 0x5453, index);
6912 FPT_utilEEWrite(p_port, 0x5645, index);
6915 FPT_utilEEWrite(p_port, 0x2045, index);
6918 FPT_utilEEWrite(p_port, 0x202F, index);
6921 FPT_utilEEWrite(p_port, 0x4F4A, index);
6924 FPT_utilEEWrite(p_port, 0x204E, index);
6927 FPT_utilEEWrite(p_port, 0x3539, index);
6932 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
6934 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
6939 /*---------------------------------------------------------------------
6941 * Function: Queue Search Select
6943 * Description: Try to find a new command to execute.
6945 *---------------------------------------------------------------------*/
6947 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
6949 unsigned char scan_ptr, lun;
6950 PSCCBMgr_tar_info currTar_Info;
6953 scan_ptr = pCurrCard->scanIndex;
6956 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6957 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6958 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6960 if (currTar_Info->TarSelQ_Cnt != 0)
6964 if (scan_ptr == MAX_SCSI_TAR)
6967 for(lun=0; lun < MAX_LUN; lun++)
6969 if(currTar_Info->TarLUNBusy[lun] == 0)
6972 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6975 while((pCurrCard->currentSCCB != NULL) &&
6976 (lun != pCurrCard->currentSCCB->Lun))
6978 pOldSccb = pCurrCard->currentSCCB;
6979 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6982 if(pCurrCard->currentSCCB == NULL)
6984 if(pOldSccb != NULL)
6986 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6988 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6990 currTar_Info->TarSelQ_Cnt--;
6994 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6996 if (currTar_Info->TarSelQ_Head == NULL)
6998 currTar_Info->TarSelQ_Tail = NULL;
6999 currTar_Info->TarSelQ_Cnt = 0;
7003 currTar_Info->TarSelQ_Cnt--;
7004 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7007 pCurrCard->scanIndex = scan_ptr;
7009 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7019 if (scan_ptr == MAX_SCSI_TAR) {
7027 if ((currTar_Info->TarSelQ_Cnt != 0) &&
7028 (currTar_Info->TarLUNBusy[0] == 0))
7031 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7033 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7035 if (currTar_Info->TarSelQ_Head == NULL)
7037 currTar_Info->TarSelQ_Tail = NULL;
7038 currTar_Info->TarSelQ_Cnt = 0;
7042 currTar_Info->TarSelQ_Cnt--;
7043 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7047 if (scan_ptr == MAX_SCSI_TAR)
7050 pCurrCard->scanIndex = scan_ptr;
7052 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7060 if (scan_ptr == MAX_SCSI_TAR)
7066 } while (scan_ptr != pCurrCard->scanIndex);
7070 /*---------------------------------------------------------------------
7072 * Function: Queue Select Fail
7074 * Description: Add the current SCCB to the head of the Queue.
7076 *---------------------------------------------------------------------*/
7078 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
7080 unsigned char thisTarg;
7081 PSCCBMgr_tar_info currTar_Info;
7083 if (pCurrCard->currentSCCB != NULL)
7085 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
7086 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7088 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7090 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7092 if (currTar_Info->TarSelQ_Cnt == 0)
7094 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7099 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7103 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7105 pCurrCard->currentSCCB = NULL;
7106 currTar_Info->TarSelQ_Cnt++;
7109 /*---------------------------------------------------------------------
7111 * Function: Queue Command Complete
7113 * Description: Call the callback function with the current SCCB.
7115 *---------------------------------------------------------------------*/
7117 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7118 unsigned char p_card)
7121 unsigned char i, SCSIcmd;
7122 CALL_BK_FN callback;
7123 PSCCBMgr_tar_info currTar_Info;
7125 SCSIcmd = p_sccb->Cdb[0];
7128 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7130 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7131 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7132 (p_sccb->TargetStatus != SSCHECK))
7134 if ((SCSIcmd == SCSI_READ) ||
7135 (SCSIcmd == SCSI_WRITE) ||
7136 (SCSIcmd == SCSI_READ_EXTENDED) ||
7137 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7138 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7139 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7140 (pCurrCard->globalFlags & F_NO_FILTER)
7142 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7146 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7148 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7149 p_sccb->SccbStatus = SCCB_ERROR;
7151 p_sccb->SccbStatus = SCCB_SUCCESS;
7154 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7156 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7157 for (i=0; i < 6; i++) {
7158 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7162 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7163 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7165 FPT_utilUpdateResidual(p_sccb);
7168 pCurrCard->cmdCounter--;
7169 if (!pCurrCard->cmdCounter) {
7171 if (pCurrCard->globalFlags & F_GREEN_PC) {
7172 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7173 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7176 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7177 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7181 if(pCurrCard->discQCount != 0)
7183 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7184 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7185 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7187 pCurrCard->discQCount--;
7188 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7192 if(p_sccb->Sccb_tag)
7194 pCurrCard->discQCount--;
7195 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7198 pCurrCard->discQCount--;
7199 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7205 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7207 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7208 pCurrCard->currentSCCB = NULL;
7212 /*---------------------------------------------------------------------
7214 * Function: Queue Disconnect
7216 * Description: Add SCCB to our disconnect array.
7218 *---------------------------------------------------------------------*/
7219 static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
7221 PSCCBMgr_tar_info currTar_Info;
7223 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7225 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7226 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7228 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
7232 if (p_sccb->Sccb_tag)
7234 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7235 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7236 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7239 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
7242 FPT_BL_Card[p_card].currentSCCB = NULL;
7246 /*---------------------------------------------------------------------
7248 * Function: Queue Flush SCCB
7250 * Description: Flush all SCCB's back to the host driver for this target.
7252 *---------------------------------------------------------------------*/
7254 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
7256 unsigned char qtag,thisTarg;
7258 PSCCBMgr_tar_info currTar_Info;
7260 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7261 if(currSCCB != NULL)
7263 thisTarg = (unsigned char)currSCCB->TargID;
7264 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7266 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7268 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7269 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7272 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7274 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7276 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7277 currTar_Info->TarTagQ_Cnt--;
7285 /*---------------------------------------------------------------------
7287 * Function: Queue Flush Target SCCB
7289 * Description: Flush all SCCB's back to the host driver for this target.
7291 *---------------------------------------------------------------------*/
7293 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7294 unsigned char error_code)
7297 PSCCBMgr_tar_info currTar_Info;
7299 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7301 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7303 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7304 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7307 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7309 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7311 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7312 currTar_Info->TarTagQ_Cnt--;
7323 static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
7325 PSCCBMgr_tar_info currTar_Info;
7326 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7328 p_SCCB->Sccb_forwardlink = NULL;
7330 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7332 if (currTar_Info->TarSelQ_Cnt == 0) {
7334 currTar_Info->TarSelQ_Head = p_SCCB;
7339 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7343 currTar_Info->TarSelQ_Tail = p_SCCB;
7344 currTar_Info->TarSelQ_Cnt++;
7348 /*---------------------------------------------------------------------
7350 * Function: Queue Find SCCB
7352 * Description: Search the target select Queue for this SCCB, and
7353 * remove it if found.
7355 *---------------------------------------------------------------------*/
7357 static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
7360 PSCCBMgr_tar_info currTar_Info;
7362 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7364 q_ptr = currTar_Info->TarSelQ_Head;
7366 while(q_ptr != NULL) {
7368 if (q_ptr == p_SCCB) {
7371 if (currTar_Info->TarSelQ_Head == q_ptr) {
7373 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7376 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7378 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7381 if (q_ptr->Sccb_forwardlink != NULL) {
7382 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7385 if (q_ptr->Sccb_backlink != NULL) {
7386 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7389 currTar_Info->TarSelQ_Cnt--;
7395 q_ptr = q_ptr->Sccb_forwardlink;
7405 /*---------------------------------------------------------------------
7407 * Function: Utility Update Residual Count
7409 * Description: Update the XferCnt to the remaining byte count.
7410 * If we transferred all the data then just write zero.
7411 * If Non-SG transfer then report Total Cnt - Actual Transfer
7412 * Cnt. For SG transfers add the count fields of all
7413 * remaining SG elements, as well as any partial remaining
7416 *---------------------------------------------------------------------*/
7418 static void FPT_utilUpdateResidual(PSCCB p_SCCB)
7424 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7426 p_SCCB->DataLength = 0x0000;
7429 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7431 partial_cnt = 0x0000;
7433 sg_index = p_SCCB->Sccb_sgseg;
7435 sg_ptr = (ULONG *)p_SCCB->DataPointer;
7437 if (p_SCCB->Sccb_SGoffset) {
7439 partial_cnt = p_SCCB->Sccb_SGoffset;
7443 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7444 p_SCCB->DataLength ) {
7446 partial_cnt += *(sg_ptr+(sg_index * 2));
7450 p_SCCB->DataLength = partial_cnt;
7455 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7460 /*---------------------------------------------------------------------
7462 * Function: Wait 1 Second
7464 * Description: Wait for 1 second.
7466 *---------------------------------------------------------------------*/
7468 static void FPT_Wait1Second(ULONG p_port)
7472 for(i=0; i < 4; i++) {
7474 FPT_Wait(p_port, TO_250ms);
7476 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7479 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7485 /*---------------------------------------------------------------------
7487 * Function: FPT_Wait
7489 * Description: Wait the desired delay.
7491 *---------------------------------------------------------------------*/
7493 static void FPT_Wait(ULONG p_port, unsigned char p_delay)
7495 unsigned char old_timer;
7496 unsigned char green_flag;
7498 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7500 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7501 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7503 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7504 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7505 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
7508 WR_HARPOON(p_port+hp_portctrl_0,
7509 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7511 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7513 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7516 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7520 WR_HARPOON(p_port+hp_portctrl_0,
7521 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7523 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7524 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
7526 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7528 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7532 /*---------------------------------------------------------------------
7534 * Function: Enable/Disable Write to EEPROM
7536 * Description: The EEPROM must first be enabled for writes
7537 * A total of 9 clocks are needed.
7539 *---------------------------------------------------------------------*/
7541 static void FPT_utilEEWriteOnOff(ULONG p_port,unsigned char p_mode)
7543 unsigned char ee_value;
7545 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7549 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7554 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7556 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7557 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7561 /*---------------------------------------------------------------------
7563 * Function: Write EEPROM
7565 * Description: Write a word to the EEPROM at the specified
7568 *---------------------------------------------------------------------*/
7570 static void FPT_utilEEWrite(ULONG p_port, unsigned short ee_data, unsigned short ee_addr)
7573 unsigned char ee_value;
7576 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7581 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7584 ee_value |= (SEE_MS + SEE_CS);
7586 for(i = 0x8000; i != 0; i>>=1) {
7591 ee_value &= ~SEE_DO;
7593 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7594 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7595 ee_value |= SEE_CLK; /* Clock data! */
7596 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7597 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7598 ee_value &= ~SEE_CLK;
7599 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7600 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7602 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7603 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7605 FPT_Wait(p_port, TO_10ms);
7607 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7608 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7609 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7612 /*---------------------------------------------------------------------
7614 * Function: Read EEPROM
7616 * Description: Read a word from the EEPROM at the desired
7619 *---------------------------------------------------------------------*/
7621 static unsigned short FPT_utilEERead(ULONG p_port, unsigned short ee_addr)
7623 unsigned short i, ee_data1, ee_data2;
7626 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7629 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7631 if(ee_data1 == ee_data2)
7634 ee_data1 = ee_data2;
7642 /*---------------------------------------------------------------------
7644 * Function: Read EEPROM Original
7646 * Description: Read a word from the EEPROM at the desired
7649 *---------------------------------------------------------------------*/
7651 static unsigned short FPT_utilEEReadOrg(ULONG p_port, unsigned short ee_addr)
7654 unsigned char ee_value;
7655 unsigned short i, ee_data;
7657 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7661 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7664 ee_value |= (SEE_MS + SEE_CS);
7667 for(i = 1; i <= 16; i++) {
7669 ee_value |= SEE_CLK; /* Clock data! */
7670 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7671 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7672 ee_value &= ~SEE_CLK;
7673 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7674 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7678 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7682 ee_value &= ~(SEE_MS + SEE_CS);
7683 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7684 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7690 /*---------------------------------------------------------------------
7692 * Function: Send EE command and Address to the EEPROM
7694 * Description: Transfers the correct command and sends the address
7697 *---------------------------------------------------------------------*/
7699 static void FPT_utilEESendCmdAddr(ULONG p_port, unsigned char ee_cmd, unsigned short ee_addr)
7701 unsigned char ee_value;
7702 unsigned char narrow_flg;
7707 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7711 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7713 ee_value |= SEE_CS; /* Set CS to EEPROM */
7714 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7717 for(i = 0x04; i != 0; i>>=1) {
7722 ee_value &= ~SEE_DO;
7724 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7725 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7726 ee_value |= SEE_CLK; /* Clock data! */
7727 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7728 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7729 ee_value &= ~SEE_CLK;
7730 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7731 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7747 ee_value &= ~SEE_DO;
7749 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7750 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7751 ee_value |= SEE_CLK; /* Clock data! */
7752 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7753 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7754 ee_value &= ~SEE_CLK;
7755 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7756 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7762 static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7764 unsigned short crc=0;
7767 for (i=0; i < ID_STRING_LENGTH; i++)
7769 ch = (unsigned short) buffer[i];
7770 for(j=0; j < 8; j++)
7773 crc = (crc >> 1) ^ CRCMASK;
7782 static unsigned char FPT_CalcLrc(unsigned char buffer[])
7787 for(i = 0; i < ID_STRING_LENGTH; i++)
7795 The following inline definitions avoid type conflicts.
7798 static inline unsigned char
7799 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7801 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7805 static inline FlashPoint_CardHandle_T
7806 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7808 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7812 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7814 FlashPoint_ReleaseHostAdapter(CardHandle);
7819 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7821 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7826 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7828 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7832 static inline boolean
7833 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7835 return FlashPoint_InterruptPending(CardHandle);
7840 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7842 return FlashPoint_HandleInterrupt(CardHandle);
7846 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7847 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7848 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7849 #define FlashPoint_StartCCB FlashPoint__StartCCB
7850 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7851 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7852 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7855 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7859 Define prototypes for the FlashPoint SCCB Manager Functions.
7862 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7863 extern FlashPoint_CardHandle_T
7864 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7865 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7866 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7867 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7868 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7869 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7872 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */