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
29 #define OS_InPortByte(port) inb(port)
30 #define OS_InPortWord(port) inw(port)
31 #define OS_InPortLong(port) inl(port)
32 #define OS_OutPortByte(port, value) outb(value, port)
33 #define OS_OutPortWord(port, value) outw(value, port)
34 #define OS_OutPortLong(port, value) outl(value, port)
38 Define name replacements for compatibility with the Linux BusLogic Driver.
41 #define SccbMgr_sense_adapter FlashPoint_ProbeHostAdapter
42 #define SccbMgr_config_adapter FlashPoint_HardwareResetHostAdapter
43 #define SccbMgr_unload_card FlashPoint_ReleaseHostAdapter
44 #define SccbMgr_start_sccb FlashPoint_StartCCB
45 #define SccbMgr_abort_sccb FlashPoint_AbortCCB
46 #define SccbMgr_my_int FlashPoint_InterruptPending
47 #define SccbMgr_isr FlashPoint_HandleInterrupt
52 #define CRCMASK 0xA001
56 #define FAILURE 0xFFFFFFFFL
59 typedef unsigned char UCHAR;
60 typedef unsigned short USHORT;
61 typedef unsigned int UINT;
62 typedef unsigned long ULONG;
65 typedef unsigned short * ushort_ptr;
72 #define u08bits unsigned s08bits
73 #define u16bits unsigned s16bits
74 #define u32bits unsigned s32bits
78 #define BIT(x) ((UCHAR)(1<<(x))) /* single-bit mask in bit position x */
79 #define BITW(x) ((USHORT)(1<<(x))) /* single-bit mask in bit position x */
84 typedef struct _SCCB *PSCCB;
85 typedef void (*CALL_BK_FN)(PSCCB);
88 typedef struct SCCBMgr_info {
94 USHORT si_fw_revision;
95 USHORT si_per_targ_init_sync;
96 USHORT si_per_targ_fast_nego;
97 USHORT si_per_targ_ultra_nego;
98 USHORT si_per_targ_no_disc;
99 USHORT si_per_targ_wide_nego;
101 UCHAR si_card_family;
103 UCHAR si_card_model[3];
104 UCHAR si_relative_cardnum;
105 UCHAR si_reserved[4];
106 ULONG si_OS_reserved;
107 UCHAR si_XlatInfo[4];
108 ULONG si_reserved2[5];
109 ULONG si_secondary_range;
112 typedef SCCBMGR_INFO * PSCCBMGR_INFO;
115 #define SCSI_PARITY_ENA 0x0001
116 #define LOW_BYTE_TERM 0x0010
117 #define HIGH_BYTE_TERM 0x0020
118 #define BUSTYPE_PCI 0x3
120 #define SUPPORT_16TAR_32LUN 0x0002
121 #define SOFT_RESET 0x0004
122 #define EXTENDED_TRANSLATION 0x0008
123 #define POST_ALL_UNDERRRUNS 0x0040
124 #define FLAG_SCAM_ENABLED 0x0080
125 #define FLAG_SCAM_LEVEL2 0x0100
130 #define HARPOON_FAMILY 0x02
134 /* SCCB struct used for both SCCB and UCB manager compiles!
135 * The UCB Manager treats the SCCB as it's 'native hardware structure'
140 typedef struct _SCCB {
144 UCHAR RequestSenseLength;
159 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
160 ULONG SccbIOPort; /* Identifies board base port */
166 ULONG Sccb_XferCnt; /* actual transfer count */
168 ULONG SccbVirtDataPtr; /* virtual addr for OS/2 */
170 USHORT Sccb_MGRFlags;
172 UCHAR Sccb_scsimsg; /* identify msg for selection */
175 UCHAR Sccb_idmsg; /* image of last msg in */
176 PSCCB Sccb_forwardlink;
181 UCHAR Sccb_XferState;
190 #define SCATTER_GATHER_COMMAND 0x02
191 #define RESIDUAL_COMMAND 0x03
192 #define RESIDUAL_SG_COMMAND 0x04
193 #define RESET_COMMAND 0x81
196 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
197 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
198 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
199 #define SCCB_DATA_XFER_IN 0x08 /* Read */
202 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
205 #define BUS_FREE_ST 0
207 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
208 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
209 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
210 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
212 #define DATA_OUT_ST 7
214 #define DISCONNECT_ST 9
218 #define F_HOST_XFER_DIR 0x01
219 #define F_ALL_XFERRED 0x02
220 #define F_SG_XFER 0x04
221 #define F_AUTO_SENSE 0x08
222 #define F_ODD_BALL_CNT 0x10
223 #define F_NO_DATA_YET 0x80
226 #define F_STATUSLOADED 0x01
227 #define F_DEV_SELECTED 0x04
230 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
231 #define SCCB_DATA_UNDER_RUN 0x0C
232 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
233 #define SCCB_DATA_OVER_RUN 0x12
234 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
236 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
237 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
238 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
244 #define SCCB_IN_PROCESS 0x00
245 #define SCCB_SUCCESS 0x01
246 #define SCCB_ABORT 0x02
247 #define SCCB_ERROR 0x04
251 #define ORION_FW_REV 3110
255 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
257 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
260 #define MAX_SCSI_TAR 16
262 #define LUN_MASK 0x1f
264 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
266 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
269 #define RD_HARPOON(ioport) OS_InPortByte((u32bits)ioport)
270 #define RDW_HARPOON(ioport) OS_InPortWord((u32bits)ioport)
271 #define RD_HARP32(ioport,offset,data) (data = OS_InPortLong((u32bits)(ioport + offset)))
272 #define WR_HARPOON(ioport,val) OS_OutPortByte((u32bits)ioport,(u08bits) val)
273 #define WRW_HARPOON(ioport,val) OS_OutPortWord((u32bits)ioport,(u16bits)val)
274 #define WR_HARP32(ioport,offset,data) OS_OutPortLong((u32bits)(ioport + offset), data)
277 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
278 #define SYNC_TRYING BIT(6)
279 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
281 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
282 #define WIDE_ENABLED BIT(4)
283 #define WIDE_NEGOCIATED BIT(5)
285 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
286 #define TAG_Q_TRYING BIT(2)
287 #define TAG_Q_REJECT BIT(3)
289 #define TAR_ALLOW_DISC BIT(0)
292 #define EE_SYNC_MASK (BIT(0)+BIT(1))
293 #define EE_SYNC_5MB BIT(0)
294 #define EE_SYNC_10MB BIT(1)
295 #define EE_SYNC_20MB (BIT(0)+BIT(1))
297 #define EE_WIDE_SCSI BIT(7)
300 typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
303 typedef struct SCCBMgr_tar_info {
307 UCHAR TarLUN_CA; /*Contingent Allgiance */
313 UCHAR TarReserved[2]; /* for alignment */
314 UCHAR LunDiscQ_Idx[MAX_LUN];
315 UCHAR TarLUNBusy[MAX_LUN];
318 typedef struct NVRAMInfo {
319 UCHAR niModel; /* Model No. of card */
320 UCHAR niCardNo; /* Card no. */
321 ULONG niBaseAddr; /* Port Address of card */
322 UCHAR niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
323 UCHAR niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
324 UCHAR niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
325 UCHAR niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
326 UCHAR niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
327 UCHAR niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
330 typedef NVRAMINFO *PNVRamInfo;
338 typedef struct SCCBcard {
340 PSCCBMGR_INFO cardInfo;
351 PNVRamInfo pNvRamInfo;
352 PSCCB discQ_Tbl[QUEUE_DEPTH];
356 typedef struct SCCBcard *PSCCBcard;
359 #define F_TAG_STARTED 0x01
360 #define F_CONLUN_IO 0x02
361 #define F_DO_RENEGO 0x04
362 #define F_NO_FILTER 0x08
363 #define F_GREEN_PC 0x10
364 #define F_HOST_XFER_ACT 0x20
365 #define F_NEW_SCCB_CMD 0x40
366 #define F_UPDATE_EEPROM 0x80
369 #define ID_STRING_LENGTH 32
370 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
373 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
375 #define ASSIGN_ID 0x00
376 #define SET_P_FLAG 0x01
377 #define CFG_CMPLT 0x03
378 #define DOM_MSTR 0x0F
379 #define SYNC_PTRN 0x1F
383 #define MISC_CODE 0x14
384 #define CLR_P_FLAG 0x18
388 #define INIT_SELTD 0x01
389 #define LEVEL2_TAR 0x02
392 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
393 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
394 CLR_PRIORITY,NO_ID_AVAIL };
396 typedef struct SCCBscam_info {
398 UCHAR id_string[ID_STRING_LENGTH];
399 enum scam_id_st state;
404 #define SCSI_REQUEST_SENSE 0x03
405 #define SCSI_READ 0x08
406 #define SCSI_WRITE 0x0A
407 #define SCSI_START_STOP_UNIT 0x1B
408 #define SCSI_READ_EXTENDED 0x28
409 #define SCSI_WRITE_EXTENDED 0x2A
410 #define SCSI_WRITE_AND_VERIFY 0x2E
416 #define SSQ_FULL 0x28
421 #define SMCMD_COMP 0x00
423 #define SMSAVE_DATA_PTR 0x02
424 #define SMREST_DATA_PTR 0x03
427 #define SMREJECT 0x07
429 #define SMPARITY 0x09
430 #define SMDEV_RESET 0x0C
431 #define SMABORT_TAG 0x0D
432 #define SMINIT_RECOVERY 0x0F
433 #define SMREL_RECOVERY 0x10
436 #define DISC_PRIV 0x40
443 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
452 #define SIX_BYTE_CMD 0x06
453 #define TWELVE_BYTE_CMD 0x0C
456 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
459 #define EEPROM_WD_CNT 256
461 #define EEPROM_CHECK_SUM 0
462 #define FW_SIGNATURE 2
463 #define MODEL_NUMB_0 4
464 #define MODEL_NUMB_2 6
465 #define MODEL_NUMB_4 8
466 #define SYSTEM_CONFIG 16
467 #define SCSI_CONFIG 17
468 #define BIOS_CONFIG 18
469 #define SCAM_CONFIG 20
470 #define ADAPTER_SCSI_ID 24
473 #define IGNORE_B_SCAN 32
474 #define SEND_START_ENA 34
475 #define DEVICE_ENABLE 36
477 #define SYNC_RATE_TBL 38
478 #define SYNC_RATE_TBL01 38
479 #define SYNC_RATE_TBL23 40
480 #define SYNC_RATE_TBL45 42
481 #define SYNC_RATE_TBL67 44
482 #define SYNC_RATE_TBL89 46
483 #define SYNC_RATE_TBLab 48
484 #define SYNC_RATE_TBLcd 50
485 #define SYNC_RATE_TBLef 52
489 #define EE_SCAMBASE 256
493 #define SCAM_ENABLED BIT(2)
494 #define SCAM_LEVEL2 BIT(3)
497 #define RENEGO_ENA BITW(10)
498 #define CONNIO_ENA BITW(11)
499 #define GREEN_PC_ENA BITW(12)
502 #define AUTO_RATE_00 00
503 #define AUTO_RATE_05 01
504 #define AUTO_RATE_10 02
505 #define AUTO_RATE_20 03
507 #define WIDE_NEGO_BIT BIT(7)
508 #define DISC_ENABLE_BIT BIT(6)
512 #define hp_vendor_id_0 0x00 /* LSB */
513 #define ORION_VEND_0 0x4B
515 #define hp_vendor_id_1 0x01 /* MSB */
516 #define ORION_VEND_1 0x10
518 #define hp_device_id_0 0x02 /* LSB */
519 #define ORION_DEV_0 0x30
521 #define hp_device_id_1 0x03 /* MSB */
522 #define ORION_DEV_1 0x81
524 /* Sub Vendor ID and Sub Device ID only available in
525 Harpoon Version 2 and higher */
527 #define hp_sub_device_id_0 0x06 /* LSB */
531 #define hp_semaphore 0x0C
532 #define SCCB_MGR_ACTIVE BIT(0)
533 #define TICKLE_ME BIT(1)
534 #define SCCB_MGR_PRESENT BIT(3)
535 #define BIOS_IN_USE BIT(4)
539 #define hp_sys_ctrl 0x0F
541 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
542 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
543 #define HALT_MACH BIT(3) /*Halt State Machine */
544 #define HARD_ABORT BIT(4) /*Hard Abort */
554 #define hp_host_blk_cnt 0x13
556 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
558 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
562 #define hp_int_mask 0x17
564 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
565 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
568 #define hp_xfer_cnt_lo 0x18
569 #define hp_xfer_cnt_hi 0x1A
570 #define hp_xfer_cmd 0x1B
572 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
573 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
576 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
578 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
580 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
582 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
583 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
585 #define hp_host_addr_lo 0x1C
586 #define hp_host_addr_hmi 0x1E
588 #define hp_ee_ctrl 0x22
590 #define EXT_ARB_ACK BIT(7)
591 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
592 #define SEE_MS BIT(5)
593 #define SEE_CS BIT(3)
594 #define SEE_CLK BIT(2)
595 #define SEE_DO BIT(1)
596 #define SEE_DI BIT(0)
599 #define EE_WRITE 0x05
601 #define EWEN_ADDR 0x03C0
603 #define EWDS_ADDR 0x0000
611 #define hp_bm_ctrl 0x26
613 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
614 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
615 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
616 #define FAST_SINGLE BIT(6) /*?? */
618 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
621 #define hp_sg_addr 0x28
622 #define hp_page_ctrl 0x29
624 #define SCATTER_EN BIT(0)
625 #define SGRAM_ARAM BIT(1)
626 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
627 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
632 #define hp_pci_stat_cfg 0x2D
634 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
643 #define hp_rev_num 0x33
646 #define hp_stack_data 0x34
647 #define hp_stack_addr 0x35
649 #define hp_ext_status 0x36
651 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
652 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
653 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
654 #define CMD_ABORTED BIT(4) /*Command aborted */
655 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
656 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
657 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
658 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
659 BM_PARITY_ERR | PIO_OVERRUN)
661 #define hp_int_status 0x37
663 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
664 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
665 #define INT_ASSERTED BIT(5) /* */
668 #define hp_fifo_cnt 0x38
673 #define hp_intena 0x40
675 #define RESET BITW(7)
676 #define PROG_HLT BITW(6)
677 #define PARITY BITW(5)
680 #define SCAM_SEL BITW(2)
682 #define TIMEOUT BITW(0)
683 #define BUS_FREE BITW(15)
684 #define XFER_CNT_0 BITW(14)
685 #define PHASE BITW(13)
686 #define IUNKWN BITW(12)
687 #define ICMD_COMP BITW(11)
688 #define ITICKLE BITW(10)
689 #define IDO_STRT BITW(9)
690 #define ITAR_DISC BITW(8)
691 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
692 #define CLR_ALL_INT 0xFFFF
693 #define CLR_ALL_INT_1 0xFF00
695 #define hp_intstat 0x42
697 #define hp_scsisig 0x44
699 #define SCSI_SEL BIT(7)
700 #define SCSI_BSY BIT(6)
701 #define SCSI_REQ BIT(5)
702 #define SCSI_ACK BIT(4)
703 #define SCSI_ATN BIT(3)
704 #define SCSI_CD BIT(2)
705 #define SCSI_MSG BIT(1)
706 #define SCSI_IOBIT BIT(0)
708 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
709 #define S_MSGO_PH (BIT(2)+BIT(1) )
710 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
711 #define S_DATAI_PH ( BIT(0))
712 #define S_DATAO_PH 0x00
713 #define S_ILL_PH ( BIT(1) )
715 #define hp_scsictrl_0 0x45
717 #define SEL_TAR BIT(6)
718 #define ENA_ATN BIT(4)
719 #define ENA_RESEL BIT(2)
720 #define SCSI_RST BIT(1)
721 #define ENA_SCAM_SEL BIT(0)
725 #define hp_portctrl_0 0x46
727 #define SCSI_PORT BIT(7)
728 #define SCSI_INBIT BIT(6)
729 #define DMA_PORT BIT(5)
730 #define DMA_RD BIT(4)
731 #define HOST_PORT BIT(3)
732 #define HOST_WRT BIT(2)
733 #define SCSI_BUS_EN BIT(1)
734 #define START_TO BIT(0)
736 #define hp_scsireset 0x47
738 #define SCSI_INI BIT(6)
739 #define SCAM_EN BIT(5)
740 #define DMA_RESET BIT(3)
741 #define HPSCSI_RESET BIT(2)
742 #define PROG_RESET BIT(1)
743 #define FIFO_CLR BIT(0)
745 #define hp_xfercnt_0 0x48
746 #define hp_xfercnt_2 0x4A
748 #define hp_fifodata_0 0x4C
749 #define hp_addstat 0x4E
751 #define SCAM_TIMER BIT(7)
752 #define SCSI_MODE8 BIT(3)
753 #define SCSI_PAR_ERR BIT(0)
755 #define hp_prgmcnt_0 0x4F
758 #define hp_selfid_0 0x50
759 #define hp_selfid_1 0x51
760 #define hp_arb_id 0x52
763 #define hp_select_id 0x53
766 #define hp_synctarg_base 0x54
767 #define hp_synctarg_12 0x54
768 #define hp_synctarg_13 0x55
769 #define hp_synctarg_14 0x56
770 #define hp_synctarg_15 0x57
772 #define hp_synctarg_8 0x58
773 #define hp_synctarg_9 0x59
774 #define hp_synctarg_10 0x5A
775 #define hp_synctarg_11 0x5B
777 #define hp_synctarg_4 0x5C
778 #define hp_synctarg_5 0x5D
779 #define hp_synctarg_6 0x5E
780 #define hp_synctarg_7 0x5F
782 #define hp_synctarg_0 0x60
783 #define hp_synctarg_1 0x61
784 #define hp_synctarg_2 0x62
785 #define hp_synctarg_3 0x63
787 #define NARROW_SCSI BIT(4)
788 #define DEFAULT_OFFSET 0x0F
790 #define hp_autostart_0 0x64
791 #define hp_autostart_1 0x65
792 #define hp_autostart_3 0x67
796 #define AUTO_IMMED BIT(5)
797 #define SELECT BIT(6)
798 #define END_DATA (BIT(7)+BIT(6))
800 #define hp_gp_reg_0 0x68
801 #define hp_gp_reg_1 0x69
802 #define hp_gp_reg_3 0x6B
804 #define hp_seltimeout 0x6C
807 #define TO_4ms 0x67 /* 3.9959ms */
809 #define TO_5ms 0x03 /* 4.9152ms */
810 #define TO_10ms 0x07 /* 11.xxxms */
811 #define TO_250ms 0x99 /* 250.68ms */
812 #define TO_290ms 0xB1 /* 289.99ms */
814 #define hp_clkctrl_0 0x6D
816 #define PWR_DWN BIT(6)
817 #define ACTdeassert BIT(4)
818 #define CLK_40MHZ (BIT(1) + BIT(0))
820 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
822 #define hp_fiforead 0x6E
823 #define hp_fifowrite 0x6F
825 #define hp_offsetctr 0x70
826 #define hp_xferstat 0x71
828 #define FIFO_EMPTY BIT(6)
830 #define hp_portctrl_1 0x72
832 #define CHK_SCSI_P BIT(3)
833 #define HOST_MODE8 BIT(0)
835 #define hp_xfer_pad 0x73
837 #define ID_UNLOCK BIT(3)
839 #define hp_scsidata_0 0x74
840 #define hp_scsidata_1 0x75
844 #define hp_aramBase 0x80
845 #define BIOS_DATA_OFFSET 0x60
846 #define BIOS_RELATIVE_CARD 0x64
851 #define AR3 (BITW(9) + BITW(8))
852 #define SDATA BITW(10)
855 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
857 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
861 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
863 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
866 #define ADATA_OUT 0x00
867 #define ADATA_IN BITW(8)
868 #define ACOMMAND BITW(10)
869 #define ASTATUS (BITW(10)+BITW(8))
870 #define AMSG_OUT (BITW(10)+BITW(9))
871 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
874 #define BRH_OP BITW(13) /* Branch */
878 #define EQUAL BITW(8)
879 #define NOT_EQ BITW(9)
881 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
884 #define FIFO_0 BITW(10)
887 #define MPM_OP BITW(15) /* Match phase and move data */
890 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
893 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
898 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
908 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
910 #define SSI_OP (BITW(15)+BITW(11))
913 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
914 #define SSI_IDO_STRT (IDO_STRT >> 8)
916 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
917 #define SSI_ITICKLE (ITICKLE >> 8)
919 #define SSI_IUNKWN (IUNKWN >> 8)
920 #define SSI_INO_CC (IUNKWN >> 8)
921 #define SSI_IRFAIL (IUNKWN >> 8)
924 #define NP 0x10 /*Next Phase */
925 #define NTCMD 0x02 /*Non- Tagged Command start */
926 #define CMDPZ 0x04 /*Command phase */
927 #define DINT 0x12 /*Data Out/In interrupt */
928 #define DI 0x13 /*Data Out */
929 #define DC 0x19 /*Disconnect Message */
930 #define ST 0x1D /*Status Phase */
931 #define UNKNWN 0x24 /*Unknown bus action */
932 #define CC 0x25 /*Command Completion failure */
933 #define TICK 0x26 /*New target reselected us. */
934 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
937 #define ID_MSG_STRT hp_aramBase + 0x00
938 #define NON_TAG_ID_MSG hp_aramBase + 0x06
939 #define CMD_STRT hp_aramBase + 0x08
940 #define SYNC_MSGS hp_aramBase + 0x08
946 #define TAG_STRT 0x00
947 #define DISCONNECT_START 0x10/2
948 #define END_DATA_START 0x14/2
949 #define CMD_ONLY_STRT CMDPZ/2
950 #define SELCHK_STRT SELCHK/2
960 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
961 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
963 xfercnt |= RDW_HARPOON((USHORT)(port+hp_xfercnt_0)))
965 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (USHORT)(addr & 0x0000FFFFL)),\
967 WRW_HARPOON((port+hp_host_addr_hmi), (USHORT)(addr & 0x0000FFFFL)),\
968 WR_HARP32(port,hp_xfercnt_0,count),\
969 WRW_HARPOON((port+hp_xfer_cnt_lo), (USHORT)(count & 0x0000FFFFL)),\
971 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
973 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
974 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
977 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
978 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
982 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
983 WR_HARPOON(port+hp_scsireset, 0x00))
985 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
986 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
988 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
989 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
991 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
992 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
994 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
995 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
1000 static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag);
1001 static void FPT_ssel(ULONG port, UCHAR p_card);
1002 static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard);
1003 static void FPT_shandem(ULONG port, UCHAR p_card,PSCCB pCurrSCCB);
1004 static void FPT_stsyncn(ULONG port, UCHAR p_card);
1005 static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset);
1006 static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
1007 PSCCBMgr_tar_info currTar_Info);
1008 static void FPT_sresb(ULONG port, UCHAR p_card);
1009 static void FPT_sxfrp(ULONG p_port, UCHAR p_card);
1010 static void FPT_schkdd(ULONG port, UCHAR p_card);
1011 static UCHAR FPT_RdStack(ULONG port, UCHAR index);
1012 static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data);
1013 static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort);
1015 static void FPT_SendMsg(ULONG port, UCHAR message);
1016 static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
1019 static void FPT_sinits(PSCCB p_sccb, UCHAR p_card);
1020 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
1022 static UCHAR FPT_siwidn(ULONG port, UCHAR p_card);
1023 static void FPT_stwidn(ULONG port, UCHAR p_card);
1024 static void FPT_siwidr(ULONG port, UCHAR width);
1027 static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card);
1028 static void FPT_queueDisconnect(PSCCB p_SCCB, UCHAR p_card);
1029 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1031 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card);
1032 static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code);
1033 static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR card);
1034 static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card);
1035 static void FPT_utilUpdateResidual(PSCCB p_SCCB);
1036 static USHORT FPT_CalcCrc16(UCHAR buffer[]);
1037 static UCHAR FPT_CalcLrc(UCHAR buffer[]);
1040 static void FPT_Wait1Second(ULONG p_port);
1041 static void FPT_Wait(ULONG p_port, UCHAR p_delay);
1042 static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode);
1043 static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr);
1044 static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr);
1045 static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr);
1046 static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr);
1050 static void FPT_phaseDataOut(ULONG port, UCHAR p_card);
1051 static void FPT_phaseDataIn(ULONG port, UCHAR p_card);
1052 static void FPT_phaseCommand(ULONG port, UCHAR p_card);
1053 static void FPT_phaseStatus(ULONG port, UCHAR p_card);
1054 static void FPT_phaseMsgOut(ULONG port, UCHAR p_card);
1055 static void FPT_phaseMsgIn(ULONG port, UCHAR p_card);
1056 static void FPT_phaseIllegal(ULONG port, UCHAR p_card);
1058 static void FPT_phaseDecode(ULONG port, UCHAR p_card);
1059 static void FPT_phaseChkFifo(ULONG port, UCHAR p_card);
1060 static void FPT_phaseBusFree(ULONG p_port, UCHAR p_card);
1065 static void FPT_XbowInit(ULONG port, UCHAR scamFlg);
1066 static void FPT_BusMasterInit(ULONG p_port);
1067 static void FPT_DiagEEPROM(ULONG p_port);
1072 static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard);
1073 static void FPT_busMstrSGDataXferStart(ULONG port, PSCCB pCurrSCCB);
1074 static void FPT_busMstrDataXferStart(ULONG port, PSCCB pCurrSCCB);
1075 static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB);
1076 static void FPT_hostDataXferRestart(PSCCB currSCCB);
1079 static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
1080 PSCCBcard pCurrCard, USHORT p_int);
1082 static void FPT_SccbMgrTableInitAll(void);
1083 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card);
1084 static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target);
1088 static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up);
1090 static int FPT_scarb(ULONG p_port, UCHAR p_sel_type);
1091 static void FPT_scbusf(ULONG p_port);
1092 static void FPT_scsel(ULONG p_port);
1093 static void FPT_scasid(UCHAR p_card, ULONG p_port);
1094 static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data);
1095 static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[]);
1096 static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[]);
1097 static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit);
1098 static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit);
1099 static UCHAR FPT_scvalq(UCHAR p_quintet);
1100 static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id);
1101 static void FPT_scwtsel(ULONG p_port);
1102 static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id);
1103 static void FPT_scsavdi(UCHAR p_card, ULONG p_port);
1104 static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[]);
1107 static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card);
1108 static void FPT_autoLoadDefaultMap(ULONG p_port);
1113 static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1114 static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1115 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1116 static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1119 static UCHAR FPT_mbCards = 0;
1120 static UCHAR FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1121 ' ', 'B', 'T', '-', '9', '3', '0', \
1122 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1123 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1125 static USHORT FPT_default_intena = 0;
1128 static void (*FPT_s_PhaseTbl[8]) (ULONG, UCHAR)= { 0 };
1131 /*---------------------------------------------------------------------
1133 * Function: SccbMgr_sense_adapter
1135 * Description: Setup and/or Search for cards and return info to caller.
1137 *---------------------------------------------------------------------*/
1139 static int SccbMgr_sense_adapter(PSCCBMGR_INFO pCardInfo)
1141 static UCHAR first_time = 1;
1143 UCHAR i,j,id,ScamFlg;
1144 USHORT temp,temp2,temp3,temp4,temp5,temp6;
1146 PNVRamInfo pCurrNvRam;
1148 ioport = pCardInfo->si_baseaddr;
1151 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1152 return((int)FAILURE);
1154 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1155 return((int)FAILURE);
1157 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1158 return((int)FAILURE);
1160 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1161 return((int)FAILURE);
1164 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1166 /* For new Harpoon then check for sub_device ID LSB
1167 the bits(0-3) must be all ZERO for compatible with
1168 current version of SCCBMgr, else skip this Harpoon
1171 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1172 return((int)FAILURE);
1177 FPT_SccbMgrTableInitAll();
1182 if(FPT_RdStack(ioport, 0) != 0x00) {
1183 if(FPT_ChkIfChipInitialized(ioport) == 0)
1186 WR_HARPOON(ioport+hp_semaphore, 0x00);
1187 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1188 FPT_DiagEEPROM(ioport);
1192 if(FPT_mbCards < MAX_MB_CARDS) {
1193 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1195 pCurrNvRam->niBaseAddr = ioport;
1196 FPT_RNVRamData(pCurrNvRam);
1198 return((int) FAILURE);
1203 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1204 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1207 pCardInfo->si_id = pCurrNvRam->niAdapId;
1209 pCardInfo->si_id = (UCHAR)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1212 pCardInfo->si_lun = 0x00;
1213 pCardInfo->si_fw_revision = ORION_FW_REV;
1220 for (id = 0; id < (16/2); id++) {
1223 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1224 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1225 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1227 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
1229 for (i = 0; i < 2; temp >>=8,i++) {
1238 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1239 temp6 |= 0x8000; /* Fall through */
1240 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1241 temp5 |= 0x8000; /* Fall through */
1242 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1243 temp2 |= 0x8000; /* Fall through */
1244 case AUTO_RATE_00: /* Asynchronous */
1248 if (temp & DISC_ENABLE_BIT)
1251 if (temp & WIDE_NEGO_BIT)
1257 pCardInfo->si_per_targ_init_sync = temp2;
1258 pCardInfo->si_per_targ_no_disc = temp3;
1259 pCardInfo->si_per_targ_wide_nego = temp4;
1260 pCardInfo->si_per_targ_fast_nego = temp5;
1261 pCardInfo->si_per_targ_ultra_nego = temp6;
1264 i = pCurrNvRam->niSysConf;
1266 i = (UCHAR)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1269 ScamFlg = pCurrNvRam->niScamConf;
1271 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1273 pCardInfo->si_flags = 0x0000;
1276 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1279 pCardInfo->si_flags |= SOFT_RESET;
1282 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1284 if (ScamFlg & SCAM_ENABLED)
1285 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1287 if (ScamFlg & SCAM_LEVEL2)
1288 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1290 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1292 j |= SCSI_TERM_ENA_L;
1294 WR_HARPOON(ioport+hp_bm_ctrl, j );
1296 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1298 j |= SCSI_TERM_ENA_H;
1300 WR_HARPOON(ioport+hp_ee_ctrl, j );
1302 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1304 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1306 pCardInfo->si_card_family = HARPOON_FAMILY;
1307 pCardInfo->si_bustype = BUSTYPE_PCI;
1310 pCardInfo->si_card_model[0] = '9';
1311 switch(pCurrNvRam->niModel & 0x0f){
1313 pCardInfo->si_card_model[1] = '3';
1314 pCardInfo->si_card_model[2] = '0';
1317 pCardInfo->si_card_model[1] = '5';
1318 pCardInfo->si_card_model[2] = '0';
1321 pCardInfo->si_card_model[1] = '3';
1322 pCardInfo->si_card_model[2] = '2';
1325 pCardInfo->si_card_model[1] = '5';
1326 pCardInfo->si_card_model[2] = '2';
1330 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1331 pCardInfo->si_card_model[0] = (UCHAR)(temp >> 8);
1332 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1334 pCardInfo->si_card_model[1] = (UCHAR)(temp & 0x00FF);
1335 pCardInfo->si_card_model[2] = (UCHAR)(temp >> 8);
1338 if (pCardInfo->si_card_model[1] == '3')
1340 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1341 pCardInfo->si_flags |= LOW_BYTE_TERM;
1343 else if (pCardInfo->si_card_model[2] == '0')
1345 temp = RD_HARPOON(ioport+hp_xfer_pad);
1346 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1347 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1348 pCardInfo->si_flags |= LOW_BYTE_TERM;
1349 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1350 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1351 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1352 WR_HARPOON(ioport+hp_xfer_pad, temp);
1356 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1357 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1358 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1359 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1361 for (i = 0; i < 8; i++)
1364 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1366 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1367 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1369 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1370 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1371 if (!(temp3 & BIT(7)))
1372 pCardInfo->si_flags |= LOW_BYTE_TERM;
1373 if (!(temp3 & BIT(6)))
1374 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1378 ARAM_ACCESS(ioport);
1380 for ( i = 0; i < 4; i++ ) {
1382 pCardInfo->si_XlatInfo[i] =
1383 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1386 /* return with -1 if no sort, else return with
1387 logical card number sorted by BIOS (zero-based) */
1389 pCardInfo->si_relative_cardnum =
1390 (UCHAR)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1392 SGRAM_ACCESS(ioport);
1394 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1395 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1396 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1397 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1398 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1399 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1400 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1401 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1403 pCardInfo->si_present = 0x01;
1409 /*---------------------------------------------------------------------
1411 * Function: SccbMgr_config_adapter
1413 * Description: Setup adapter for normal operation (hard reset).
1415 *---------------------------------------------------------------------*/
1417 static ULONG SccbMgr_config_adapter(PSCCBMGR_INFO pCardInfo)
1419 PSCCBcard CurrCard = NULL;
1420 PNVRamInfo pCurrNvRam;
1421 UCHAR i,j,thisCard, ScamFlg;
1422 USHORT temp,sync_bit_map,id;
1425 ioport = pCardInfo->si_baseaddr;
1427 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1429 if (thisCard == MAX_CARDS) {
1434 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1436 CurrCard = &FPT_BL_Card[thisCard];
1437 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1441 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1443 FPT_BL_Card[thisCard].ioPort = ioport;
1444 CurrCard = &FPT_BL_Card[thisCard];
1447 for(i = 0; i < FPT_mbCards; i++){
1448 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1449 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1451 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1452 CurrCard->cardIndex = thisCard;
1453 CurrCard->cardInfo = pCardInfo;
1459 pCurrNvRam = CurrCard->pNvRamInfo;
1462 ScamFlg = pCurrNvRam->niScamConf;
1465 ScamFlg = (UCHAR) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1469 FPT_BusMasterInit(ioport);
1470 FPT_XbowInit(ioport, ScamFlg);
1472 FPT_autoLoadDefaultMap(ioport);
1475 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1477 WR_HARPOON(ioport+hp_selfid_0, id);
1478 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1479 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1480 CurrCard->ourId = pCardInfo->si_id;
1482 i = (UCHAR) pCardInfo->si_flags;
1483 if (i & SCSI_PARITY_ENA)
1484 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1486 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1487 if (i & LOW_BYTE_TERM)
1488 j |= SCSI_TERM_ENA_L;
1489 WR_HARPOON(ioport+hp_bm_ctrl, j);
1491 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1492 if (i & HIGH_BYTE_TERM)
1493 j |= SCSI_TERM_ENA_H;
1494 WR_HARPOON(ioport+hp_ee_ctrl, j );
1497 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1499 FPT_sresb(ioport,thisCard);
1501 FPT_scini(thisCard, pCardInfo->si_id, 0);
1506 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1507 CurrCard->globalFlags |= F_NO_FILTER;
1510 if(pCurrNvRam->niSysConf & 0x10)
1511 CurrCard->globalFlags |= F_GREEN_PC;
1514 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1515 CurrCard->globalFlags |= F_GREEN_PC;
1518 /* Set global flag to indicate Re-Negotiation to be done on all
1521 if(pCurrNvRam->niScsiConf & 0x04)
1522 CurrCard->globalFlags |= F_DO_RENEGO;
1525 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1526 CurrCard->globalFlags |= F_DO_RENEGO;
1530 if(pCurrNvRam->niScsiConf & 0x08)
1531 CurrCard->globalFlags |= F_CONLUN_IO;
1534 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1535 CurrCard->globalFlags |= F_CONLUN_IO;
1539 temp = pCardInfo->si_per_targ_no_disc;
1541 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1544 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1547 sync_bit_map = 0x0001;
1549 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1552 temp = (USHORT) pCurrNvRam->niSyncTbl[id];
1553 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1554 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1556 temp = FPT_utilEERead(ioport, (USHORT)((SYNC_RATE_TBL/2)+id));
1558 for (i = 0; i < 2; temp >>=8,i++) {
1560 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1562 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (UCHAR)temp;
1566 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1567 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1568 (UCHAR)(temp & ~EE_SYNC_MASK);
1571 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1574 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1576 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1580 else { /* NARROW SCSI */
1581 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1592 WR_HARPOON((ioport+hp_semaphore),
1593 (UCHAR)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1595 return((ULONG)CurrCard);
1598 static void SccbMgr_unload_card(ULONG pCurrCard)
1605 PNVRamInfo pCurrNvRam;
1607 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1610 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1611 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1612 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1613 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1614 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1616 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1617 FPT_WrStack(pCurrNvRam->niBaseAddr, (UCHAR)(i+5), pCurrNvRam->niSyncTbl[i]);
1619 portBase = pCurrNvRam->niBaseAddr;
1621 for(i = 0; i < MAX_SCSI_TAR; i++){
1622 regOffset = hp_aramBase + 64 + i*4;
1623 pScamTbl = (ULONG *) &pCurrNvRam->niScamTbl[i];
1624 scamData = *pScamTbl;
1625 WR_HARP32(portBase, regOffset, scamData);
1629 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1634 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1642 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1643 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1644 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1645 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1646 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1648 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1649 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (UCHAR)(i+5));
1651 portBase = pNvRamInfo->niBaseAddr;
1653 for(i = 0; i < MAX_SCSI_TAR; i++){
1654 regOffset = hp_aramBase + 64 + i*4;
1655 RD_HARP32(portBase, regOffset, scamData);
1656 pScamTbl = (ULONG *) &pNvRamInfo->niScamTbl[i];
1657 *pScamTbl = scamData;
1662 static UCHAR FPT_RdStack(ULONG portBase, UCHAR index)
1664 WR_HARPOON(portBase + hp_stack_addr, index);
1665 return(RD_HARPOON(portBase + hp_stack_data));
1668 static void FPT_WrStack(ULONG portBase, UCHAR index, UCHAR data)
1670 WR_HARPOON(portBase + hp_stack_addr, index);
1671 WR_HARPOON(portBase + hp_stack_data, data);
1675 static UCHAR FPT_ChkIfChipInitialized(ULONG ioPort)
1677 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1679 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1682 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1683 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1688 /*---------------------------------------------------------------------
1690 * Function: SccbMgr_start_sccb
1692 * Description: Start a command pointed to by p_Sccb. When the
1693 * command is completed it will be returned via the
1694 * callback function.
1696 *---------------------------------------------------------------------*/
1697 static void SccbMgr_start_sccb(ULONG pCurrCard, PSCCB p_Sccb)
1700 UCHAR thisCard, lun;
1702 CALL_BK_FN callback;
1704 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1705 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1707 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1710 p_Sccb->HostStatus = SCCB_COMPLETE;
1711 p_Sccb->SccbStatus = SCCB_ERROR;
1712 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1719 FPT_sinits(p_Sccb,thisCard);
1722 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1724 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1725 | SCCB_MGR_ACTIVE));
1727 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1729 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1730 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1734 ((PSCCBcard)pCurrCard)->cmdCounter++;
1736 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1738 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1740 if(p_Sccb->OperationCode == RESET_COMMAND)
1742 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1743 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1744 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1745 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1749 FPT_queueAddSccb(p_Sccb,thisCard);
1753 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1755 if(p_Sccb->OperationCode == RESET_COMMAND)
1757 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1758 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1759 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1760 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1764 FPT_queueAddSccb(p_Sccb,thisCard);
1770 MDISABLE_INT(ioport);
1772 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
1773 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1777 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
1778 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1779 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1782 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1783 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1788 if(p_Sccb->OperationCode == RESET_COMMAND)
1790 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1791 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1792 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1793 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1797 FPT_queueAddSccb(p_Sccb,thisCard);
1802 MENABLE_INT(ioport);
1808 /*---------------------------------------------------------------------
1810 * Function: SccbMgr_abort_sccb
1812 * Description: Abort the command pointed to by p_Sccb. When the
1813 * command is completed it will be returned via the
1814 * callback function.
1816 *---------------------------------------------------------------------*/
1817 static int SccbMgr_abort_sccb(ULONG pCurrCard, PSCCB p_Sccb)
1822 CALL_BK_FN callback;
1825 PSCCBMgr_tar_info currTar_Info;
1828 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1830 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1832 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1835 if (FPT_queueFindSccb(p_Sccb,thisCard))
1838 ((PSCCBcard)pCurrCard)->cmdCounter--;
1840 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1841 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1842 & (UCHAR)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1844 p_Sccb->SccbStatus = SCCB_ABORT;
1845 callback = p_Sccb->SccbCallback;
1853 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1855 p_Sccb->SccbStatus = SCCB_ABORT;
1863 TID = p_Sccb->TargID;
1866 if(p_Sccb->Sccb_tag)
1868 MDISABLE_INT(ioport);
1869 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1871 p_Sccb->SccbStatus = SCCB_ABORT;
1872 p_Sccb->Sccb_scsistat = ABORT_ST;
1873 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1875 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1877 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1878 FPT_ssel(ioport, thisCard);
1882 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1883 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1884 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1885 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1888 MENABLE_INT(ioport);
1893 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1895 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1898 p_Sccb->SccbStatus = SCCB_ABORT;
1909 /*---------------------------------------------------------------------
1911 * Function: SccbMgr_my_int
1913 * Description: Do a quick check to determine if there is a pending
1914 * interrupt for this card and disable the IRQ Pin if so.
1916 *---------------------------------------------------------------------*/
1917 static UCHAR SccbMgr_my_int(ULONG pCurrCard)
1921 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1923 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1935 /*---------------------------------------------------------------------
1937 * Function: SccbMgr_isr
1939 * Description: This is our entry point when an interrupt is generated
1940 * by the card and the upper level driver passes it on to
1943 *---------------------------------------------------------------------*/
1944 static int SccbMgr_isr(ULONG pCurrCard)
1947 UCHAR thisCard,result,bm_status, bm_int_st;
1952 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1953 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1955 MDISABLE_INT(ioport);
1957 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1958 bm_status = RD_HARPOON(ioport+hp_ext_status) & (UCHAR)BAD_EXT_STATUS;
1962 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1964 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1968 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1970 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1971 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1972 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1977 MENABLE_INT(ioport);
1983 else if (hp_int & ICMD_COMP) {
1985 if ( !(hp_int & BUS_FREE) ) {
1986 /* Wait for the BusFree before starting a new command. We
1987 must also check for being reselected since the BusFree
1988 may not show up if another device reselects us in 1.5us or
1989 less. SRR Wednesday, 3/8/1995.
1991 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1994 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1996 FPT_phaseChkFifo(ioport, thisCard);
1998 /* WRW_HARPOON((ioport+hp_intstat),
1999 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
2002 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
2004 FPT_autoCmdCmplt(ioport,thisCard);
2009 else if (hp_int & ITAR_DISC)
2012 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2014 FPT_phaseChkFifo(ioport, thisCard);
2018 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
2020 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2021 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2023 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2026 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2027 FPT_queueDisconnect(currSCCB,thisCard);
2029 /* Wait for the BusFree before starting a new command. We
2030 must also check for being reselected since the BusFree
2031 may not show up if another device reselects us in 1.5us or
2032 less. SRR Wednesday, 3/8/1995.
2034 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2035 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2036 RD_HARPOON((ioport+hp_scsisig)) ==
2037 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2040 The additional loop exit condition above detects a timing problem
2041 with the revision D/E harpoon chips. The caller should reset the
2042 host adapter to recover when 0xFE is returned.
2044 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2046 MENABLE_INT(ioport);
2050 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2053 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2058 else if (hp_int & RSEL) {
2060 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2062 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2064 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2066 FPT_phaseChkFifo(ioport, thisCard);
2069 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2071 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2072 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2073 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2076 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2077 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2078 FPT_queueDisconnect(currSCCB,thisCard);
2081 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2082 FPT_phaseDecode(ioport,thisCard);
2087 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2090 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2091 FPT_phaseDecode(ioport,thisCard);
2096 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2098 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2099 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (UCHAR)0x3f)< (UCHAR)SELCHK)
2101 FPT_phaseDecode(ioport,thisCard);
2105 /* Harpoon problem some SCSI target device respond to selection
2106 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2107 to latch the correct Target ID into reg. x53.
2108 The work around require to correct this reg. But when write to this
2109 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2110 need to read this reg first then restore it later. After update to 0x53 */
2112 i = (UCHAR)(RD_HARPOON(ioport+hp_fifowrite));
2113 target = (UCHAR)(RD_HARPOON(ioport+hp_gp_reg_3));
2114 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) ID_UNLOCK);
2115 WR_HARPOON(ioport+hp_select_id, (UCHAR)(target | target<<4));
2116 WR_HARPOON(ioport+hp_xfer_pad, (UCHAR) 0x00);
2117 WR_HARPOON(ioport+hp_fifowrite, i);
2118 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2122 else if (hp_int & XFER_CNT_0) {
2124 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2126 FPT_schkdd(ioport,thisCard);
2131 else if (hp_int & BUS_FREE) {
2133 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2135 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2137 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
2140 FPT_phaseBusFree(ioport,thisCard);
2144 else if (hp_int & ITICKLE) {
2146 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2147 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2152 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2155 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2158 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2160 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
2163 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2164 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2165 FPT_ssel(ioport,thisCard);
2174 MENABLE_INT(ioport);
2179 /*---------------------------------------------------------------------
2181 * Function: Sccb_bad_isr
2183 * Description: Some type of interrupt has occurred which is slightly
2184 * out of the ordinary. We will now decode it fully, in
2185 * this routine. This is broken up in an attempt to save
2188 *---------------------------------------------------------------------*/
2189 static UCHAR FPT_SccbMgr_bad_isr(ULONG p_port, UCHAR p_card,
2190 PSCCBcard pCurrCard, USHORT p_int)
2192 UCHAR temp, ScamFlg;
2193 PSCCBMgr_tar_info currTar_Info;
2194 PNVRamInfo pCurrNvRam;
2197 if (RD_HARPOON(p_port+hp_ext_status) &
2198 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2201 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2204 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2207 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2210 WR_HARPOON(p_port+hp_pci_stat_cfg,
2211 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2213 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2217 if (pCurrCard->currentSCCB != NULL)
2220 if (!pCurrCard->currentSCCB->HostStatus)
2221 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2223 FPT_sxfrp(p_port,p_card);
2225 temp = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) &
2226 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2227 WR_HARPOON(p_port+hp_ee_ctrl, ((UCHAR)temp | SEE_MS | SEE_CS));
2228 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2230 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2232 FPT_phaseDecode(p_port,p_card);
2238 else if (p_int & RESET)
2241 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2242 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2243 if (pCurrCard->currentSCCB != NULL) {
2245 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2247 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2251 DISABLE_AUTO(p_port);
2253 FPT_sresb(p_port,p_card);
2255 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2257 pCurrNvRam = pCurrCard->pNvRamInfo;
2259 ScamFlg = pCurrNvRam->niScamConf;
2262 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
2265 FPT_XbowInit(p_port, ScamFlg);
2267 FPT_scini(p_card, pCurrCard->ourId, 0);
2273 else if (p_int & FIFO) {
2275 WRW_HARPOON((p_port+hp_intstat), FIFO);
2277 if (pCurrCard->currentSCCB != NULL)
2278 FPT_sxfrp(p_port,p_card);
2281 else if (p_int & TIMEOUT)
2284 DISABLE_AUTO(p_port);
2286 WRW_HARPOON((p_port+hp_intstat),
2287 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2289 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2292 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2293 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2294 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2295 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
2297 currTar_Info->TarLUNBusy[0] = 0;
2300 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2302 currTar_Info->TarSyncCtrl = 0;
2303 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2306 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2308 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2311 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
2313 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2317 else if (p_int & SCAM_SEL)
2320 FPT_scarb(p_port,LEVEL2_TAR);
2322 FPT_scasid(p_card, p_port);
2326 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2333 /*---------------------------------------------------------------------
2335 * Function: SccbMgrTableInit
2337 * Description: Initialize all Sccb manager data structures.
2339 *---------------------------------------------------------------------*/
2341 static void FPT_SccbMgrTableInitAll()
2345 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2347 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
2349 FPT_BL_Card[thisCard].ioPort = 0x00;
2350 FPT_BL_Card[thisCard].cardInfo = NULL;
2351 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2352 FPT_BL_Card[thisCard].ourId = 0x00;
2353 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2358 /*---------------------------------------------------------------------
2360 * Function: SccbMgrTableInit
2362 * Description: Initialize all Sccb manager data structures.
2364 *---------------------------------------------------------------------*/
2366 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, UCHAR p_card)
2370 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2372 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2375 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2377 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2378 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2379 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2382 pCurrCard->scanIndex = 0x00;
2383 pCurrCard->currentSCCB = NULL;
2384 pCurrCard->globalFlags = 0x00;
2385 pCurrCard->cmdCounter = 0x00;
2386 pCurrCard->tagQ_Lst = 0x01;
2387 pCurrCard->discQCount = 0;
2393 /*---------------------------------------------------------------------
2395 * Function: SccbMgrTableInit
2397 * Description: Initialize all Sccb manager data structures.
2399 *---------------------------------------------------------------------*/
2401 static void FPT_SccbMgrTableInitTarget(UCHAR p_card, UCHAR target)
2405 PSCCBMgr_tar_info currTar_Info;
2407 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2409 currTar_Info->TarSelQ_Cnt = 0;
2410 currTar_Info->TarSyncCtrl = 0;
2412 currTar_Info->TarSelQ_Head = NULL;
2413 currTar_Info->TarSelQ_Tail = NULL;
2414 currTar_Info->TarTagQ_Cnt = 0;
2415 currTar_Info->TarLUN_CA = 0;
2418 for (lun = 0; lun < MAX_LUN; lun++)
2420 currTar_Info->TarLUNBusy[lun] = 0;
2421 currTar_Info->LunDiscQ_Idx[lun] = 0;
2424 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2426 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
2428 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
2430 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2431 FPT_BL_Card[p_card].discQCount--;
2438 /*---------------------------------------------------------------------
2442 * Description: Read in a message byte from the SCSI bus, and check
2443 * for a parity error.
2445 *---------------------------------------------------------------------*/
2447 static UCHAR FPT_sfm(ULONG port, PSCCB pCurrSCCB)
2453 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2454 (TimeOutLoop++ < 20000) ){}
2457 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2459 message = RD_HARPOON(port+hp_scsidata_0);
2461 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2464 if (TimeOutLoop > 20000)
2465 message = 0x00; /* force message byte = 0 if Time Out on Req */
2467 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2468 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2470 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2471 WR_HARPOON(port+hp_xferstat, 0);
2472 WR_HARPOON(port+hp_fiforead, 0);
2473 WR_HARPOON(port+hp_fifowrite, 0);
2474 if (pCurrSCCB != NULL)
2476 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2481 ACCEPT_MSG_ATN(port);
2483 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2484 (TimeOutLoop++ < 20000) ){}
2485 if (TimeOutLoop > 20000)
2487 WRW_HARPOON((port+hp_intstat), PARITY);
2490 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2492 WRW_HARPOON((port+hp_intstat), PARITY);
2495 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2497 RD_HARPOON(port+hp_scsidata_0);
2499 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2504 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2505 WR_HARPOON(port+hp_xferstat, 0);
2506 WR_HARPOON(port+hp_fiforead, 0);
2507 WR_HARPOON(port+hp_fifowrite, 0);
2512 /*---------------------------------------------------------------------
2514 * Function: FPT_ssel
2516 * Description: Load up automation and select target device.
2518 *---------------------------------------------------------------------*/
2520 static void FPT_ssel(ULONG port, UCHAR p_card)
2523 UCHAR auto_loaded, i, target, *theCCB;
2528 PSCCBMgr_tar_info currTar_Info;
2531 CurrCard = &FPT_BL_Card[p_card];
2532 currSCCB = CurrCard->currentSCCB;
2533 target = currSCCB->TargID;
2534 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2535 lastTag = CurrCard->tagQ_Lst;
2540 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2541 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2543 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2544 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2546 lun = currSCCB->Lun;
2551 if (CurrCard->globalFlags & F_TAG_STARTED)
2553 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2555 if ((currTar_Info->TarLUN_CA == 0)
2556 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2560 if (currTar_Info->TarTagQ_Cnt !=0)
2562 currTar_Info->TarLUNBusy[lun] = 1;
2563 FPT_queueSelectFail(CurrCard,p_card);
2569 currTar_Info->TarLUNBusy[lun] = 1;
2572 } /*End non-tagged */
2575 currTar_Info->TarLUNBusy[lun] = 1;
2578 } /*!Use cmd Q Tagged */
2581 if (currTar_Info->TarLUN_CA == 1)
2583 FPT_queueSelectFail(CurrCard,p_card);
2588 currTar_Info->TarLUNBusy[lun] = 1;
2590 } /*else use cmd Q tagged */
2592 } /*if glob tagged started */
2595 currTar_Info->TarLUNBusy[lun] = 1;
2600 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2601 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2602 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2604 if(CurrCard->discQCount >= QUEUE_DEPTH)
2606 currTar_Info->TarLUNBusy[lun] = 1;
2607 FPT_queueSelectFail(CurrCard,p_card);
2611 for (i = 1; i < QUEUE_DEPTH; i++)
2613 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2614 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2616 CurrCard->tagQ_Lst = lastTag;
2617 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2618 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2619 CurrCard->discQCount++;
2623 if(i == QUEUE_DEPTH)
2625 currTar_Info->TarLUNBusy[lun] = 1;
2626 FPT_queueSelectFail(CurrCard,p_card);
2636 WR_HARPOON(port+hp_select_id, target);
2637 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2639 if (currSCCB->OperationCode == RESET_COMMAND) {
2640 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2641 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2643 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2645 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2647 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2649 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2651 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2653 currTar_Info->TarSyncCtrl = 0;
2654 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2657 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2659 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2662 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2663 FPT_SccbMgrTableInitTarget(p_card, target);
2667 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2669 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2670 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2672 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2674 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2675 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
2676 >> 6) | (UCHAR)0x20)));
2677 WRW_HARPOON((port+SYNC_MSGS+2),
2678 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2679 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2681 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2686 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2687 auto_loaded = FPT_siwidn(port,p_card);
2688 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2691 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2692 == SYNC_SUPPORTED)) {
2693 auto_loaded = FPT_sisyncn(port,p_card, 0);
2694 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2701 if (currSCCB->ControlByte & F_USE_CMD_Q)
2704 CurrCard->globalFlags |= F_TAG_STARTED;
2706 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2709 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2711 /* Fix up the start instruction with a jump to
2712 Non-Tag-CMD handling */
2713 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2715 WRW_HARPOON((port+NON_TAG_ID_MSG),
2716 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2718 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2720 /* Setup our STATE so we know what happend when
2721 the wheels fall off. */
2722 currSCCB->Sccb_scsistat = SELECT_ST;
2724 currTar_Info->TarLUNBusy[lun] = 1;
2729 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2731 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2732 (((UCHAR)(currSCCB->ControlByte & TAG_TYPE_MASK)
2733 >> 6) | (UCHAR)0x20)));
2735 for (i = 1; i < QUEUE_DEPTH; i++)
2737 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2738 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2740 WRW_HARPOON((port+ID_MSG_STRT+6),
2741 (MPM_OP+AMSG_OUT+lastTag));
2742 CurrCard->tagQ_Lst = lastTag;
2743 currSCCB->Sccb_tag = lastTag;
2744 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2745 CurrCard->discQCount++;
2751 if ( i == QUEUE_DEPTH )
2753 currTar_Info->TarLUNBusy[lun] = 1;
2754 FPT_queueSelectFail(CurrCard,p_card);
2759 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2761 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2768 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2770 WRW_HARPOON((port+NON_TAG_ID_MSG),
2771 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2773 currSCCB->Sccb_scsistat = SELECT_ST;
2775 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2779 theCCB = (UCHAR *)&currSCCB->Cdb[0];
2781 cdb_reg = port + CMD_STRT;
2783 for (i=0; i < currSCCB->CdbLength; i++)
2785 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2790 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2791 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2795 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
2796 WR_HARPOON(port+hp_xferstat, 0x00);
2798 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2800 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2803 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2805 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2810 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (UCHAR)0x1F);
2811 auto_loaded |= AUTO_IMMED; */
2812 auto_loaded = AUTO_IMMED;
2816 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2823 /*---------------------------------------------------------------------
2825 * Function: FPT_sres
2827 * Description: Hookup the correct CCB and handle the incoming messages.
2829 *---------------------------------------------------------------------*/
2831 static void FPT_sres(ULONG port, UCHAR p_card, PSCCBcard pCurrCard)
2834 UCHAR our_target, message, lun = 0, tag, msgRetryCount;
2837 PSCCBMgr_tar_info currTar_Info;
2843 if(pCurrCard->currentSCCB != NULL)
2845 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2849 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2852 currSCCB = pCurrCard->currentSCCB;
2853 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2855 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2856 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2858 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2860 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2861 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2863 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2864 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2866 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2867 if(currSCCB->Sccb_scsistat != ABORT_ST)
2869 pCurrCard->discQCount--;
2870 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2876 currTar_Info->TarLUNBusy[0] = 0;
2877 if(currSCCB->Sccb_tag)
2879 if(currSCCB->Sccb_scsistat != ABORT_ST)
2881 pCurrCard->discQCount--;
2882 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2886 if(currSCCB->Sccb_scsistat != ABORT_ST)
2888 pCurrCard->discQCount--;
2889 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2894 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
2897 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
2900 our_target = (UCHAR)(RD_HARPOON(port+hp_select_id) >> 4);
2901 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2908 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2912 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2914 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2917 WRW_HARPOON((port+hp_intstat), PHASE);
2922 WRW_HARPOON((port+hp_intstat), PHASE);
2923 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2926 message = FPT_sfm(port,pCurrCard->currentSCCB);
2930 if (message <= (0x80 | LUN_MASK))
2932 lun = message & (UCHAR)LUN_MASK;
2934 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2936 if (currTar_Info->TarTagQ_Cnt != 0)
2939 if (!(currTar_Info->TarLUN_CA))
2941 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2944 message = FPT_sfm(port,pCurrCard->currentSCCB);
2955 tag = FPT_sfm(port,pCurrCard->currentSCCB);
2963 } /*End Q cnt != 0 */
2965 } /*End Tag cmds supported! */
2967 } /*End valid ID message. */
2972 ACCEPT_MSG_ATN(port);
2975 } /* End good id message. */
2985 ACCEPT_MSG_ATN(port);
2987 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2988 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2989 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2997 if(msgRetryCount == 1)
2999 FPT_SendMsg(port, SMPARITY);
3003 FPT_SendMsg(port, SMDEV_RESET);
3005 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
3007 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
3010 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
3014 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
3017 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
3021 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3022 FPT_SccbMgrTableInitTarget(p_card,our_target);
3026 }while(message == 0);
3030 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3031 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3033 currTar_Info->TarLUNBusy[lun] = 1;
3034 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3035 if(pCurrCard->currentSCCB != NULL)
3041 ACCEPT_MSG_ATN(port);
3046 currTar_Info->TarLUNBusy[0] = 1;
3051 if (pCurrCard->discQ_Tbl[tag] != NULL)
3053 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3054 currTar_Info->TarTagQ_Cnt--;
3059 ACCEPT_MSG_ATN(port);
3063 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3064 if(pCurrCard->currentSCCB != NULL)
3070 ACCEPT_MSG_ATN(port);
3075 if(pCurrCard->currentSCCB != NULL)
3077 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3079 /* During Abort Tag command, the target could have got re-selected
3080 and completed the command. Check the select Q and remove the CCB
3081 if it is in the Select Q */
3082 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
3087 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3088 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3089 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3092 static void FPT_SendMsg(ULONG port, UCHAR message)
3094 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3096 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3099 WRW_HARPOON((port+hp_intstat), PHASE);
3104 WRW_HARPOON((port+hp_intstat), PHASE);
3105 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3107 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3110 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3112 WR_HARPOON(port+hp_scsidata_0,message);
3114 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3118 WR_HARPOON(port+hp_portctrl_0, 0x00);
3120 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3121 (message == SMABORT_TAG) )
3123 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3125 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3127 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3133 /*---------------------------------------------------------------------
3135 * Function: FPT_sdecm
3137 * Description: Determine the proper responce to the message from the
3140 *---------------------------------------------------------------------*/
3141 static void FPT_sdecm(UCHAR message, ULONG port, UCHAR p_card)
3145 PSCCBMgr_tar_info currTar_Info;
3147 CurrCard = &FPT_BL_Card[p_card];
3148 currSCCB = CurrCard->currentSCCB;
3150 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3152 if (message == SMREST_DATA_PTR)
3154 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3156 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3158 FPT_hostDataXferRestart(currSCCB);
3162 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3165 else if (message == SMCMD_COMP)
3169 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3171 currTar_Info->TarStatus &= ~(UCHAR)TAR_TAG_Q_MASK;
3172 currTar_Info->TarStatus |= (UCHAR)TAG_Q_REJECT;
3179 else if ((message == SMNO_OP) || (message >= SMIDENT)
3180 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3184 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3187 else if (message == SMREJECT)
3190 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3191 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3192 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3193 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3196 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3201 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3202 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3204 if(currSCCB->Lun == 0x00)
3206 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3209 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3211 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3214 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3218 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3219 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3221 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3225 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3227 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3228 ~(UCHAR)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3231 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3232 CurrCard->discQCount--;
3233 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3234 currSCCB->Sccb_tag = 0x00;
3239 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3243 if(currSCCB->Lun == 0x00)
3245 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3246 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3253 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3254 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3255 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
3257 currTar_Info->TarLUNBusy[0] = 1;
3260 currSCCB->ControlByte &= ~(UCHAR)F_USE_CMD_Q;
3262 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3271 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3272 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3274 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3276 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3281 else if (message == SMEXT)
3285 FPT_shandem(port,p_card,currSCCB);
3288 else if (message == SMIGNORWR)
3291 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3293 message = FPT_sfm(port,currSCCB);
3295 if(currSCCB->Sccb_scsimsg != SMPARITY)
3297 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3304 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3305 currSCCB->Sccb_scsimsg = SMREJECT;
3307 ACCEPT_MSG_ATN(port);
3308 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3313 /*---------------------------------------------------------------------
3315 * Function: FPT_shandem
3317 * Description: Decide what to do with the extended message.
3319 *---------------------------------------------------------------------*/
3320 static void FPT_shandem(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
3322 UCHAR length,message;
3324 length = FPT_sfm(port,pCurrSCCB);
3329 message = FPT_sfm(port,pCurrSCCB);
3333 if (message == SMSYNC)
3340 FPT_stsyncn(port,p_card);
3345 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3346 ACCEPT_MSG_ATN(port);
3349 else if (message == SMWDTR)
3356 FPT_stwidn(port,p_card);
3361 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3362 ACCEPT_MSG_ATN(port);
3364 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3370 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3371 ACCEPT_MSG_ATN(port);
3373 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3378 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3380 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3384 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3385 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3390 /*---------------------------------------------------------------------
3392 * Function: FPT_sisyncn
3394 * Description: Read in a message byte from the SCSI bus, and check
3395 * for a parity error.
3397 *---------------------------------------------------------------------*/
3399 static UCHAR FPT_sisyncn(ULONG port, UCHAR p_card, UCHAR syncFlag)
3402 PSCCBMgr_tar_info currTar_Info;
3404 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3405 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3407 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3410 WRW_HARPOON((port+ID_MSG_STRT),
3411 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
3413 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3415 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3416 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3417 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3420 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3422 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3424 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3426 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3428 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3430 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3433 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3436 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3437 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3438 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3443 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3444 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3445 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_TRYING);
3449 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3458 currTar_Info->TarStatus |= (UCHAR)SYNC_SUPPORTED;
3459 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3466 /*---------------------------------------------------------------------
3468 * Function: FPT_stsyncn
3470 * Description: The has sent us a Sync Nego message so handle it as
3473 *---------------------------------------------------------------------*/
3474 static void FPT_stsyncn(ULONG port, UCHAR p_card)
3476 UCHAR sync_msg,offset,sync_reg,our_sync_msg;
3478 PSCCBMgr_tar_info currTar_Info;
3480 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3481 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3483 sync_msg = FPT_sfm(port,currSCCB);
3485 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3487 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3494 offset = FPT_sfm(port,currSCCB);
3496 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3498 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3502 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3504 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3506 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3508 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3510 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3512 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3515 our_sync_msg = 0; /* Message = Async */
3517 if (sync_msg < our_sync_msg) {
3518 sync_msg = our_sync_msg; /*if faster, then set to max. */
3521 if (offset == ASYNC)
3524 if (offset > MAX_OFFSET)
3525 offset = MAX_OFFSET;
3531 sync_reg = 0x20; /* Use 10MB/s */
3535 sync_reg = 0x40; /* Use 6.6MB/s */
3539 sync_reg = 0x60; /* Use 5MB/s */
3543 sync_reg = 0x80; /* Use 4MB/s */
3547 sync_reg = 0xA0; /* Use 3.33MB/s */
3551 sync_reg = 0xC0; /* Use 2.85MB/s */
3555 sync_reg = 0xE0; /* Use 2.5MB/s */
3557 if (sync_msg > 100) {
3559 sync_reg = 0x00; /* Use ASYNC */
3564 if (currTar_Info->TarStatus & WIDE_ENABLED)
3570 sync_reg |= (offset | NARROW_SCSI);
3572 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
3575 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3580 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3581 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3583 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3589 ACCEPT_MSG_ATN(port);
3591 FPT_sisyncr(port,sync_msg,offset);
3593 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3594 ~(UCHAR)TAR_SYNC_MASK) | (UCHAR)SYNC_SUPPORTED);
3599 /*---------------------------------------------------------------------
3601 * Function: FPT_sisyncr
3603 * Description: Answer the targets sync message.
3605 *---------------------------------------------------------------------*/
3606 static void FPT_sisyncr(ULONG port,UCHAR sync_pulse, UCHAR offset)
3609 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3610 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3611 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3612 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3613 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3614 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3615 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3618 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3619 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3621 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3623 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3628 /*---------------------------------------------------------------------
3630 * Function: FPT_siwidn
3632 * Description: Read in a message byte from the SCSI bus, and check
3633 * for a parity error.
3635 *---------------------------------------------------------------------*/
3637 static UCHAR FPT_siwidn(ULONG port, UCHAR p_card)
3640 PSCCBMgr_tar_info currTar_Info;
3642 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3643 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3645 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3648 WRW_HARPOON((port+ID_MSG_STRT),
3649 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV)));
3651 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3653 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3654 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3655 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3656 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3657 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3658 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3660 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3663 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3664 ~(UCHAR)TAR_WIDE_MASK) | (UCHAR)WIDE_ENABLED);
3671 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3672 ~(UCHAR)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3674 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3681 /*---------------------------------------------------------------------
3683 * Function: FPT_stwidn
3685 * Description: The has sent us a Wide Nego message so handle it as
3688 *---------------------------------------------------------------------*/
3689 static void FPT_stwidn(ULONG port, UCHAR p_card)
3693 PSCCBMgr_tar_info currTar_Info;
3695 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3696 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3698 width = FPT_sfm(port,currSCCB);
3700 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3702 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3707 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3711 currTar_Info->TarStatus |= WIDE_ENABLED;
3715 width = NARROW_SCSI;
3716 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3720 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
3723 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3728 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3730 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3732 ACCEPT_MSG_ATN(port);
3734 FPT_sisyncn(port,p_card, 1);
3735 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3741 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3748 ACCEPT_MSG_ATN(port);
3750 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3755 FPT_siwidr(port,width);
3757 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3762 /*---------------------------------------------------------------------
3764 * Function: FPT_siwidr
3766 * Description: Answer the targets Wide nego message.
3768 *---------------------------------------------------------------------*/
3769 static void FPT_siwidr(ULONG port, UCHAR width)
3772 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3773 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3774 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3775 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3776 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3777 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3780 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3781 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3783 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3785 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3790 /*---------------------------------------------------------------------
3792 * Function: FPT_sssyncv
3794 * Description: Write the desired value to the Sync Register for the
3797 *---------------------------------------------------------------------*/
3798 static void FPT_sssyncv(ULONG p_port, UCHAR p_id, UCHAR p_sync_value,
3799 PSCCBMgr_tar_info currTar_Info)
3808 index = 12; /* hp_synctarg_0 */
3811 index = 13; /* hp_synctarg_1 */
3814 index = 14; /* hp_synctarg_2 */
3817 index = 15; /* hp_synctarg_3 */
3820 index = 8; /* hp_synctarg_4 */
3823 index = 9; /* hp_synctarg_5 */
3826 index = 10; /* hp_synctarg_6 */
3829 index = 11; /* hp_synctarg_7 */
3832 index = 4; /* hp_synctarg_8 */
3835 index = 5; /* hp_synctarg_9 */
3838 index = 6; /* hp_synctarg_10 */
3841 index = 7; /* hp_synctarg_11 */
3844 index = 0; /* hp_synctarg_12 */
3847 index = 1; /* hp_synctarg_13 */
3850 index = 2; /* hp_synctarg_14 */
3853 index = 3; /* hp_synctarg_15 */
3857 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3859 currTar_Info->TarSyncCtrl = p_sync_value;
3863 /*---------------------------------------------------------------------
3865 * Function: FPT_sresb
3867 * Description: Reset the desired card's SCSI bus.
3869 *---------------------------------------------------------------------*/
3870 static void FPT_sresb(ULONG port, UCHAR p_card)
3874 PSCCBMgr_tar_info currTar_Info;
3876 WR_HARPOON(port+hp_page_ctrl,
3877 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3878 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3880 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3882 scsiID = RD_HARPOON(port+hp_seltimeout);
3883 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3884 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3886 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3888 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3890 WR_HARPOON(port+hp_seltimeout,scsiID);
3892 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3894 FPT_Wait(port, TO_5ms);
3896 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3898 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3900 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3902 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3904 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3906 currTar_Info->TarSyncCtrl = 0;
3907 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3910 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3912 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3915 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
3917 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3920 FPT_BL_Card[p_card].scanIndex = 0x00;
3921 FPT_BL_Card[p_card].currentSCCB = NULL;
3922 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3924 FPT_BL_Card[p_card].cmdCounter = 0x00;
3925 FPT_BL_Card[p_card].discQCount = 0x00;
3926 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3928 for(i = 0; i < QUEUE_DEPTH; i++)
3929 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3931 WR_HARPOON(port+hp_page_ctrl,
3932 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3936 /*---------------------------------------------------------------------
3938 * Function: FPT_ssenss
3940 * Description: Setup for the Auto Sense command.
3942 *---------------------------------------------------------------------*/
3943 static void FPT_ssenss(PSCCBcard pCurrCard)
3948 currSCCB = pCurrCard->currentSCCB;
3951 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3953 for (i = 0; i < 6; i++) {
3955 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3958 currSCCB->CdbLength = SIX_BYTE_CMD;
3959 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3960 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (UCHAR)0xE0; /*Keep LUN. */
3961 currSCCB->Cdb[2] = 0x00;
3962 currSCCB->Cdb[3] = 0x00;
3963 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3964 currSCCB->Cdb[5] = 0x00;
3966 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3968 currSCCB->Sccb_ATC = 0x00;
3970 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3972 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3974 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(UCHAR)DISC_PRIV;
3976 currSCCB->ControlByte = 0x00;
3978 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3983 /*---------------------------------------------------------------------
3985 * Function: FPT_sxfrp
3987 * Description: Transfer data into the bit bucket until the device
3988 * decides to switch phase.
3990 *---------------------------------------------------------------------*/
3992 static void FPT_sxfrp(ULONG p_port, UCHAR p_card)
3997 DISABLE_AUTO(p_port);
3999 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
4001 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
4005 /* If the Automation handled the end of the transfer then do not
4006 match the phase or we will get out of sync with the ISR. */
4008 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
4011 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
4013 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ;
4015 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
4018 WR_HARPOON(p_port+hp_scsisig, curr_phz);
4020 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
4021 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (UCHAR)S_SCSI_PHZ)) )
4023 if (curr_phz & (UCHAR)SCSI_IOBIT)
4025 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4027 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4029 RD_HARPOON(p_port+hp_fifodata_0);
4034 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4035 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4037 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4040 } /* End of While loop for padding data I/O phase */
4042 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4044 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4048 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4049 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4051 RD_HARPOON(p_port+hp_fifodata_0);
4054 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4056 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4057 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4059 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4060 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4065 /*---------------------------------------------------------------------
4067 * Function: FPT_schkdd
4069 * Description: Make sure data has been flushed from both FIFOs and abort
4070 * the operations if necessary.
4072 *---------------------------------------------------------------------*/
4074 static void FPT_schkdd(ULONG port, UCHAR p_card)
4081 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4084 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4085 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4091 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4094 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4096 currSCCB->Sccb_XferCnt = 1;
4098 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4099 WRW_HARPOON((port+hp_fiforead), (USHORT) 0x00);
4100 WR_HARPOON(port+hp_xferstat, 0x00);
4106 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4108 currSCCB->Sccb_XferCnt = 0;
4111 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4112 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4114 currSCCB->HostStatus = SCCB_PARITY_ERR;
4115 WRW_HARPOON((port+hp_intstat), PARITY);
4119 FPT_hostDataXferAbort(port,p_card,currSCCB);
4122 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4126 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4128 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4131 if (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) {
4134 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4137 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4141 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4142 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4143 (RD_HARPOON(port+hp_offsetctr) & (UCHAR)0x1F) ||
4144 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4145 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4148 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4150 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4152 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4153 FPT_phaseDataIn(port,p_card);
4157 FPT_phaseDataOut(port,p_card);
4162 FPT_sxfrp(port,p_card);
4163 if (!(RDW_HARPOON((port+hp_intstat)) &
4164 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4166 WRW_HARPOON((port+hp_intstat), AUTO_INT);
4167 FPT_phaseDecode(port,p_card);
4174 WR_HARPOON(port+hp_portctrl_0, 0x00);
4179 /*---------------------------------------------------------------------
4181 * Function: FPT_sinits
4183 * Description: Setup SCCB manager fields in this SCCB.
4185 *---------------------------------------------------------------------*/
4187 static void FPT_sinits(PSCCB p_sccb, UCHAR p_card)
4189 PSCCBMgr_tar_info currTar_Info;
4191 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4195 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
4197 p_sccb->Sccb_XferState = 0x00;
4198 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4200 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4201 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4203 p_sccb->Sccb_SGoffset = 0;
4204 p_sccb->Sccb_XferState = F_SG_XFER;
4205 p_sccb->Sccb_XferCnt = 0x00;
4208 if (p_sccb->DataLength == 0x00)
4210 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4212 if (p_sccb->ControlByte & F_USE_CMD_Q)
4214 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4215 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4218 currTar_Info->TarStatus |= TAG_Q_TRYING;
4221 /* For !single SCSI device in system & device allow Disconnect
4222 or command is tag_q type then send Cmd with Disconnect Enable
4223 else send Cmd with Disconnect Disable */
4226 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4227 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4228 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4230 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4231 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4232 p_sccb->Sccb_idmsg = (UCHAR)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4237 p_sccb->Sccb_idmsg = (UCHAR)SMIDENT | p_sccb->Lun;
4240 p_sccb->HostStatus = 0x00;
4241 p_sccb->TargetStatus = 0x00;
4242 p_sccb->Sccb_tag = 0x00;
4243 p_sccb->Sccb_MGRFlags = 0x00;
4244 p_sccb->Sccb_sgseg = 0x00;
4245 p_sccb->Sccb_ATC = 0x00;
4246 p_sccb->Sccb_savedATC = 0x00;
4248 p_sccb->SccbVirtDataPtr = 0x00;
4249 p_sccb->Sccb_forwardlink = NULL;
4250 p_sccb->Sccb_backlink = NULL;
4252 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4253 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4254 p_sccb->Sccb_scsimsg = SMNO_OP;
4259 /*---------------------------------------------------------------------
4261 * Function: Phase Decode
4263 * Description: Determine the phase and call the appropriate function.
4265 *---------------------------------------------------------------------*/
4267 static void FPT_phaseDecode(ULONG p_port, UCHAR p_card)
4269 unsigned char phase_ref;
4270 void (*phase) (ULONG, UCHAR);
4273 DISABLE_AUTO(p_port);
4275 phase_ref = (UCHAR) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4277 phase = FPT_s_PhaseTbl[phase_ref];
4279 (*phase)(p_port, p_card); /* Call the correct phase func */
4284 /*---------------------------------------------------------------------
4286 * Function: Data Out Phase
4288 * Description: Start up both the BusMaster and Xbow.
4290 *---------------------------------------------------------------------*/
4292 static void FPT_phaseDataOut(ULONG port, UCHAR p_card)
4297 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4298 if (currSCCB == NULL)
4300 return; /* Exit if No SCCB record */
4303 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4304 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4306 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4308 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4310 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4312 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4314 if (currSCCB->Sccb_XferCnt == 0) {
4317 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4318 (currSCCB->HostStatus == SCCB_COMPLETE))
4319 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4321 FPT_sxfrp(port,p_card);
4322 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4323 FPT_phaseDecode(port,p_card);
4328 /*---------------------------------------------------------------------
4330 * Function: Data In Phase
4332 * Description: Startup the BusMaster and the XBOW.
4334 *---------------------------------------------------------------------*/
4336 static void FPT_phaseDataIn(ULONG port, UCHAR p_card)
4341 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4343 if (currSCCB == NULL)
4345 return; /* Exit if No SCCB record */
4349 currSCCB->Sccb_scsistat = DATA_IN_ST;
4350 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4351 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4353 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4355 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4357 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4359 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4361 if (currSCCB->Sccb_XferCnt == 0) {
4364 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4365 (currSCCB->HostStatus == SCCB_COMPLETE))
4366 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4368 FPT_sxfrp(port,p_card);
4369 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4370 FPT_phaseDecode(port,p_card);
4375 /*---------------------------------------------------------------------
4377 * Function: Command Phase
4379 * Description: Load the CDB into the automation and start it up.
4381 *---------------------------------------------------------------------*/
4383 static void FPT_phaseCommand(ULONG p_port, UCHAR p_card)
4389 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4391 if (currSCCB->OperationCode == RESET_COMMAND) {
4393 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4394 currSCCB->CdbLength = SIX_BYTE_CMD;
4397 WR_HARPOON(p_port+hp_scsisig, 0x00);
4399 ARAM_ACCESS(p_port);
4402 cdb_reg = p_port + CMD_STRT;
4404 for (i=0; i < currSCCB->CdbLength; i++) {
4406 if (currSCCB->OperationCode == RESET_COMMAND)
4408 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4411 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4415 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4416 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4418 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4420 currSCCB->Sccb_scsistat = COMMAND_ST;
4422 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4423 SGRAM_ACCESS(p_port);
4427 /*---------------------------------------------------------------------
4429 * Function: Status phase
4431 * Description: Bring in the status and command complete message bytes
4433 *---------------------------------------------------------------------*/
4435 static void FPT_phaseStatus(ULONG port, UCHAR p_card)
4437 /* Start-up the automation to finish off this command and let the
4438 isr handle the interrupt for command complete when it comes in.
4439 We could wait here for the interrupt to be generated?
4442 WR_HARPOON(port+hp_scsisig, 0x00);
4444 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4448 /*---------------------------------------------------------------------
4450 * Function: Phase Message Out
4452 * Description: Send out our message (if we have one) and handle whatever
4455 *---------------------------------------------------------------------*/
4457 static void FPT_phaseMsgOut(ULONG port, UCHAR p_card)
4459 UCHAR message,scsiID;
4461 PSCCBMgr_tar_info currTar_Info;
4463 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4465 if (currSCCB != NULL) {
4467 message = currSCCB->Sccb_scsimsg;
4468 scsiID = currSCCB->TargID;
4470 if (message == SMDEV_RESET)
4474 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4475 currTar_Info->TarSyncCtrl = 0;
4476 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
4478 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
4481 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
4485 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
4488 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
4492 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4493 FPT_SccbMgrTableInitTarget(p_card,scsiID);
4495 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4497 currSCCB->HostStatus = SCCB_COMPLETE;
4498 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
4500 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4501 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4506 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4510 if(message == SMNO_OP)
4512 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4514 FPT_ssel(port,p_card);
4522 if (message == SMABORT)
4524 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4533 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4536 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4538 WR_HARPOON(port+hp_scsidata_0,message);
4540 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4544 WR_HARPOON(port+hp_portctrl_0, 0x00);
4546 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4547 (message == SMABORT_TAG) )
4550 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4552 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4554 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4556 if (currSCCB != NULL)
4559 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4560 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4561 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4563 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4565 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
4570 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4577 FPT_sxfrp(port,p_card);
4584 if(message == SMPARITY)
4586 currSCCB->Sccb_scsimsg = SMNO_OP;
4587 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4591 FPT_sxfrp(port,p_card);
4597 /*---------------------------------------------------------------------
4599 * Function: Message In phase
4601 * Description: Bring in the message and determine what to do with it.
4603 *---------------------------------------------------------------------*/
4605 static void FPT_phaseMsgIn(ULONG port, UCHAR p_card)
4610 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4612 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
4615 FPT_phaseChkFifo(port, p_card);
4618 message = RD_HARPOON(port+hp_scsidata_0);
4619 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4622 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4629 message = FPT_sfm(port,currSCCB);
4634 FPT_sdecm(message,port,p_card);
4639 if(currSCCB->Sccb_scsimsg != SMPARITY)
4641 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4648 /*---------------------------------------------------------------------
4650 * Function: Illegal phase
4652 * Description: Target switched to some illegal phase, so all we can do
4653 * is report an error back to the host (if that is possible)
4654 * and send an ABORT message to the misbehaving target.
4656 *---------------------------------------------------------------------*/
4658 static void FPT_phaseIllegal(ULONG port, UCHAR p_card)
4662 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4664 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4665 if (currSCCB != NULL) {
4667 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4668 currSCCB->Sccb_scsistat = ABORT_ST;
4669 currSCCB->Sccb_scsimsg = SMABORT;
4672 ACCEPT_MSG_ATN(port);
4677 /*---------------------------------------------------------------------
4679 * Function: Phase Check FIFO
4681 * Description: Make sure data has been flushed from both FIFOs and abort
4682 * the operations if necessary.
4684 *---------------------------------------------------------------------*/
4686 static void FPT_phaseChkFifo(ULONG port, UCHAR p_card)
4691 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4693 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4696 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4697 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4700 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4702 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4704 currSCCB->Sccb_XferCnt = 0;
4706 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4707 (currSCCB->HostStatus == SCCB_COMPLETE))
4709 currSCCB->HostStatus = SCCB_PARITY_ERR;
4710 WRW_HARPOON((port+hp_intstat), PARITY);
4713 FPT_hostDataXferAbort(port,p_card,currSCCB);
4715 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4717 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4718 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4721 } /*End Data In specific code. */
4725 GET_XFER_CNT(port,xfercnt);
4728 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4731 WR_HARPOON(port+hp_portctrl_0, 0x00);
4733 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4735 currSCCB->Sccb_XferCnt = xfercnt;
4737 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4738 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4740 currSCCB->HostStatus = SCCB_PARITY_ERR;
4741 WRW_HARPOON((port+hp_intstat), PARITY);
4745 FPT_hostDataXferAbort(port,p_card,currSCCB);
4748 WR_HARPOON(port+hp_fifowrite, 0x00);
4749 WR_HARPOON(port+hp_fiforead, 0x00);
4750 WR_HARPOON(port+hp_xferstat, 0x00);
4752 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4756 /*---------------------------------------------------------------------
4758 * Function: Phase Bus Free
4760 * Description: We just went bus free so figure out if it was
4761 * because of command complete or from a disconnect.
4763 *---------------------------------------------------------------------*/
4764 static void FPT_phaseBusFree(ULONG port, UCHAR p_card)
4768 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4770 if (currSCCB != NULL)
4776 if (currSCCB->OperationCode == RESET_COMMAND)
4779 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4780 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4781 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4783 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4785 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4787 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
4791 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4793 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4794 (UCHAR)SYNC_SUPPORTED;
4795 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4798 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4800 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4801 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4802 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4804 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
4807 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4809 /* Make sure this is not a phony BUS_FREE. If we were
4810 reselected or if BUSY is NOT on then this is a
4811 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4813 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4814 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4816 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4817 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
4829 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4831 if (!currSCCB->HostStatus)
4833 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4836 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4837 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4838 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4840 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4842 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4847 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4849 } /*end if !=null */
4855 /*---------------------------------------------------------------------
4857 * Function: Auto Load Default Map
4859 * Description: Load the Automation RAM with the defualt map values.
4861 *---------------------------------------------------------------------*/
4862 static void FPT_autoLoadDefaultMap(ULONG p_port)
4866 ARAM_ACCESS(p_port);
4867 map_addr = p_port + hp_aramBase;
4869 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4871 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4873 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4875 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4877 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4879 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4881 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4883 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4885 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4887 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4889 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4891 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4893 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4895 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4897 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4899 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4901 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4903 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4904 map_addr +=2; /*This means AYNC DATA IN */
4905 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4907 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4909 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4911 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4913 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4915 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4917 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4919 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4921 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4923 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4925 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4927 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4929 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4931 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4933 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4935 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4937 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4939 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4942 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4944 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4946 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4948 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4949 map_addr +=2; /* DIDN'T GET ONE */
4950 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4952 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4954 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4958 SGRAM_ACCESS(p_port);
4961 /*---------------------------------------------------------------------
4963 * Function: Auto Command Complete
4965 * Description: Post command back to host and find another command
4968 *---------------------------------------------------------------------*/
4970 static void FPT_autoCmdCmplt(ULONG p_port, UCHAR p_card)
4975 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4977 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4979 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4981 if (status_byte != SSGOOD) {
4983 if (status_byte == SSQ_FULL) {
4986 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4987 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4989 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4990 if(FPT_BL_Card[p_card].discQCount != 0)
4991 FPT_BL_Card[p_card].discQCount--;
4992 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
4996 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
4997 if(currSCCB->Sccb_tag)
4999 if(FPT_BL_Card[p_card].discQCount != 0)
5000 FPT_BL_Card[p_card].discQCount--;
5001 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5004 if(FPT_BL_Card[p_card].discQCount != 0)
5005 FPT_BL_Card[p_card].discQCount--;
5006 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5010 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
5012 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
5017 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
5019 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
5020 (UCHAR)SYNC_SUPPORTED;
5022 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5023 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5025 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5026 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5028 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5029 if(FPT_BL_Card[p_card].discQCount != 0)
5030 FPT_BL_Card[p_card].discQCount--;
5031 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5035 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5036 if(currSCCB->Sccb_tag)
5038 if(FPT_BL_Card[p_card].discQCount != 0)
5039 FPT_BL_Card[p_card].discQCount--;
5040 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5043 if(FPT_BL_Card[p_card].discQCount != 0)
5044 FPT_BL_Card[p_card].discQCount--;
5045 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5052 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5055 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5056 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
5057 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5059 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5060 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5062 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5063 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5065 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5066 if(FPT_BL_Card[p_card].discQCount != 0)
5067 FPT_BL_Card[p_card].discQCount--;
5068 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5072 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5073 if(currSCCB->Sccb_tag)
5075 if(FPT_BL_Card[p_card].discQCount != 0)
5076 FPT_BL_Card[p_card].discQCount--;
5077 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5080 if(FPT_BL_Card[p_card].discQCount != 0)
5081 FPT_BL_Card[p_card].discQCount--;
5082 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5089 if (status_byte == SSCHECK)
5091 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
5093 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
5095 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
5097 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
5099 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
5104 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5106 currSCCB->SccbStatus = SCCB_ERROR;
5107 currSCCB->TargetStatus = status_byte;
5109 if (status_byte == SSCHECK) {
5111 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5115 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5117 if (currSCCB->RequestSenseLength == 0)
5118 currSCCB->RequestSenseLength = 14;
5120 FPT_ssenss(&FPT_BL_Card[p_card]);
5121 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5123 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5124 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5126 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5127 if(FPT_BL_Card[p_card].discQCount != 0)
5128 FPT_BL_Card[p_card].discQCount--;
5129 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5133 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5134 if(currSCCB->Sccb_tag)
5136 if(FPT_BL_Card[p_card].discQCount != 0)
5137 FPT_BL_Card[p_card].discQCount--;
5138 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5141 if(FPT_BL_Card[p_card].discQCount != 0)
5142 FPT_BL_Card[p_card].discQCount--;
5143 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5153 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5154 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5155 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
5157 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5160 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
5163 #define SHORT_WAIT 0x0000000F
5164 #define LONG_WAIT 0x0000FFFFL
5167 /*---------------------------------------------------------------------
5169 * Function: Data Transfer Processor
5171 * Description: This routine performs two tasks.
5172 * (1) Start data transfer by calling HOST_DATA_XFER_START
5173 * function. Once data transfer is started, (2) Depends
5174 * on the type of data transfer mode Scatter/Gather mode
5175 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5176 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5177 * data transfer done. In Scatter/Gather mode, this routine
5178 * checks bus master command complete and dual rank busy
5179 * bit to keep chaining SC transfer command. Similarly,
5180 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5181 * (F_HOST_XFER_ACT bit) for data transfer done.
5183 *---------------------------------------------------------------------*/
5185 static void FPT_dataXferProcessor(ULONG port, PSCCBcard pCurrCard)
5189 currSCCB = pCurrCard->currentSCCB;
5191 if (currSCCB->Sccb_XferState & F_SG_XFER)
5193 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5196 currSCCB->Sccb_sgseg += (UCHAR)SG_BUF_CNT;
5197 currSCCB->Sccb_SGoffset = 0x00;
5199 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5201 FPT_busMstrSGDataXferStart(port, currSCCB);
5206 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5208 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5210 FPT_busMstrDataXferStart(port, currSCCB);
5216 /*---------------------------------------------------------------------
5218 * Function: BusMaster Scatter Gather Data Transfer Start
5222 *---------------------------------------------------------------------*/
5223 static void FPT_busMstrSGDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
5225 ULONG count,addr,tmpSGCnt;
5231 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5233 count = ((ULONG) HOST_RD_CMD)<<24;
5237 count = ((ULONG) HOST_WRT_CMD)<<24;
5242 sg_index = pcurrSCCB->Sccb_sgseg;
5243 reg_offset = hp_aramBase;
5246 i = (UCHAR) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5249 WR_HARPOON(p_port+hp_page_ctrl, i);
5251 while ((sg_count < (UCHAR)SG_BUF_CNT) &&
5252 ((ULONG)(sg_index * (UINT)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5254 tmpSGCnt += *(((ULONG *)pcurrSCCB->DataPointer)+
5257 count |= *(((ULONG *)pcurrSCCB->DataPointer)+
5260 addr = *(((ULONG *)pcurrSCCB->DataPointer)+
5261 ((sg_index * 2) + 1));
5264 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5266 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5267 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5269 tmpSGCnt = count & 0x00FFFFFFL;
5272 WR_HARP32(p_port,reg_offset,addr);
5275 WR_HARP32(p_port,reg_offset,count);
5278 count &= 0xFF000000L;
5284 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5286 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5288 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5290 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5293 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5294 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5300 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5301 (tmpSGCnt & 0x000000001))
5304 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5309 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5311 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5312 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5316 WR_HARPOON(p_port+hp_page_ctrl, (UCHAR) (i | SCATTER_EN));
5321 /*---------------------------------------------------------------------
5323 * Function: BusMaster Data Transfer Start
5327 *---------------------------------------------------------------------*/
5328 static void FPT_busMstrDataXferStart(ULONG p_port, PSCCB pcurrSCCB)
5332 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5334 count = pcurrSCCB->Sccb_XferCnt;
5336 addr = (ULONG) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5340 addr = pcurrSCCB->SensePointer;
5341 count = pcurrSCCB->RequestSenseLength;
5345 HP_SETUP_ADDR_CNT(p_port,addr,count);
5348 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5350 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5351 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5353 WR_HARPOON(p_port+hp_xfer_cmd,
5354 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5359 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5360 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5362 WR_HARPOON(p_port+hp_xfer_cmd,
5363 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5369 /*---------------------------------------------------------------------
5371 * Function: BusMaster Timeout Handler
5373 * Description: This function is called after a bus master command busy time
5374 * out is detected. This routines issue halt state machine
5375 * with a software time out for command busy. If command busy
5376 * is still asserted at the end of the time out, it issues
5377 * hard abort with another software time out. It hard abort
5378 * command busy is also time out, it'll just give up.
5380 *---------------------------------------------------------------------*/
5381 static UCHAR FPT_busMstrTimeOut(ULONG p_port)
5385 timeout = LONG_WAIT;
5387 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5389 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5393 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5394 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5396 timeout = LONG_WAIT;
5397 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5400 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5402 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5412 /*---------------------------------------------------------------------
5414 * Function: Host Data Transfer Abort
5416 * Description: Abort any in progress transfer.
5418 *---------------------------------------------------------------------*/
5419 static void FPT_hostDataXferAbort(ULONG port, UCHAR p_card, PSCCB pCurrSCCB)
5426 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5428 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5431 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5433 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5434 timeout = LONG_WAIT;
5436 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5438 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5440 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5442 if (FPT_busMstrTimeOut(port)) {
5444 if (pCurrSCCB->HostStatus == 0x00)
5446 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5450 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5452 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5454 if (pCurrSCCB->HostStatus == 0x00)
5457 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5463 else if (pCurrSCCB->Sccb_XferCnt) {
5465 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5468 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5471 WR_HARPOON(port+hp_sg_addr,0x00);
5473 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5475 if (sg_ptr > (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5477 sg_ptr = (UINT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5480 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5482 while (remain_cnt < 0x01000000L) {
5486 if (remain_cnt > (ULONG)(*(((ULONG *)pCurrSCCB->
5487 DataPointer) + (sg_ptr * 2)))) {
5489 remain_cnt -= (ULONG)(*(((ULONG *)pCurrSCCB->
5490 DataPointer) + (sg_ptr * 2)));
5501 if (remain_cnt < 0x01000000L) {
5504 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5506 pCurrSCCB->Sccb_sgseg = (USHORT)sg_ptr;
5509 if ((ULONG)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5510 && (remain_cnt == 0))
5512 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5518 if (pCurrSCCB->HostStatus == 0x00) {
5520 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5526 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5529 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5531 FPT_busMstrTimeOut(port);
5536 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5538 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5540 if (pCurrSCCB->HostStatus == 0x00) {
5542 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5553 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5555 timeout = SHORT_WAIT;
5557 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5558 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5562 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5564 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5567 timeout = LONG_WAIT;
5569 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5572 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5576 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5578 if (pCurrSCCB->HostStatus == 0x00) {
5580 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5583 FPT_busMstrTimeOut(port);
5587 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5589 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5591 if (pCurrSCCB->HostStatus == 0x00) {
5593 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5604 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5606 timeout = LONG_WAIT;
5608 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5610 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5612 if (pCurrSCCB->HostStatus == 0x00) {
5614 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5617 FPT_busMstrTimeOut(port);
5622 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5624 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5626 if (pCurrSCCB->HostStatus == 0x00) {
5628 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5634 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5636 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5639 WR_HARPOON(port+hp_sg_addr,0x00);
5641 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5643 pCurrSCCB->Sccb_SGoffset = 0x00;
5646 if ((ULONG)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5647 pCurrSCCB->DataLength) {
5649 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5651 pCurrSCCB->Sccb_sgseg = (USHORT)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5658 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5660 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5664 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5669 /*---------------------------------------------------------------------
5671 * Function: Host Data Transfer Restart
5673 * Description: Reset the available count due to a restore data
5676 *---------------------------------------------------------------------*/
5677 static void FPT_hostDataXferRestart(PSCCB currSCCB)
5683 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5685 currSCCB->Sccb_XferCnt = 0;
5687 sg_index = 0xffff; /*Index by long words into sg list. */
5688 data_count = 0; /*Running count of SG xfer counts. */
5690 sg_ptr = (ULONG *)currSCCB->DataPointer;
5692 while (data_count < currSCCB->Sccb_ATC) {
5695 data_count += *(sg_ptr+(sg_index * 2));
5698 if (data_count == currSCCB->Sccb_ATC) {
5700 currSCCB->Sccb_SGoffset = 0;
5705 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5708 currSCCB->Sccb_sgseg = (USHORT)sg_index;
5712 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5718 /*---------------------------------------------------------------------
5720 * Function: FPT_scini
5722 * Description: Setup all data structures necessary for SCAM selection.
5724 *---------------------------------------------------------------------*/
5726 static void FPT_scini(UCHAR p_card, UCHAR p_our_id, UCHAR p_power_up)
5729 UCHAR loser,assigned_id;
5734 PNVRamInfo pCurrNvRam;
5736 currCard = &FPT_BL_Card[p_card];
5737 p_port = currCard->ioPort;
5738 pCurrNvRam = currCard->pNvRamInfo;
5742 ScamFlg = pCurrNvRam->niScamConf;
5743 i = pCurrNvRam->niSysConf;
5746 ScamFlg = (UCHAR) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5747 i = (UCHAR)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
5749 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5752 FPT_inisci(p_card,p_port, p_our_id);
5754 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5755 too slow to return to SCAM selection */
5758 FPT_Wait1Second(p_port);
5760 FPT_Wait(p_port, TO_250ms); */
5762 FPT_Wait1Second(p_port);
5764 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5766 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5771 FPT_scxferc(p_port,SYNC_PTRN);
5772 FPT_scxferc(p_port,DOM_MSTR);
5773 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
5774 } while ( loser == 0xFF );
5778 if ((p_power_up) && (!loser))
5780 FPT_sresb(p_port,p_card);
5781 FPT_Wait(p_port, TO_250ms);
5783 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5788 FPT_scxferc(p_port, SYNC_PTRN);
5789 FPT_scxferc(p_port, DOM_MSTR);
5790 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
5792 } while ( loser == 0xFF );
5807 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5810 if (ScamFlg & SCAM_ENABLED)
5813 for (i=0; i < MAX_SCSI_TAR; i++)
5815 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5816 (FPT_scamInfo[i].state == ID_UNUSED))
5818 if (FPT_scsell(p_port,i))
5820 FPT_scamInfo[i].state = LEGACY;
5821 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5822 (FPT_scamInfo[i].id_string[1] != 0xFA))
5825 FPT_scamInfo[i].id_string[0] = 0xFF;
5826 FPT_scamInfo[i].id_string[1] = 0xFA;
5827 if(pCurrNvRam == NULL)
5828 currCard->globalFlags |= F_UPDATE_EEPROM;
5834 FPT_sresb(p_port,p_card);
5835 FPT_Wait1Second(p_port);
5836 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5838 FPT_scasid(p_card, p_port);
5843 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5845 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5847 FPT_scwtsel(p_port);
5850 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
5852 i = FPT_scxferc(p_port,0x00);
5855 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
5857 i = FPT_scxferc(p_port,0x00);
5860 k = FPT_scxferc(p_port,0x00);
5865 ((UCHAR)(i<<3)+(k & (UCHAR)7)) & (UCHAR) 0x3F;
5866 FPT_inisci(p_card, p_port, p_our_id);
5867 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5868 FPT_scamInfo[currCard->ourId].id_string[0]
5876 else if (i == SET_P_FLAG)
5878 if (!(FPT_scsendi(p_port,
5879 &FPT_scamInfo[p_our_id].id_string[0])))
5880 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
5882 }while (!assigned_id);
5884 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
5887 if (ScamFlg & SCAM_ENABLED)
5890 if (currCard->globalFlags & F_UPDATE_EEPROM)
5892 FPT_scsavdi(p_card, p_port);
5893 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5899 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5901 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5902 (FPT_scamInfo[i].state == LEGACY))
5907 currCard->globalFlags |= F_SINGLE_DEVICE;
5909 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5914 /*---------------------------------------------------------------------
5916 * Function: FPT_scarb
5918 * Description: Gain control of the bus and wait SCAM select time (250ms)
5920 *---------------------------------------------------------------------*/
5922 static int FPT_scarb(ULONG p_port, UCHAR p_sel_type)
5924 if (p_sel_type == INIT_SELTD)
5927 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5930 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
5933 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
5936 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5938 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5940 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5946 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5948 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5950 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5951 ~(SCSI_BSY | SCSI_SEL)));
5957 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5959 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5960 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5961 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
5962 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5964 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5966 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5969 FPT_Wait(p_port,TO_250ms);
5975 /*---------------------------------------------------------------------
5977 * Function: FPT_scbusf
5979 * Description: Release the SCSI bus and disable SCAM selection.
5981 *---------------------------------------------------------------------*/
5983 static void FPT_scbusf(ULONG p_port)
5985 WR_HARPOON(p_port+hp_page_ctrl,
5986 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5989 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5991 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5994 WR_HARPOON(p_port+hp_scsisig, 0x00);
5997 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
6000 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
6003 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
6005 WR_HARPOON(p_port+hp_page_ctrl,
6006 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6011 /*---------------------------------------------------------------------
6013 * Function: FPT_scasid
6015 * Description: Assign an ID to all the SCAM devices.
6017 *---------------------------------------------------------------------*/
6019 static void FPT_scasid(UCHAR p_card, ULONG p_port)
6021 UCHAR temp_id_string[ID_STRING_LENGTH];
6025 PNVRamInfo pCurrNvRam;
6026 ushort_ptr pCrcBytes;
6028 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6035 for (k=0; k < ID_STRING_LENGTH; k++)
6037 temp_id_string[k] = (UCHAR) 0x00;
6040 FPT_scxferc(p_port,SYNC_PTRN);
6041 FPT_scxferc(p_port,ASSIGN_ID);
6043 if (!(FPT_sciso(p_port,&temp_id_string[0])))
6046 pCrcBytes = (ushort_ptr)&crcBytes[0];
6047 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6048 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
6049 temp_id_string[1] = crcBytes[2];
6050 temp_id_string[2] = crcBytes[0];
6051 temp_id_string[3] = crcBytes[1];
6052 for(k = 4; k < ID_STRING_LENGTH; k++)
6053 temp_id_string[k] = (UCHAR) 0x00;
6055 i = FPT_scmachid(p_card,temp_id_string);
6057 if (i == CLR_PRIORITY)
6059 FPT_scxferc(p_port,MISC_CODE);
6060 FPT_scxferc(p_port,CLR_P_FLAG);
6061 i = 0; /*Not the last ID yet. */
6064 else if (i != NO_ID_AVAIL)
6067 FPT_scxferc(p_port,ID_0_7);
6069 FPT_scxferc(p_port,ID_8_F);
6071 scam_id = (i & (UCHAR) 0x07);
6074 for (k=1; k < 0x08; k <<= 1)
6076 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6078 FPT_scxferc(p_port,scam_id);
6080 i = 0; /*Not the last ID yet. */
6091 FPT_scxferc(p_port,SYNC_PTRN);
6092 FPT_scxferc(p_port,CFG_CMPLT);
6099 /*---------------------------------------------------------------------
6101 * Function: FPT_scsel
6103 * Description: Select all the SCAM devices.
6105 *---------------------------------------------------------------------*/
6107 static void FPT_scsel(ULONG p_port)
6110 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6111 FPT_scwiros(p_port, SCSI_MSG);
6113 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6116 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6117 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) |
6118 (UCHAR)(BIT(7)+BIT(6))));
6121 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6122 FPT_scwiros(p_port, SCSI_SEL);
6124 WR_HARPOON(p_port+hp_scsidata_0, (UCHAR)(RD_HARPOON(p_port+hp_scsidata_0) &
6126 FPT_scwirod(p_port, BIT(6));
6128 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6133 /*---------------------------------------------------------------------
6135 * Function: FPT_scxferc
6137 * Description: Handshake the p_data (DB4-0) across the bus.
6139 *---------------------------------------------------------------------*/
6141 static UCHAR FPT_scxferc(ULONG p_port, UCHAR p_data)
6143 UCHAR curr_data, ret_data;
6145 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6147 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6149 curr_data &= ~BIT(7);
6151 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6153 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
6154 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6156 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (UCHAR) 0x1F);
6158 curr_data |= BIT(6);
6160 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6162 curr_data &= ~BIT(5);
6164 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6166 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
6168 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6169 curr_data |= BIT(7);
6171 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6173 curr_data &= ~BIT(6);
6175 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6177 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
6183 /*---------------------------------------------------------------------
6185 * Function: FPT_scsendi
6187 * Description: Transfer our Identification string to determine if we
6188 * will be the dominant master.
6190 *---------------------------------------------------------------------*/
6192 static UCHAR FPT_scsendi(ULONG p_port, UCHAR p_id_string[])
6194 UCHAR ret_data,byte_cnt,bit_cnt,defer;
6198 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6200 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6203 ret_data = FPT_scxferc(p_port,00);
6205 else if (p_id_string[byte_cnt] & bit_cnt)
6207 ret_data = FPT_scxferc(p_port,02);
6211 ret_data = FPT_scxferc(p_port,01);
6216 if ((ret_data & 0x1C) == 0x10)
6217 return(0x00); /*End of isolation stage, we won! */
6219 if (ret_data & 0x1C)
6222 if ((defer) && (!(ret_data & 0x1F)))
6223 return(0x01); /*End of isolation stage, we lost. */
6230 return(0x01); /*We lost */
6232 return(0); /*We WON! Yeeessss! */
6237 /*---------------------------------------------------------------------
6239 * Function: FPT_sciso
6241 * Description: Transfer the Identification string.
6243 *---------------------------------------------------------------------*/
6245 static UCHAR FPT_sciso(ULONG p_port, UCHAR p_id_string[])
6247 UCHAR ret_data,the_data,byte_cnt,bit_cnt;
6251 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6253 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6255 ret_data = FPT_scxferc(p_port,0);
6257 if (ret_data & 0xFC)
6263 if (ret_data & BIT(1)) {
6268 if ((ret_data & 0x1F) == 0)
6271 if(bit_cnt != 0 || bit_cnt != 8)
6275 FPT_scxferc(p_port, SYNC_PTRN);
6276 FPT_scxferc(p_port, ASSIGN_ID);
6288 p_id_string[byte_cnt] = the_data;
6297 /*---------------------------------------------------------------------
6299 * Function: FPT_scwirod
6301 * Description: Sample the SCSI data bus making sure the signal has been
6302 * deasserted for the correct number of consecutive samples.
6304 *---------------------------------------------------------------------*/
6306 static void FPT_scwirod(ULONG p_port, UCHAR p_data_bit)
6311 while ( i < MAX_SCSI_TAR ) {
6313 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6326 /*---------------------------------------------------------------------
6328 * Function: FPT_scwiros
6330 * Description: Sample the SCSI Signal lines making sure the signal has been
6331 * deasserted for the correct number of consecutive samples.
6333 *---------------------------------------------------------------------*/
6335 static void FPT_scwiros(ULONG p_port, UCHAR p_data_bit)
6340 while ( i < MAX_SCSI_TAR ) {
6342 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6354 /*---------------------------------------------------------------------
6356 * Function: FPT_scvalq
6358 * Description: Make sure we received a valid data byte.
6360 *---------------------------------------------------------------------*/
6362 static UCHAR FPT_scvalq(UCHAR p_quintet)
6366 for (count=1; count < 0x08; count<<=1) {
6367 if (!(p_quintet & count))
6371 if (p_quintet & 0x18)
6379 /*---------------------------------------------------------------------
6381 * Function: FPT_scsell
6383 * Description: Select the specified device ID using a selection timeout
6384 * less than 4ms. If somebody responds then it is a legacy
6385 * drive and this ID must be marked as such.
6387 *---------------------------------------------------------------------*/
6389 static UCHAR FPT_scsell(ULONG p_port, UCHAR targ_id)
6393 WR_HARPOON(p_port+hp_page_ctrl,
6394 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6396 ARAM_ACCESS(p_port);
6398 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6399 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6402 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6403 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6405 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6407 WRW_HARPOON((p_port+hp_intstat),
6408 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6410 WR_HARPOON(p_port+hp_select_id, targ_id);
6412 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6413 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6414 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6417 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6418 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6420 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6421 FPT_Wait(p_port, TO_250ms);
6423 DISABLE_AUTO(p_port);
6425 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6426 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6428 SGRAM_ACCESS(p_port);
6430 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6432 WRW_HARPOON((p_port+hp_intstat),
6433 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6435 WR_HARPOON(p_port+hp_page_ctrl,
6436 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6438 return(0); /*No legacy device */
6443 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6444 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6446 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6451 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6453 WR_HARPOON(p_port+hp_page_ctrl,
6454 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6456 return(1); /*Found one of them oldies! */
6460 /*---------------------------------------------------------------------
6462 * Function: FPT_scwtsel
6464 * Description: Wait to be selected by another SCAM initiator.
6466 *---------------------------------------------------------------------*/
6468 static void FPT_scwtsel(ULONG p_port)
6470 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6474 /*---------------------------------------------------------------------
6476 * Function: FPT_inisci
6478 * Description: Setup the data Structure with the info from the EEPROM.
6480 *---------------------------------------------------------------------*/
6482 static void FPT_inisci(UCHAR p_card, ULONG p_port, UCHAR p_our_id)
6486 PNVRamInfo pCurrNvRam;
6488 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6490 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6497 for(i = 0; i < max_id; i++){
6499 for(k = 0; k < 4; k++)
6500 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
6501 for(k = 4; k < ID_STRING_LENGTH; k++)
6502 FPT_scamInfo[i].id_string[k] = (UCHAR) 0x00;
6504 if(FPT_scamInfo[i].id_string[0] == 0x00)
6505 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6507 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6511 for (i=0; i < max_id; i++)
6513 for (k=0; k < ID_STRING_LENGTH; k+=2)
6515 ee_data = FPT_utilEERead(p_port, (USHORT)((EE_SCAMBASE/2) +
6516 (USHORT) (i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
6517 FPT_scamInfo[i].id_string[k] = (UCHAR) ee_data;
6519 FPT_scamInfo[i].id_string[k+1] = (UCHAR) ee_data;
6522 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6523 (FPT_scamInfo[i].id_string[0] == 0xFF))
6525 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6528 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6532 for(k = 0; k < ID_STRING_LENGTH; k++)
6533 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6537 /*---------------------------------------------------------------------
6539 * Function: FPT_scmachid
6541 * Description: Match the Device ID string with our values stored in
6544 *---------------------------------------------------------------------*/
6546 static UCHAR FPT_scmachid(UCHAR p_card, UCHAR p_id_string[])
6552 for (i=0; i < MAX_SCSI_TAR; i++) {
6556 for (k=0; k < ID_STRING_LENGTH; k++)
6558 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6564 FPT_scamInfo[i].state = ID_ASSIGNED;
6572 if (p_id_string[0] & BIT(5))
6577 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6578 match = p_id_string[1] & (UCHAR) 0x1F;
6586 if (FPT_scamInfo[match].state == ID_UNUSED)
6588 for (k=0; k < ID_STRING_LENGTH; k++)
6590 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6593 FPT_scamInfo[match].state = ID_ASSIGNED;
6595 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6596 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6606 if (p_id_string[0] & BIT(5))
6609 match = MAX_SCSI_TAR-1;
6615 if (p_id_string[0] & BIT(7))
6617 return(CLR_PRIORITY);
6621 if (p_id_string[0] & BIT(5))
6626 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6627 match = p_id_string[1] & (UCHAR) 0x1F;
6636 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
6638 for (k=0; k < ID_STRING_LENGTH; k++)
6640 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6643 FPT_scamInfo[match].id_string[0] |= BIT(7);
6644 FPT_scamInfo[match].state = ID_ASSIGNED;
6645 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6646 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6656 if (p_id_string[0] & BIT(5))
6659 match = MAX_SCSI_TAR-1;
6663 return(NO_ID_AVAIL);
6667 /*---------------------------------------------------------------------
6669 * Function: FPT_scsavdi
6671 * Description: Save off the device SCAM ID strings.
6673 *---------------------------------------------------------------------*/
6675 static void FPT_scsavdi(UCHAR p_card, ULONG p_port)
6678 USHORT ee_data,sum_data;
6683 for (i = 1; i < EE_SCAMBASE/2; i++)
6685 sum_data += FPT_utilEERead(p_port, i);
6689 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
6691 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6697 for (i=0; i < max_id; i++)
6700 for (k=0; k < ID_STRING_LENGTH; k+=2)
6702 ee_data = FPT_scamInfo[i].id_string[k+1];
6704 ee_data |= FPT_scamInfo[i].id_string[k];
6705 sum_data += ee_data;
6706 FPT_utilEEWrite(p_port, ee_data, (USHORT)((EE_SCAMBASE/2) +
6707 (USHORT)(i*((USHORT)ID_STRING_LENGTH/2)) + (USHORT)(k/2)));
6712 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6713 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
6716 /*---------------------------------------------------------------------
6718 * Function: FPT_XbowInit
6720 * Description: Setup the Xbow for normal operation.
6722 *---------------------------------------------------------------------*/
6724 static void FPT_XbowInit(ULONG port, UCHAR ScamFlg)
6728 i = RD_HARPOON(port+hp_page_ctrl);
6729 WR_HARPOON(port+hp_page_ctrl, (UCHAR) (i | G_INT_DISABLE));
6731 WR_HARPOON(port+hp_scsireset,0x00);
6732 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6734 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6737 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6739 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6741 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6742 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6744 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6746 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6747 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6749 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6750 FPT_default_intena |= SCAM_SEL;
6752 WRW_HARPOON((port+hp_intena), FPT_default_intena);
6754 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6756 /* Turn on SCSI_MODE8 for narrow cards to fix the
6757 strapping issue with the DUAL CHANNEL card */
6758 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6759 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6761 WR_HARPOON(port+hp_page_ctrl, i);
6766 /*---------------------------------------------------------------------
6768 * Function: FPT_BusMasterInit
6770 * Description: Initialize the BusMaster for normal operations.
6772 *---------------------------------------------------------------------*/
6774 static void FPT_BusMasterInit(ULONG p_port)
6778 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6779 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6781 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6784 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6786 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6789 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6790 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6791 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6796 /*---------------------------------------------------------------------
6798 * Function: FPT_DiagEEPROM
6800 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6803 *---------------------------------------------------------------------*/
6805 static void FPT_DiagEEPROM(ULONG p_port)
6807 USHORT index,temp,max_wd_cnt;
6809 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6810 max_wd_cnt = EEPROM_WD_CNT;
6812 max_wd_cnt = EEPROM_WD_CNT * 2;
6814 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
6816 if (temp == 0x4641) {
6818 for (index = 2; index < max_wd_cnt; index++) {
6820 temp += FPT_utilEERead(p_port, index);
6824 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
6826 return; /*EEPROM is Okay so return now! */
6831 FPT_utilEEWriteOnOff(p_port,(UCHAR)1);
6833 for (index = 0; index < max_wd_cnt; index++) {
6835 FPT_utilEEWrite(p_port, 0x0000, index);
6840 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
6842 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
6844 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
6846 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
6848 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
6850 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
6852 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
6854 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
6857 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
6859 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
6861 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
6864 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
6866 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
6868 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
6870 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
6872 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
6874 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
6876 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
6878 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
6882 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
6884 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
6886 FPT_utilEEWrite(p_port, 0x5068, 68/2);
6888 FPT_utilEEWrite(p_port, 0x696F, 70/2);
6890 FPT_utilEEWrite(p_port, 0x746E, 72/2);
6892 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
6894 FPT_utilEEWrite(p_port, 0x2054, 76/2);
6896 FPT_utilEEWrite(p_port, 0x2020, 78/2);
6899 index = ((EE_SCAMBASE/2)+(7*16));
6900 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
6901 temp += (0x0700+TYPE_CODE0);
6903 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6904 temp += 0x5542; /* BUSLOGIC */
6906 FPT_utilEEWrite(p_port, 0x4C53, index);
6909 FPT_utilEEWrite(p_port, 0x474F, index);
6912 FPT_utilEEWrite(p_port, 0x4349, index);
6915 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6916 temp += 0x5442; /* BT- 930 */
6918 FPT_utilEEWrite(p_port, 0x202D, index);
6921 FPT_utilEEWrite(p_port, 0x3339, index);
6923 index++; /*Serial # */
6924 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6927 FPT_utilEEWrite(p_port, 0x5453, index);
6930 FPT_utilEEWrite(p_port, 0x5645, index);
6933 FPT_utilEEWrite(p_port, 0x2045, index);
6936 FPT_utilEEWrite(p_port, 0x202F, index);
6939 FPT_utilEEWrite(p_port, 0x4F4A, index);
6942 FPT_utilEEWrite(p_port, 0x204E, index);
6945 FPT_utilEEWrite(p_port, 0x3539, index);
6950 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
6952 FPT_utilEEWriteOnOff(p_port,(UCHAR)0);
6957 /*---------------------------------------------------------------------
6959 * Function: Queue Search Select
6961 * Description: Try to find a new command to execute.
6963 *---------------------------------------------------------------------*/
6965 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, UCHAR p_card)
6967 UCHAR scan_ptr, lun;
6968 PSCCBMgr_tar_info currTar_Info;
6971 scan_ptr = pCurrCard->scanIndex;
6974 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6975 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6976 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6978 if (currTar_Info->TarSelQ_Cnt != 0)
6982 if (scan_ptr == MAX_SCSI_TAR)
6985 for(lun=0; lun < MAX_LUN; lun++)
6987 if(currTar_Info->TarLUNBusy[lun] == 0)
6990 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6993 while((pCurrCard->currentSCCB != NULL) &&
6994 (lun != pCurrCard->currentSCCB->Lun))
6996 pOldSccb = pCurrCard->currentSCCB;
6997 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
7000 if(pCurrCard->currentSCCB == NULL)
7002 if(pOldSccb != NULL)
7004 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
7006 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
7008 currTar_Info->TarSelQ_Cnt--;
7012 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7014 if (currTar_Info->TarSelQ_Head == NULL)
7016 currTar_Info->TarSelQ_Tail = NULL;
7017 currTar_Info->TarSelQ_Cnt = 0;
7021 currTar_Info->TarSelQ_Cnt--;
7022 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7025 pCurrCard->scanIndex = scan_ptr;
7027 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7037 if (scan_ptr == MAX_SCSI_TAR) {
7045 if ((currTar_Info->TarSelQ_Cnt != 0) &&
7046 (currTar_Info->TarLUNBusy[0] == 0))
7049 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7051 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7053 if (currTar_Info->TarSelQ_Head == NULL)
7055 currTar_Info->TarSelQ_Tail = NULL;
7056 currTar_Info->TarSelQ_Cnt = 0;
7060 currTar_Info->TarSelQ_Cnt--;
7061 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7065 if (scan_ptr == MAX_SCSI_TAR)
7068 pCurrCard->scanIndex = scan_ptr;
7070 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7078 if (scan_ptr == MAX_SCSI_TAR)
7084 } while (scan_ptr != pCurrCard->scanIndex);
7088 /*---------------------------------------------------------------------
7090 * Function: Queue Select Fail
7092 * Description: Add the current SCCB to the head of the Queue.
7094 *---------------------------------------------------------------------*/
7096 static void FPT_queueSelectFail(PSCCBcard pCurrCard, UCHAR p_card)
7099 PSCCBMgr_tar_info currTar_Info;
7101 if (pCurrCard->currentSCCB != NULL)
7103 thisTarg = (UCHAR)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
7104 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7106 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7108 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7110 if (currTar_Info->TarSelQ_Cnt == 0)
7112 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7117 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7121 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7123 pCurrCard->currentSCCB = NULL;
7124 currTar_Info->TarSelQ_Cnt++;
7127 /*---------------------------------------------------------------------
7129 * Function: Queue Command Complete
7131 * Description: Call the callback function with the current SCCB.
7133 *---------------------------------------------------------------------*/
7135 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7140 CALL_BK_FN callback;
7141 PSCCBMgr_tar_info currTar_Info;
7143 SCSIcmd = p_sccb->Cdb[0];
7146 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7148 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7149 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7150 (p_sccb->TargetStatus != SSCHECK))
7152 if ((SCSIcmd == SCSI_READ) ||
7153 (SCSIcmd == SCSI_WRITE) ||
7154 (SCSIcmd == SCSI_READ_EXTENDED) ||
7155 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7156 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7157 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7158 (pCurrCard->globalFlags & F_NO_FILTER)
7160 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7164 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7166 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7167 p_sccb->SccbStatus = SCCB_ERROR;
7169 p_sccb->SccbStatus = SCCB_SUCCESS;
7172 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7174 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7175 for (i=0; i < 6; i++) {
7176 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7180 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7181 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7183 FPT_utilUpdateResidual(p_sccb);
7186 pCurrCard->cmdCounter--;
7187 if (!pCurrCard->cmdCounter) {
7189 if (pCurrCard->globalFlags & F_GREEN_PC) {
7190 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7191 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7194 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7195 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7199 if(pCurrCard->discQCount != 0)
7201 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7202 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7203 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7205 pCurrCard->discQCount--;
7206 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7210 if(p_sccb->Sccb_tag)
7212 pCurrCard->discQCount--;
7213 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7216 pCurrCard->discQCount--;
7217 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7223 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7225 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7226 pCurrCard->currentSCCB = NULL;
7230 /*---------------------------------------------------------------------
7232 * Function: Queue Disconnect
7234 * Description: Add SCCB to our disconnect array.
7236 *---------------------------------------------------------------------*/
7237 static void FPT_queueDisconnect(PSCCB p_sccb, UCHAR p_card)
7239 PSCCBMgr_tar_info currTar_Info;
7241 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7243 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7244 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7246 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
7250 if (p_sccb->Sccb_tag)
7252 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7253 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7254 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7257 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
7260 FPT_BL_Card[p_card].currentSCCB = NULL;
7264 /*---------------------------------------------------------------------
7266 * Function: Queue Flush SCCB
7268 * Description: Flush all SCCB's back to the host driver for this target.
7270 *---------------------------------------------------------------------*/
7272 static void FPT_queueFlushSccb(UCHAR p_card, UCHAR error_code)
7274 UCHAR qtag,thisTarg;
7276 PSCCBMgr_tar_info currTar_Info;
7278 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7279 if(currSCCB != NULL)
7281 thisTarg = (UCHAR)currSCCB->TargID;
7282 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7284 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7286 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7287 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7290 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
7292 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7294 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7295 currTar_Info->TarTagQ_Cnt--;
7303 /*---------------------------------------------------------------------
7305 * Function: Queue Flush Target SCCB
7307 * Description: Flush all SCCB's back to the host driver for this target.
7309 *---------------------------------------------------------------------*/
7311 static void FPT_queueFlushTargSccb(UCHAR p_card, UCHAR thisTarg,
7315 PSCCBMgr_tar_info currTar_Info;
7317 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7319 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7321 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7322 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7325 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (UCHAR)error_code;
7327 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7329 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7330 currTar_Info->TarTagQ_Cnt--;
7341 static void FPT_queueAddSccb(PSCCB p_SCCB, UCHAR p_card)
7343 PSCCBMgr_tar_info currTar_Info;
7344 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7346 p_SCCB->Sccb_forwardlink = NULL;
7348 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7350 if (currTar_Info->TarSelQ_Cnt == 0) {
7352 currTar_Info->TarSelQ_Head = p_SCCB;
7357 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7361 currTar_Info->TarSelQ_Tail = p_SCCB;
7362 currTar_Info->TarSelQ_Cnt++;
7366 /*---------------------------------------------------------------------
7368 * Function: Queue Find SCCB
7370 * Description: Search the target select Queue for this SCCB, and
7371 * remove it if found.
7373 *---------------------------------------------------------------------*/
7375 static UCHAR FPT_queueFindSccb(PSCCB p_SCCB, UCHAR p_card)
7378 PSCCBMgr_tar_info currTar_Info;
7380 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7382 q_ptr = currTar_Info->TarSelQ_Head;
7384 while(q_ptr != NULL) {
7386 if (q_ptr == p_SCCB) {
7389 if (currTar_Info->TarSelQ_Head == q_ptr) {
7391 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7394 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7396 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7399 if (q_ptr->Sccb_forwardlink != NULL) {
7400 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7403 if (q_ptr->Sccb_backlink != NULL) {
7404 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7407 currTar_Info->TarSelQ_Cnt--;
7413 q_ptr = q_ptr->Sccb_forwardlink;
7423 /*---------------------------------------------------------------------
7425 * Function: Utility Update Residual Count
7427 * Description: Update the XferCnt to the remaining byte count.
7428 * If we transferred all the data then just write zero.
7429 * If Non-SG transfer then report Total Cnt - Actual Transfer
7430 * Cnt. For SG transfers add the count fields of all
7431 * remaining SG elements, as well as any partial remaining
7434 *---------------------------------------------------------------------*/
7436 static void FPT_utilUpdateResidual(PSCCB p_SCCB)
7442 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7444 p_SCCB->DataLength = 0x0000;
7447 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7449 partial_cnt = 0x0000;
7451 sg_index = p_SCCB->Sccb_sgseg;
7453 sg_ptr = (ULONG *)p_SCCB->DataPointer;
7455 if (p_SCCB->Sccb_SGoffset) {
7457 partial_cnt = p_SCCB->Sccb_SGoffset;
7461 while ( ((ULONG)sg_index * (ULONG)SG_ELEMENT_SIZE) <
7462 p_SCCB->DataLength ) {
7464 partial_cnt += *(sg_ptr+(sg_index * 2));
7468 p_SCCB->DataLength = partial_cnt;
7473 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7478 /*---------------------------------------------------------------------
7480 * Function: Wait 1 Second
7482 * Description: Wait for 1 second.
7484 *---------------------------------------------------------------------*/
7486 static void FPT_Wait1Second(ULONG p_port)
7490 for(i=0; i < 4; i++) {
7492 FPT_Wait(p_port, TO_250ms);
7494 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7497 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7503 /*---------------------------------------------------------------------
7505 * Function: FPT_Wait
7507 * Description: Wait the desired delay.
7509 *---------------------------------------------------------------------*/
7511 static void FPT_Wait(ULONG p_port, UCHAR p_delay)
7516 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7518 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7519 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7521 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7522 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7523 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
7526 WR_HARPOON(p_port+hp_portctrl_0,
7527 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7529 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7531 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7534 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7538 WR_HARPOON(p_port+hp_portctrl_0,
7539 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7541 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7542 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
7544 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7546 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7550 /*---------------------------------------------------------------------
7552 * Function: Enable/Disable Write to EEPROM
7554 * Description: The EEPROM must first be enabled for writes
7555 * A total of 9 clocks are needed.
7557 *---------------------------------------------------------------------*/
7559 static void FPT_utilEEWriteOnOff(ULONG p_port,UCHAR p_mode)
7563 ee_value = (UCHAR)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7567 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7572 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7574 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7575 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7579 /*---------------------------------------------------------------------
7581 * Function: Write EEPROM
7583 * Description: Write a word to the EEPROM at the specified
7586 *---------------------------------------------------------------------*/
7588 static void FPT_utilEEWrite(ULONG p_port, USHORT ee_data, USHORT ee_addr)
7594 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7599 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7602 ee_value |= (SEE_MS + SEE_CS);
7604 for(i = 0x8000; i != 0; i>>=1) {
7609 ee_value &= ~SEE_DO;
7611 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7612 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7613 ee_value |= SEE_CLK; /* Clock data! */
7614 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7615 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7616 ee_value &= ~SEE_CLK;
7617 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7618 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7620 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7621 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7623 FPT_Wait(p_port, TO_10ms);
7625 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7626 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7627 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7630 /*---------------------------------------------------------------------
7632 * Function: Read EEPROM
7634 * Description: Read a word from the EEPROM at the desired
7637 *---------------------------------------------------------------------*/
7639 static USHORT FPT_utilEERead(ULONG p_port, USHORT ee_addr)
7641 USHORT i, ee_data1, ee_data2;
7644 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7647 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7649 if(ee_data1 == ee_data2)
7652 ee_data1 = ee_data2;
7660 /*---------------------------------------------------------------------
7662 * Function: Read EEPROM Original
7664 * Description: Read a word from the EEPROM at the desired
7667 *---------------------------------------------------------------------*/
7669 static USHORT FPT_utilEEReadOrg(ULONG p_port, USHORT ee_addr)
7675 ee_value = (UCHAR)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7679 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7682 ee_value |= (SEE_MS + SEE_CS);
7685 for(i = 1; i <= 16; i++) {
7687 ee_value |= SEE_CLK; /* Clock data! */
7688 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7689 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7690 ee_value &= ~SEE_CLK;
7691 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7692 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7696 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7700 ee_value &= ~(SEE_MS + SEE_CS);
7701 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7702 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7708 /*---------------------------------------------------------------------
7710 * Function: Send EE command and Address to the EEPROM
7712 * Description: Transfers the correct command and sends the address
7715 *---------------------------------------------------------------------*/
7717 static void FPT_utilEESendCmdAddr(ULONG p_port, UCHAR ee_cmd, USHORT ee_addr)
7725 narrow_flg= (UCHAR)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7729 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7731 ee_value |= SEE_CS; /* Set CS to EEPROM */
7732 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7735 for(i = 0x04; i != 0; i>>=1) {
7740 ee_value &= ~SEE_DO;
7742 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7743 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7744 ee_value |= SEE_CLK; /* Clock data! */
7745 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7746 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7747 ee_value &= ~SEE_CLK;
7748 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7749 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7765 ee_value &= ~SEE_DO;
7767 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7768 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7769 ee_value |= SEE_CLK; /* Clock data! */
7770 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7771 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7772 ee_value &= ~SEE_CLK;
7773 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7774 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7780 static USHORT FPT_CalcCrc16(UCHAR buffer[])
7785 for (i=0; i < ID_STRING_LENGTH; i++)
7787 ch = (USHORT) buffer[i];
7788 for(j=0; j < 8; j++)
7791 crc = (crc >> 1) ^ CRCMASK;
7800 static UCHAR FPT_CalcLrc(UCHAR buffer[])
7805 for(i = 0; i < ID_STRING_LENGTH; i++)
7813 The following inline definitions avoid type conflicts.
7816 static inline unsigned char
7817 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7819 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7823 static inline FlashPoint_CardHandle_T
7824 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7826 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7830 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7832 FlashPoint_ReleaseHostAdapter(CardHandle);
7837 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7839 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7844 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7846 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7850 static inline boolean
7851 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7853 return FlashPoint_InterruptPending(CardHandle);
7858 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7860 return FlashPoint_HandleInterrupt(CardHandle);
7864 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7865 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7866 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7867 #define FlashPoint_StartCCB FlashPoint__StartCCB
7868 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7869 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7870 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7873 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7877 Define prototypes for the FlashPoint SCCB Manager Functions.
7880 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7881 extern FlashPoint_CardHandle_T
7882 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7883 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7884 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7885 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7886 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7887 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7890 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */