3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
5 This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
6 Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
7 Linux compatibility. It was provided by BusLogic in the form of 16 separate
8 source files, which would have unnecessarily cluttered the scsi directory, so
9 the individual files have been combined into this single file.
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
19 #include <linux/config.h>
22 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
36 #define CRCMASK 0xA001
40 #define FAILURE 0xFFFFFFFFL
51 #define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
52 #define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
57 typedef void (*CALL_BK_FN
)(struct sccb
*);
60 typedef struct SCCBMgr_info
{
61 unsigned long si_baseaddr
;
62 unsigned char si_present
;
63 unsigned char si_intvect
;
66 unsigned short si_fw_revision
;
67 unsigned short si_per_targ_init_sync
;
68 unsigned short si_per_targ_fast_nego
;
69 unsigned short si_per_targ_ultra_nego
;
70 unsigned short si_per_targ_no_disc
;
71 unsigned short si_per_targ_wide_nego
;
72 unsigned short si_flags
;
73 unsigned char si_card_family
;
74 unsigned char si_bustype
;
75 unsigned char si_card_model
[3];
76 unsigned char si_relative_cardnum
;
77 unsigned char si_reserved
[4];
78 unsigned long si_OS_reserved
;
79 unsigned char si_XlatInfo
[4];
80 unsigned long si_reserved2
[5];
81 unsigned long si_secondary_range
;
84 typedef SCCBMGR_INFO
* PSCCBMGR_INFO
;
87 #define SCSI_PARITY_ENA 0x0001
88 #define LOW_BYTE_TERM 0x0010
89 #define HIGH_BYTE_TERM 0x0020
90 #define BUSTYPE_PCI 0x3
92 #define SUPPORT_16TAR_32LUN 0x0002
93 #define SOFT_RESET 0x0004
94 #define EXTENDED_TRANSLATION 0x0008
95 #define POST_ALL_UNDERRRUNS 0x0040
96 #define FLAG_SCAM_ENABLED 0x0080
97 #define FLAG_SCAM_LEVEL2 0x0100
102 #define HARPOON_FAMILY 0x02
106 /* SCCB struct used for both SCCB and UCB manager compiles!
107 * The UCB Manager treats the SCCB as it's 'native hardware structure'
113 unsigned char OperationCode
;
114 unsigned char ControlByte
;
115 unsigned char CdbLength
;
116 unsigned char RequestSenseLength
;
117 unsigned long DataLength
;
118 unsigned long DataPointer
;
119 unsigned char CcbRes
[2];
120 unsigned char HostStatus
;
121 unsigned char TargetStatus
;
122 unsigned char TargID
;
124 unsigned char Cdb
[12];
125 unsigned char CcbRes1
;
126 unsigned char Reserved1
;
127 unsigned long Reserved2
;
128 unsigned long SensePointer
;
131 CALL_BK_FN SccbCallback
; /* VOID (*SccbCallback)(); */
132 unsigned long SccbIOPort
; /* Identifies board base port */
133 unsigned char SccbStatus
;
134 unsigned char SCCBRes2
;
135 unsigned short SccbOSFlags
;
138 unsigned long Sccb_XferCnt
; /* actual transfer count */
139 unsigned long Sccb_ATC
;
140 unsigned long SccbVirtDataPtr
; /* virtual addr for OS/2 */
141 unsigned long Sccb_res1
;
142 unsigned short Sccb_MGRFlags
;
143 unsigned short Sccb_sgseg
;
144 unsigned char Sccb_scsimsg
; /* identify msg for selection */
145 unsigned char Sccb_tag
;
146 unsigned char Sccb_scsistat
;
147 unsigned char Sccb_idmsg
; /* image of last msg in */
148 struct sccb
* Sccb_forwardlink
;
149 struct sccb
* Sccb_backlink
;
150 unsigned long Sccb_savedATC
;
151 unsigned char Save_Cdb
[6];
152 unsigned char Save_CdbLen
;
153 unsigned char Sccb_XferState
;
154 unsigned long Sccb_SGoffset
;
162 #define SCATTER_GATHER_COMMAND 0x02
163 #define RESIDUAL_COMMAND 0x03
164 #define RESIDUAL_SG_COMMAND 0x04
165 #define RESET_COMMAND 0x81
168 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
169 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
170 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
171 #define SCCB_DATA_XFER_IN 0x08 /* Read */
174 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
177 #define BUS_FREE_ST 0
179 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
180 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
181 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
182 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
184 #define DATA_OUT_ST 7
186 #define DISCONNECT_ST 9
190 #define F_HOST_XFER_DIR 0x01
191 #define F_ALL_XFERRED 0x02
192 #define F_SG_XFER 0x04
193 #define F_AUTO_SENSE 0x08
194 #define F_ODD_BALL_CNT 0x10
195 #define F_NO_DATA_YET 0x80
198 #define F_STATUSLOADED 0x01
199 #define F_DEV_SELECTED 0x04
202 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
203 #define SCCB_DATA_UNDER_RUN 0x0C
204 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
205 #define SCCB_DATA_OVER_RUN 0x12
206 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
208 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
209 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
210 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
216 #define SCCB_IN_PROCESS 0x00
217 #define SCCB_SUCCESS 0x01
218 #define SCCB_ABORT 0x02
219 #define SCCB_ERROR 0x04
223 #define ORION_FW_REV 3110
227 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
229 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
232 #define MAX_SCSI_TAR 16
234 #define LUN_MASK 0x1f
236 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
238 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
241 #define RD_HARPOON(ioport) inb((u32)ioport)
242 #define RDW_HARPOON(ioport) inw((u32)ioport)
243 #define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
244 #define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
245 #define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
246 #define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
249 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
250 #define SYNC_TRYING BIT(6)
251 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
253 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
254 #define WIDE_ENABLED BIT(4)
255 #define WIDE_NEGOCIATED BIT(5)
257 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
258 #define TAG_Q_TRYING BIT(2)
259 #define TAG_Q_REJECT BIT(3)
261 #define TAR_ALLOW_DISC BIT(0)
264 #define EE_SYNC_MASK (BIT(0)+BIT(1))
265 #define EE_SYNC_5MB BIT(0)
266 #define EE_SYNC_10MB BIT(1)
267 #define EE_SYNC_20MB (BIT(0)+BIT(1))
269 #define EE_WIDE_SCSI BIT(7)
272 typedef struct SCCBMgr_tar_info
*PSCCBMgr_tar_info
;
275 typedef struct SCCBMgr_tar_info
{
277 struct sccb
* TarSelQ_Head
;
278 struct sccb
* TarSelQ_Tail
;
279 unsigned char TarLUN_CA
; /*Contingent Allgiance */
280 unsigned char TarTagQ_Cnt
;
281 unsigned char TarSelQ_Cnt
;
282 unsigned char TarStatus
;
283 unsigned char TarEEValue
;
284 unsigned char TarSyncCtrl
;
285 unsigned char TarReserved
[2]; /* for alignment */
286 unsigned char LunDiscQ_Idx
[MAX_LUN
];
287 unsigned char TarLUNBusy
[MAX_LUN
];
290 typedef struct NVRAMInfo
{
291 unsigned char niModel
; /* Model No. of card */
292 unsigned char niCardNo
; /* Card no. */
293 unsigned long niBaseAddr
; /* Port Address of card */
294 unsigned char niSysConf
; /* Adapter Configuration byte - Byte 16 of eeprom map */
295 unsigned char niScsiConf
; /* SCSI Configuration byte - Byte 17 of eeprom map */
296 unsigned char niScamConf
; /* SCAM Configuration byte - Byte 20 of eeprom map */
297 unsigned char niAdapId
; /* Host Adapter ID - Byte 24 of eerpom map */
298 unsigned char niSyncTbl
[MAX_SCSI_TAR
/ 2]; /* Sync/Wide byte of targets */
299 unsigned char niScamTbl
[MAX_SCSI_TAR
][4]; /* Compressed Scam name string of Targets */
302 typedef NVRAMINFO
*PNVRamInfo
;
310 typedef struct SCCBcard
{
311 struct sccb
* currentSCCB
;
312 PSCCBMGR_INFO cardInfo
;
314 unsigned long ioPort
;
316 unsigned short cmdCounter
;
317 unsigned char discQCount
;
318 unsigned char tagQ_Lst
;
319 unsigned char cardIndex
;
320 unsigned char scanIndex
;
321 unsigned char globalFlags
;
323 PNVRamInfo pNvRamInfo
;
324 struct sccb
* discQ_Tbl
[QUEUE_DEPTH
];
328 typedef struct SCCBcard
*PSCCBcard
;
331 #define F_TAG_STARTED 0x01
332 #define F_CONLUN_IO 0x02
333 #define F_DO_RENEGO 0x04
334 #define F_NO_FILTER 0x08
335 #define F_GREEN_PC 0x10
336 #define F_HOST_XFER_ACT 0x20
337 #define F_NEW_SCCB_CMD 0x40
338 #define F_UPDATE_EEPROM 0x80
341 #define ID_STRING_LENGTH 32
342 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
345 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
347 #define ASSIGN_ID 0x00
348 #define SET_P_FLAG 0x01
349 #define CFG_CMPLT 0x03
350 #define DOM_MSTR 0x0F
351 #define SYNC_PTRN 0x1F
355 #define MISC_CODE 0x14
356 #define CLR_P_FLAG 0x18
360 #define INIT_SELTD 0x01
361 #define LEVEL2_TAR 0x02
364 enum scam_id_st
{ ID0
,ID1
,ID2
,ID3
,ID4
,ID5
,ID6
,ID7
,ID8
,ID9
,ID10
,ID11
,ID12
,
365 ID13
,ID14
,ID15
,ID_UNUSED
,ID_UNASSIGNED
,ID_ASSIGNED
,LEGACY
,
366 CLR_PRIORITY
,NO_ID_AVAIL
};
368 typedef struct SCCBscam_info
{
370 unsigned char id_string
[ID_STRING_LENGTH
];
371 enum scam_id_st state
;
376 #define SCSI_REQUEST_SENSE 0x03
377 #define SCSI_READ 0x08
378 #define SCSI_WRITE 0x0A
379 #define SCSI_START_STOP_UNIT 0x1B
380 #define SCSI_READ_EXTENDED 0x28
381 #define SCSI_WRITE_EXTENDED 0x2A
382 #define SCSI_WRITE_AND_VERIFY 0x2E
388 #define SSQ_FULL 0x28
393 #define SMCMD_COMP 0x00
395 #define SMSAVE_DATA_PTR 0x02
396 #define SMREST_DATA_PTR 0x03
399 #define SMREJECT 0x07
401 #define SMPARITY 0x09
402 #define SMDEV_RESET 0x0C
403 #define SMABORT_TAG 0x0D
404 #define SMINIT_RECOVERY 0x0F
405 #define SMREL_RECOVERY 0x10
408 #define DISC_PRIV 0x40
415 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
424 #define SIX_BYTE_CMD 0x06
425 #define TWELVE_BYTE_CMD 0x0C
428 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
431 #define EEPROM_WD_CNT 256
433 #define EEPROM_CHECK_SUM 0
434 #define FW_SIGNATURE 2
435 #define MODEL_NUMB_0 4
436 #define MODEL_NUMB_2 6
437 #define MODEL_NUMB_4 8
438 #define SYSTEM_CONFIG 16
439 #define SCSI_CONFIG 17
440 #define BIOS_CONFIG 18
441 #define SCAM_CONFIG 20
442 #define ADAPTER_SCSI_ID 24
445 #define IGNORE_B_SCAN 32
446 #define SEND_START_ENA 34
447 #define DEVICE_ENABLE 36
449 #define SYNC_RATE_TBL 38
450 #define SYNC_RATE_TBL01 38
451 #define SYNC_RATE_TBL23 40
452 #define SYNC_RATE_TBL45 42
453 #define SYNC_RATE_TBL67 44
454 #define SYNC_RATE_TBL89 46
455 #define SYNC_RATE_TBLab 48
456 #define SYNC_RATE_TBLcd 50
457 #define SYNC_RATE_TBLef 52
461 #define EE_SCAMBASE 256
465 #define SCAM_ENABLED BIT(2)
466 #define SCAM_LEVEL2 BIT(3)
469 #define RENEGO_ENA BITW(10)
470 #define CONNIO_ENA BITW(11)
471 #define GREEN_PC_ENA BITW(12)
474 #define AUTO_RATE_00 00
475 #define AUTO_RATE_05 01
476 #define AUTO_RATE_10 02
477 #define AUTO_RATE_20 03
479 #define WIDE_NEGO_BIT BIT(7)
480 #define DISC_ENABLE_BIT BIT(6)
484 #define hp_vendor_id_0 0x00 /* LSB */
485 #define ORION_VEND_0 0x4B
487 #define hp_vendor_id_1 0x01 /* MSB */
488 #define ORION_VEND_1 0x10
490 #define hp_device_id_0 0x02 /* LSB */
491 #define ORION_DEV_0 0x30
493 #define hp_device_id_1 0x03 /* MSB */
494 #define ORION_DEV_1 0x81
496 /* Sub Vendor ID and Sub Device ID only available in
497 Harpoon Version 2 and higher */
499 #define hp_sub_device_id_0 0x06 /* LSB */
503 #define hp_semaphore 0x0C
504 #define SCCB_MGR_ACTIVE BIT(0)
505 #define TICKLE_ME BIT(1)
506 #define SCCB_MGR_PRESENT BIT(3)
507 #define BIOS_IN_USE BIT(4)
511 #define hp_sys_ctrl 0x0F
513 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
514 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
515 #define HALT_MACH BIT(3) /*Halt State Machine */
516 #define HARD_ABORT BIT(4) /*Hard Abort */
526 #define hp_host_blk_cnt 0x13
528 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
530 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
534 #define hp_int_mask 0x17
536 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
537 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
540 #define hp_xfer_cnt_lo 0x18
541 #define hp_xfer_cnt_hi 0x1A
542 #define hp_xfer_cmd 0x1B
544 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
545 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
548 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
550 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
552 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
554 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
555 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
557 #define hp_host_addr_lo 0x1C
558 #define hp_host_addr_hmi 0x1E
560 #define hp_ee_ctrl 0x22
562 #define EXT_ARB_ACK BIT(7)
563 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
564 #define SEE_MS BIT(5)
565 #define SEE_CS BIT(3)
566 #define SEE_CLK BIT(2)
567 #define SEE_DO BIT(1)
568 #define SEE_DI BIT(0)
571 #define EE_WRITE 0x05
573 #define EWEN_ADDR 0x03C0
575 #define EWDS_ADDR 0x0000
583 #define hp_bm_ctrl 0x26
585 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
586 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
587 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
588 #define FAST_SINGLE BIT(6) /*?? */
590 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
593 #define hp_sg_addr 0x28
594 #define hp_page_ctrl 0x29
596 #define SCATTER_EN BIT(0)
597 #define SGRAM_ARAM BIT(1)
598 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
599 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
604 #define hp_pci_stat_cfg 0x2D
606 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
615 #define hp_rev_num 0x33
618 #define hp_stack_data 0x34
619 #define hp_stack_addr 0x35
621 #define hp_ext_status 0x36
623 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
624 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
625 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
626 #define CMD_ABORTED BIT(4) /*Command aborted */
627 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
628 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
629 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
630 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
631 BM_PARITY_ERR | PIO_OVERRUN)
633 #define hp_int_status 0x37
635 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
636 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
637 #define INT_ASSERTED BIT(5) /* */
640 #define hp_fifo_cnt 0x38
645 #define hp_intena 0x40
647 #define RESET BITW(7)
648 #define PROG_HLT BITW(6)
649 #define PARITY BITW(5)
652 #define SCAM_SEL BITW(2)
654 #define TIMEOUT BITW(0)
655 #define BUS_FREE BITW(15)
656 #define XFER_CNT_0 BITW(14)
657 #define PHASE BITW(13)
658 #define IUNKWN BITW(12)
659 #define ICMD_COMP BITW(11)
660 #define ITICKLE BITW(10)
661 #define IDO_STRT BITW(9)
662 #define ITAR_DISC BITW(8)
663 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
664 #define CLR_ALL_INT 0xFFFF
665 #define CLR_ALL_INT_1 0xFF00
667 #define hp_intstat 0x42
669 #define hp_scsisig 0x44
671 #define SCSI_SEL BIT(7)
672 #define SCSI_BSY BIT(6)
673 #define SCSI_REQ BIT(5)
674 #define SCSI_ACK BIT(4)
675 #define SCSI_ATN BIT(3)
676 #define SCSI_CD BIT(2)
677 #define SCSI_MSG BIT(1)
678 #define SCSI_IOBIT BIT(0)
680 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
681 #define S_MSGO_PH (BIT(2)+BIT(1) )
682 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
683 #define S_DATAI_PH ( BIT(0))
684 #define S_DATAO_PH 0x00
685 #define S_ILL_PH ( BIT(1) )
687 #define hp_scsictrl_0 0x45
689 #define SEL_TAR BIT(6)
690 #define ENA_ATN BIT(4)
691 #define ENA_RESEL BIT(2)
692 #define SCSI_RST BIT(1)
693 #define ENA_SCAM_SEL BIT(0)
697 #define hp_portctrl_0 0x46
699 #define SCSI_PORT BIT(7)
700 #define SCSI_INBIT BIT(6)
701 #define DMA_PORT BIT(5)
702 #define DMA_RD BIT(4)
703 #define HOST_PORT BIT(3)
704 #define HOST_WRT BIT(2)
705 #define SCSI_BUS_EN BIT(1)
706 #define START_TO BIT(0)
708 #define hp_scsireset 0x47
710 #define SCSI_INI BIT(6)
711 #define SCAM_EN BIT(5)
712 #define DMA_RESET BIT(3)
713 #define HPSCSI_RESET BIT(2)
714 #define PROG_RESET BIT(1)
715 #define FIFO_CLR BIT(0)
717 #define hp_xfercnt_0 0x48
718 #define hp_xfercnt_2 0x4A
720 #define hp_fifodata_0 0x4C
721 #define hp_addstat 0x4E
723 #define SCAM_TIMER BIT(7)
724 #define SCSI_MODE8 BIT(3)
725 #define SCSI_PAR_ERR BIT(0)
727 #define hp_prgmcnt_0 0x4F
730 #define hp_selfid_0 0x50
731 #define hp_selfid_1 0x51
732 #define hp_arb_id 0x52
735 #define hp_select_id 0x53
738 #define hp_synctarg_base 0x54
739 #define hp_synctarg_12 0x54
740 #define hp_synctarg_13 0x55
741 #define hp_synctarg_14 0x56
742 #define hp_synctarg_15 0x57
744 #define hp_synctarg_8 0x58
745 #define hp_synctarg_9 0x59
746 #define hp_synctarg_10 0x5A
747 #define hp_synctarg_11 0x5B
749 #define hp_synctarg_4 0x5C
750 #define hp_synctarg_5 0x5D
751 #define hp_synctarg_6 0x5E
752 #define hp_synctarg_7 0x5F
754 #define hp_synctarg_0 0x60
755 #define hp_synctarg_1 0x61
756 #define hp_synctarg_2 0x62
757 #define hp_synctarg_3 0x63
759 #define NARROW_SCSI BIT(4)
760 #define DEFAULT_OFFSET 0x0F
762 #define hp_autostart_0 0x64
763 #define hp_autostart_1 0x65
764 #define hp_autostart_3 0x67
768 #define AUTO_IMMED BIT(5)
769 #define SELECT BIT(6)
770 #define END_DATA (BIT(7)+BIT(6))
772 #define hp_gp_reg_0 0x68
773 #define hp_gp_reg_1 0x69
774 #define hp_gp_reg_3 0x6B
776 #define hp_seltimeout 0x6C
779 #define TO_4ms 0x67 /* 3.9959ms */
781 #define TO_5ms 0x03 /* 4.9152ms */
782 #define TO_10ms 0x07 /* 11.xxxms */
783 #define TO_250ms 0x99 /* 250.68ms */
784 #define TO_290ms 0xB1 /* 289.99ms */
786 #define hp_clkctrl_0 0x6D
788 #define PWR_DWN BIT(6)
789 #define ACTdeassert BIT(4)
790 #define CLK_40MHZ (BIT(1) + BIT(0))
792 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
794 #define hp_fiforead 0x6E
795 #define hp_fifowrite 0x6F
797 #define hp_offsetctr 0x70
798 #define hp_xferstat 0x71
800 #define FIFO_EMPTY BIT(6)
802 #define hp_portctrl_1 0x72
804 #define CHK_SCSI_P BIT(3)
805 #define HOST_MODE8 BIT(0)
807 #define hp_xfer_pad 0x73
809 #define ID_UNLOCK BIT(3)
811 #define hp_scsidata_0 0x74
812 #define hp_scsidata_1 0x75
816 #define hp_aramBase 0x80
817 #define BIOS_DATA_OFFSET 0x60
818 #define BIOS_RELATIVE_CARD 0x64
823 #define AR3 (BITW(9) + BITW(8))
824 #define SDATA BITW(10)
827 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
829 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
833 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
835 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
838 #define ADATA_OUT 0x00
839 #define ADATA_IN BITW(8)
840 #define ACOMMAND BITW(10)
841 #define ASTATUS (BITW(10)+BITW(8))
842 #define AMSG_OUT (BITW(10)+BITW(9))
843 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
846 #define BRH_OP BITW(13) /* Branch */
850 #define EQUAL BITW(8)
851 #define NOT_EQ BITW(9)
853 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
856 #define FIFO_0 BITW(10)
859 #define MPM_OP BITW(15) /* Match phase and move data */
862 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
865 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
870 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
880 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
882 #define SSI_OP (BITW(15)+BITW(11))
885 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
886 #define SSI_IDO_STRT (IDO_STRT >> 8)
888 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
889 #define SSI_ITICKLE (ITICKLE >> 8)
891 #define SSI_IUNKWN (IUNKWN >> 8)
892 #define SSI_INO_CC (IUNKWN >> 8)
893 #define SSI_IRFAIL (IUNKWN >> 8)
896 #define NP 0x10 /*Next Phase */
897 #define NTCMD 0x02 /*Non- Tagged Command start */
898 #define CMDPZ 0x04 /*Command phase */
899 #define DINT 0x12 /*Data Out/In interrupt */
900 #define DI 0x13 /*Data Out */
901 #define DC 0x19 /*Disconnect Message */
902 #define ST 0x1D /*Status Phase */
903 #define UNKNWN 0x24 /*Unknown bus action */
904 #define CC 0x25 /*Command Completion failure */
905 #define TICK 0x26 /*New target reselected us. */
906 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
909 #define ID_MSG_STRT hp_aramBase + 0x00
910 #define NON_TAG_ID_MSG hp_aramBase + 0x06
911 #define CMD_STRT hp_aramBase + 0x08
912 #define SYNC_MSGS hp_aramBase + 0x08
918 #define TAG_STRT 0x00
919 #define DISCONNECT_START 0x10/2
920 #define END_DATA_START 0x14/2
921 #define CMD_ONLY_STRT CMDPZ/2
922 #define SELCHK_STRT SELCHK/2
932 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
933 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
935 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
937 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
939 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
940 WR_HARP32(port,hp_xfercnt_0,count),\
941 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
943 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
945 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
946 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
949 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
950 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
954 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
955 WR_HARPOON(port+hp_scsireset, 0x00))
957 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
958 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
960 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
961 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
963 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
964 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
966 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
967 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
972 static unsigned char FPT_sisyncn(unsigned long port
, unsigned char p_card
, unsigned char syncFlag
);
973 static void FPT_ssel(unsigned long port
, unsigned char p_card
);
974 static void FPT_sres(unsigned long port
, unsigned char p_card
, PSCCBcard pCurrCard
);
975 static void FPT_shandem(unsigned long port
, unsigned char p_card
,struct sccb
* pCurrSCCB
);
976 static void FPT_stsyncn(unsigned long port
, unsigned char p_card
);
977 static void FPT_sisyncr(unsigned long port
,unsigned char sync_pulse
, unsigned char offset
);
978 static void FPT_sssyncv(unsigned long p_port
, unsigned char p_id
, unsigned char p_sync_value
,
979 PSCCBMgr_tar_info currTar_Info
);
980 static void FPT_sresb(unsigned long port
, unsigned char p_card
);
981 static void FPT_sxfrp(unsigned long p_port
, unsigned char p_card
);
982 static void FPT_schkdd(unsigned long port
, unsigned char p_card
);
983 static unsigned char FPT_RdStack(unsigned long port
, unsigned char index
);
984 static void FPT_WrStack(unsigned long portBase
, unsigned char index
, unsigned char data
);
985 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort
);
987 static void FPT_SendMsg(unsigned long port
, unsigned char message
);
988 static void FPT_queueFlushTargSccb(unsigned char p_card
, unsigned char thisTarg
,
989 unsigned char error_code
);
991 static void FPT_sinits(struct sccb
* p_sccb
, unsigned char p_card
);
992 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo
);
994 static unsigned char FPT_siwidn(unsigned long port
, unsigned char p_card
);
995 static void FPT_stwidn(unsigned long port
, unsigned char p_card
);
996 static void FPT_siwidr(unsigned long port
, unsigned char width
);
999 static void FPT_queueSelectFail(PSCCBcard pCurrCard
, unsigned char p_card
);
1000 static void FPT_queueDisconnect(struct sccb
* p_SCCB
, unsigned char p_card
);
1001 static void FPT_queueCmdComplete(PSCCBcard pCurrCard
, struct sccb
* p_SCCB
,
1002 unsigned char p_card
);
1003 static void FPT_queueSearchSelect(PSCCBcard pCurrCard
, unsigned char p_card
);
1004 static void FPT_queueFlushSccb(unsigned char p_card
, unsigned char error_code
);
1005 static void FPT_queueAddSccb(struct sccb
* p_SCCB
, unsigned char card
);
1006 static unsigned char FPT_queueFindSccb(struct sccb
* p_SCCB
, unsigned char p_card
);
1007 static void FPT_utilUpdateResidual(struct sccb
* p_SCCB
);
1008 static unsigned short FPT_CalcCrc16(unsigned char buffer
[]);
1009 static unsigned char FPT_CalcLrc(unsigned char buffer
[]);
1012 static void FPT_Wait1Second(unsigned long p_port
);
1013 static void FPT_Wait(unsigned long p_port
, unsigned char p_delay
);
1014 static void FPT_utilEEWriteOnOff(unsigned long p_port
,unsigned char p_mode
);
1015 static void FPT_utilEEWrite(unsigned long p_port
, unsigned short ee_data
, unsigned short ee_addr
);
1016 static unsigned short FPT_utilEERead(unsigned long p_port
, unsigned short ee_addr
);
1017 static unsigned short FPT_utilEEReadOrg(unsigned long p_port
, unsigned short ee_addr
);
1018 static void FPT_utilEESendCmdAddr(unsigned long p_port
, unsigned char ee_cmd
, unsigned short ee_addr
);
1022 static void FPT_phaseDataOut(unsigned long port
, unsigned char p_card
);
1023 static void FPT_phaseDataIn(unsigned long port
, unsigned char p_card
);
1024 static void FPT_phaseCommand(unsigned long port
, unsigned char p_card
);
1025 static void FPT_phaseStatus(unsigned long port
, unsigned char p_card
);
1026 static void FPT_phaseMsgOut(unsigned long port
, unsigned char p_card
);
1027 static void FPT_phaseMsgIn(unsigned long port
, unsigned char p_card
);
1028 static void FPT_phaseIllegal(unsigned long port
, unsigned char p_card
);
1030 static void FPT_phaseDecode(unsigned long port
, unsigned char p_card
);
1031 static void FPT_phaseChkFifo(unsigned long port
, unsigned char p_card
);
1032 static void FPT_phaseBusFree(unsigned long p_port
, unsigned char p_card
);
1037 static void FPT_XbowInit(unsigned long port
, unsigned char scamFlg
);
1038 static void FPT_BusMasterInit(unsigned long p_port
);
1039 static void FPT_DiagEEPROM(unsigned long p_port
);
1044 static void FPT_dataXferProcessor(unsigned long port
, PSCCBcard pCurrCard
);
1045 static void FPT_busMstrSGDataXferStart(unsigned long port
, struct sccb
* pCurrSCCB
);
1046 static void FPT_busMstrDataXferStart(unsigned long port
, struct sccb
* pCurrSCCB
);
1047 static void FPT_hostDataXferAbort(unsigned long port
, unsigned char p_card
, struct sccb
* pCurrSCCB
);
1048 static void FPT_hostDataXferRestart(struct sccb
* currSCCB
);
1051 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port
, unsigned char p_card
,
1052 PSCCBcard pCurrCard
, unsigned short p_int
);
1054 static void FPT_SccbMgrTableInitAll(void);
1055 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard
, unsigned char p_card
);
1056 static void FPT_SccbMgrTableInitTarget(unsigned char p_card
, unsigned char target
);
1060 static void FPT_scini(unsigned char p_card
, unsigned char p_our_id
, unsigned char p_power_up
);
1062 static int FPT_scarb(unsigned long p_port
, unsigned char p_sel_type
);
1063 static void FPT_scbusf(unsigned long p_port
);
1064 static void FPT_scsel(unsigned long p_port
);
1065 static void FPT_scasid(unsigned char p_card
, unsigned long p_port
);
1066 static unsigned char FPT_scxferc(unsigned long p_port
, unsigned char p_data
);
1067 static unsigned char FPT_scsendi(unsigned long p_port
, unsigned char p_id_string
[]);
1068 static unsigned char FPT_sciso(unsigned long p_port
, unsigned char p_id_string
[]);
1069 static void FPT_scwirod(unsigned long p_port
, unsigned char p_data_bit
);
1070 static void FPT_scwiros(unsigned long p_port
, unsigned char p_data_bit
);
1071 static unsigned char FPT_scvalq(unsigned char p_quintet
);
1072 static unsigned char FPT_scsell(unsigned long p_port
, unsigned char targ_id
);
1073 static void FPT_scwtsel(unsigned long p_port
);
1074 static void FPT_inisci(unsigned char p_card
, unsigned long p_port
, unsigned char p_our_id
);
1075 static void FPT_scsavdi(unsigned char p_card
, unsigned long p_port
);
1076 static unsigned char FPT_scmachid(unsigned char p_card
, unsigned char p_id_string
[]);
1079 static void FPT_autoCmdCmplt(unsigned long p_port
, unsigned char p_card
);
1080 static void FPT_autoLoadDefaultMap(unsigned long p_port
);
1085 static SCCBMGR_TAR_INFO FPT_sccbMgrTbl
[MAX_CARDS
][MAX_SCSI_TAR
] = { { { 0 } } };
1086 static SCCBCARD FPT_BL_Card
[MAX_CARDS
] = { { 0 } };
1087 static SCCBSCAM_INFO FPT_scamInfo
[MAX_SCSI_TAR
] = { { { 0 } } };
1088 static NVRAMINFO FPT_nvRamInfo
[MAX_MB_CARDS
] = { { 0 } };
1091 static unsigned char FPT_mbCards
= 0;
1092 static unsigned char FPT_scamHAString
[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1093 ' ', 'B', 'T', '-', '9', '3', '0', \
1094 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1095 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1097 static unsigned short FPT_default_intena
= 0;
1100 static void (*FPT_s_PhaseTbl
[8]) (unsigned long, unsigned char)= { 0 };
1103 /*---------------------------------------------------------------------
1105 * Function: FlashPoint_ProbeHostAdapter
1107 * Description: Setup and/or Search for cards and return info to caller.
1109 *---------------------------------------------------------------------*/
1111 static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo
)
1113 static unsigned char first_time
= 1;
1115 unsigned char i
,j
,id
,ScamFlg
;
1116 unsigned short temp
,temp2
,temp3
,temp4
,temp5
,temp6
;
1117 unsigned long ioport
;
1118 PNVRamInfo pCurrNvRam
;
1120 ioport
= pCardInfo
->si_baseaddr
;
1123 if (RD_HARPOON(ioport
+hp_vendor_id_0
) != ORION_VEND_0
)
1124 return((int)FAILURE
);
1126 if ((RD_HARPOON(ioport
+hp_vendor_id_1
) != ORION_VEND_1
))
1127 return((int)FAILURE
);
1129 if ((RD_HARPOON(ioport
+hp_device_id_0
) != ORION_DEV_0
))
1130 return((int)FAILURE
);
1132 if ((RD_HARPOON(ioport
+hp_device_id_1
) != ORION_DEV_1
))
1133 return((int)FAILURE
);
1136 if (RD_HARPOON(ioport
+hp_rev_num
) != 0x0f){
1138 /* For new Harpoon then check for sub_device ID LSB
1139 the bits(0-3) must be all ZERO for compatible with
1140 current version of SCCBMgr, else skip this Harpoon
1143 if (RD_HARPOON(ioport
+hp_sub_device_id_0
) & 0x0f)
1144 return((int)FAILURE
);
1149 FPT_SccbMgrTableInitAll();
1154 if(FPT_RdStack(ioport
, 0) != 0x00) {
1155 if(FPT_ChkIfChipInitialized(ioport
) == 0)
1158 WR_HARPOON(ioport
+hp_semaphore
, 0x00);
1159 FPT_XbowInit(ioport
, 0); /*Must Init the SCSI before attempting */
1160 FPT_DiagEEPROM(ioport
);
1164 if(FPT_mbCards
< MAX_MB_CARDS
) {
1165 pCurrNvRam
= &FPT_nvRamInfo
[FPT_mbCards
];
1167 pCurrNvRam
->niBaseAddr
= ioport
;
1168 FPT_RNVRamData(pCurrNvRam
);
1170 return((int) FAILURE
);
1175 WR_HARPOON(ioport
+hp_clkctrl_0
, CLKCTRL_DEFAULT
);
1176 WR_HARPOON(ioport
+hp_sys_ctrl
, 0x00);
1179 pCardInfo
->si_id
= pCurrNvRam
->niAdapId
;
1181 pCardInfo
->si_id
= (unsigned char)(FPT_utilEERead(ioport
, (ADAPTER_SCSI_ID
/2)) &
1182 (unsigned char)0x0FF);
1184 pCardInfo
->si_lun
= 0x00;
1185 pCardInfo
->si_fw_revision
= ORION_FW_REV
;
1192 for (id
= 0; id
< (16/2); id
++) {
1195 temp
= (unsigned short) pCurrNvRam
->niSyncTbl
[id
];
1196 temp
= ((temp
& 0x03) + ((temp
<< 4) & 0xc0)) +
1197 (((temp
<< 4) & 0x0300) + ((temp
<< 8) & 0xc000));
1199 temp
= FPT_utilEERead(ioport
, (unsigned short)((SYNC_RATE_TBL
/2)+id
));
1201 for (i
= 0; i
< 2; temp
>>=8,i
++) {
1210 case AUTO_RATE_20
: /* Synchronous, 20 mega-transfers/second */
1211 temp6
|= 0x8000; /* Fall through */
1212 case AUTO_RATE_10
: /* Synchronous, 10 mega-transfers/second */
1213 temp5
|= 0x8000; /* Fall through */
1214 case AUTO_RATE_05
: /* Synchronous, 5 mega-transfers/second */
1215 temp2
|= 0x8000; /* Fall through */
1216 case AUTO_RATE_00
: /* Asynchronous */
1220 if (temp
& DISC_ENABLE_BIT
)
1223 if (temp
& WIDE_NEGO_BIT
)
1229 pCardInfo
->si_per_targ_init_sync
= temp2
;
1230 pCardInfo
->si_per_targ_no_disc
= temp3
;
1231 pCardInfo
->si_per_targ_wide_nego
= temp4
;
1232 pCardInfo
->si_per_targ_fast_nego
= temp5
;
1233 pCardInfo
->si_per_targ_ultra_nego
= temp6
;
1236 i
= pCurrNvRam
->niSysConf
;
1238 i
= (unsigned char)(FPT_utilEERead(ioport
, (SYSTEM_CONFIG
/2)));
1241 ScamFlg
= pCurrNvRam
->niScamConf
;
1243 ScamFlg
= (unsigned char) FPT_utilEERead(ioport
, SCAM_CONFIG
/2);
1245 pCardInfo
->si_flags
= 0x0000;
1248 pCardInfo
->si_flags
|= SCSI_PARITY_ENA
;
1251 pCardInfo
->si_flags
|= SOFT_RESET
;
1254 pCardInfo
->si_flags
|= EXTENDED_TRANSLATION
;
1256 if (ScamFlg
& SCAM_ENABLED
)
1257 pCardInfo
->si_flags
|= FLAG_SCAM_ENABLED
;
1259 if (ScamFlg
& SCAM_LEVEL2
)
1260 pCardInfo
->si_flags
|= FLAG_SCAM_LEVEL2
;
1262 j
= (RD_HARPOON(ioport
+hp_bm_ctrl
) & ~SCSI_TERM_ENA_L
);
1264 j
|= SCSI_TERM_ENA_L
;
1266 WR_HARPOON(ioport
+hp_bm_ctrl
, j
);
1268 j
= (RD_HARPOON(ioport
+hp_ee_ctrl
) & ~SCSI_TERM_ENA_H
);
1270 j
|= SCSI_TERM_ENA_H
;
1272 WR_HARPOON(ioport
+hp_ee_ctrl
, j
);
1274 if (!(RD_HARPOON(ioport
+hp_page_ctrl
) & NARROW_SCSI_CARD
))
1276 pCardInfo
->si_flags
|= SUPPORT_16TAR_32LUN
;
1278 pCardInfo
->si_card_family
= HARPOON_FAMILY
;
1279 pCardInfo
->si_bustype
= BUSTYPE_PCI
;
1282 pCardInfo
->si_card_model
[0] = '9';
1283 switch(pCurrNvRam
->niModel
& 0x0f){
1285 pCardInfo
->si_card_model
[1] = '3';
1286 pCardInfo
->si_card_model
[2] = '0';
1289 pCardInfo
->si_card_model
[1] = '5';
1290 pCardInfo
->si_card_model
[2] = '0';
1293 pCardInfo
->si_card_model
[1] = '3';
1294 pCardInfo
->si_card_model
[2] = '2';
1297 pCardInfo
->si_card_model
[1] = '5';
1298 pCardInfo
->si_card_model
[2] = '2';
1302 temp
= FPT_utilEERead(ioport
, (MODEL_NUMB_0
/2));
1303 pCardInfo
->si_card_model
[0] = (unsigned char)(temp
>> 8);
1304 temp
= FPT_utilEERead(ioport
, (MODEL_NUMB_2
/2));
1306 pCardInfo
->si_card_model
[1] = (unsigned char)(temp
& 0x00FF);
1307 pCardInfo
->si_card_model
[2] = (unsigned char)(temp
>> 8);
1310 if (pCardInfo
->si_card_model
[1] == '3')
1312 if (RD_HARPOON(ioport
+hp_ee_ctrl
) & BIT(7))
1313 pCardInfo
->si_flags
|= LOW_BYTE_TERM
;
1315 else if (pCardInfo
->si_card_model
[2] == '0')
1317 temp
= RD_HARPOON(ioport
+hp_xfer_pad
);
1318 WR_HARPOON(ioport
+hp_xfer_pad
, (temp
& ~BIT(4)));
1319 if (RD_HARPOON(ioport
+hp_ee_ctrl
) & BIT(7))
1320 pCardInfo
->si_flags
|= LOW_BYTE_TERM
;
1321 WR_HARPOON(ioport
+hp_xfer_pad
, (temp
| BIT(4)));
1322 if (RD_HARPOON(ioport
+hp_ee_ctrl
) & BIT(7))
1323 pCardInfo
->si_flags
|= HIGH_BYTE_TERM
;
1324 WR_HARPOON(ioport
+hp_xfer_pad
, temp
);
1328 temp
= RD_HARPOON(ioport
+hp_ee_ctrl
);
1329 temp2
= RD_HARPOON(ioport
+hp_xfer_pad
);
1330 WR_HARPOON(ioport
+hp_ee_ctrl
, (temp
| SEE_CS
));
1331 WR_HARPOON(ioport
+hp_xfer_pad
, (temp2
| BIT(4)));
1333 for (i
= 0; i
< 8; i
++)
1336 if (!(RD_HARPOON(ioport
+hp_ee_ctrl
) & BIT(7)))
1338 WR_HARPOON(ioport
+hp_xfer_pad
, (temp2
& ~BIT(4)));
1339 WR_HARPOON(ioport
+hp_xfer_pad
, (temp2
| BIT(4)));
1341 WR_HARPOON(ioport
+hp_ee_ctrl
, temp
);
1342 WR_HARPOON(ioport
+hp_xfer_pad
, temp2
);
1343 if (!(temp3
& BIT(7)))
1344 pCardInfo
->si_flags
|= LOW_BYTE_TERM
;
1345 if (!(temp3
& BIT(6)))
1346 pCardInfo
->si_flags
|= HIGH_BYTE_TERM
;
1350 ARAM_ACCESS(ioport
);
1352 for ( i
= 0; i
< 4; i
++ ) {
1354 pCardInfo
->si_XlatInfo
[i
] =
1355 RD_HARPOON(ioport
+hp_aramBase
+BIOS_DATA_OFFSET
+i
);
1358 /* return with -1 if no sort, else return with
1359 logical card number sorted by BIOS (zero-based) */
1361 pCardInfo
->si_relative_cardnum
=
1362 (unsigned char)(RD_HARPOON(ioport
+hp_aramBase
+BIOS_RELATIVE_CARD
)-1);
1364 SGRAM_ACCESS(ioport
);
1366 FPT_s_PhaseTbl
[0] = FPT_phaseDataOut
;
1367 FPT_s_PhaseTbl
[1] = FPT_phaseDataIn
;
1368 FPT_s_PhaseTbl
[2] = FPT_phaseIllegal
;
1369 FPT_s_PhaseTbl
[3] = FPT_phaseIllegal
;
1370 FPT_s_PhaseTbl
[4] = FPT_phaseCommand
;
1371 FPT_s_PhaseTbl
[5] = FPT_phaseStatus
;
1372 FPT_s_PhaseTbl
[6] = FPT_phaseMsgOut
;
1373 FPT_s_PhaseTbl
[7] = FPT_phaseMsgIn
;
1375 pCardInfo
->si_present
= 0x01;
1381 /*---------------------------------------------------------------------
1383 * Function: FlashPoint_HardwareResetHostAdapter
1385 * Description: Setup adapter for normal operation (hard reset).
1387 *---------------------------------------------------------------------*/
1389 static unsigned long FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo
)
1391 PSCCBcard CurrCard
= NULL
;
1392 PNVRamInfo pCurrNvRam
;
1393 unsigned char i
,j
,thisCard
, ScamFlg
;
1394 unsigned short temp
,sync_bit_map
,id
;
1395 unsigned long ioport
;
1397 ioport
= pCardInfo
->si_baseaddr
;
1399 for(thisCard
=0; thisCard
<= MAX_CARDS
; thisCard
++) {
1401 if (thisCard
== MAX_CARDS
) {
1406 if (FPT_BL_Card
[thisCard
].ioPort
== ioport
) {
1408 CurrCard
= &FPT_BL_Card
[thisCard
];
1409 FPT_SccbMgrTableInitCard(CurrCard
,thisCard
);
1413 else if (FPT_BL_Card
[thisCard
].ioPort
== 0x00) {
1415 FPT_BL_Card
[thisCard
].ioPort
= ioport
;
1416 CurrCard
= &FPT_BL_Card
[thisCard
];
1419 for(i
= 0; i
< FPT_mbCards
; i
++){
1420 if(CurrCard
->ioPort
== FPT_nvRamInfo
[i
].niBaseAddr
)
1421 CurrCard
->pNvRamInfo
= &FPT_nvRamInfo
[i
];
1423 FPT_SccbMgrTableInitCard(CurrCard
,thisCard
);
1424 CurrCard
->cardIndex
= thisCard
;
1425 CurrCard
->cardInfo
= pCardInfo
;
1431 pCurrNvRam
= CurrCard
->pNvRamInfo
;
1434 ScamFlg
= pCurrNvRam
->niScamConf
;
1437 ScamFlg
= (unsigned char) FPT_utilEERead(ioport
, SCAM_CONFIG
/2);
1441 FPT_BusMasterInit(ioport
);
1442 FPT_XbowInit(ioport
, ScamFlg
);
1444 FPT_autoLoadDefaultMap(ioport
);
1447 for (i
= 0,id
= 0x01; i
!= pCardInfo
->si_id
; i
++,id
<<= 1){}
1449 WR_HARPOON(ioport
+hp_selfid_0
, id
);
1450 WR_HARPOON(ioport
+hp_selfid_1
, 0x00);
1451 WR_HARPOON(ioport
+hp_arb_id
, pCardInfo
->si_id
);
1452 CurrCard
->ourId
= pCardInfo
->si_id
;
1454 i
= (unsigned char) pCardInfo
->si_flags
;
1455 if (i
& SCSI_PARITY_ENA
)
1456 WR_HARPOON(ioport
+hp_portctrl_1
,(HOST_MODE8
| CHK_SCSI_P
));
1458 j
= (RD_HARPOON(ioport
+hp_bm_ctrl
) & ~SCSI_TERM_ENA_L
);
1459 if (i
& LOW_BYTE_TERM
)
1460 j
|= SCSI_TERM_ENA_L
;
1461 WR_HARPOON(ioport
+hp_bm_ctrl
, j
);
1463 j
= (RD_HARPOON(ioport
+hp_ee_ctrl
) & ~SCSI_TERM_ENA_H
);
1464 if (i
& HIGH_BYTE_TERM
)
1465 j
|= SCSI_TERM_ENA_H
;
1466 WR_HARPOON(ioport
+hp_ee_ctrl
, j
);
1469 if (!(pCardInfo
->si_flags
& SOFT_RESET
)) {
1471 FPT_sresb(ioport
,thisCard
);
1473 FPT_scini(thisCard
, pCardInfo
->si_id
, 0);
1478 if (pCardInfo
->si_flags
& POST_ALL_UNDERRRUNS
)
1479 CurrCard
->globalFlags
|= F_NO_FILTER
;
1482 if(pCurrNvRam
->niSysConf
& 0x10)
1483 CurrCard
->globalFlags
|= F_GREEN_PC
;
1486 if (FPT_utilEERead(ioport
, (SYSTEM_CONFIG
/2)) & GREEN_PC_ENA
)
1487 CurrCard
->globalFlags
|= F_GREEN_PC
;
1490 /* Set global flag to indicate Re-Negotiation to be done on all
1493 if(pCurrNvRam
->niScsiConf
& 0x04)
1494 CurrCard
->globalFlags
|= F_DO_RENEGO
;
1497 if (FPT_utilEERead(ioport
, (SCSI_CONFIG
/2)) & RENEGO_ENA
)
1498 CurrCard
->globalFlags
|= F_DO_RENEGO
;
1502 if(pCurrNvRam
->niScsiConf
& 0x08)
1503 CurrCard
->globalFlags
|= F_CONLUN_IO
;
1506 if (FPT_utilEERead(ioport
, (SCSI_CONFIG
/2)) & CONNIO_ENA
)
1507 CurrCard
->globalFlags
|= F_CONLUN_IO
;
1511 temp
= pCardInfo
->si_per_targ_no_disc
;
1513 for (i
= 0,id
= 1; i
< MAX_SCSI_TAR
; i
++, id
<<= 1) {
1516 FPT_sccbMgrTbl
[thisCard
][i
].TarStatus
|= TAR_ALLOW_DISC
;
1519 sync_bit_map
= 0x0001;
1521 for (id
= 0; id
< (MAX_SCSI_TAR
/2); id
++) {
1524 temp
= (unsigned short) pCurrNvRam
->niSyncTbl
[id
];
1525 temp
= ((temp
& 0x03) + ((temp
<< 4) & 0xc0)) +
1526 (((temp
<< 4) & 0x0300) + ((temp
<< 8) & 0xc000));
1528 temp
= FPT_utilEERead(ioport
, (unsigned short)((SYNC_RATE_TBL
/2)+id
));
1530 for (i
= 0; i
< 2; temp
>>=8,i
++) {
1532 if (pCardInfo
->si_per_targ_init_sync
& sync_bit_map
) {
1534 FPT_sccbMgrTbl
[thisCard
][id
*2+i
].TarEEValue
= (unsigned char)temp
;
1538 FPT_sccbMgrTbl
[thisCard
][id
*2+i
].TarStatus
|= SYNC_SUPPORTED
;
1539 FPT_sccbMgrTbl
[thisCard
][id
*2+i
].TarEEValue
=
1540 (unsigned char)(temp
& ~EE_SYNC_MASK
);
1543 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1546 if (pCardInfo
->si_per_targ_wide_nego
& sync_bit_map
){
1548 FPT_sccbMgrTbl
[thisCard
][id
*2+i
].TarEEValue
|= EE_WIDE_SCSI
;
1552 else { /* NARROW SCSI */
1553 FPT_sccbMgrTbl
[thisCard
][id
*2+i
].TarStatus
|= WIDE_NEGOCIATED
;
1564 WR_HARPOON((ioport
+hp_semaphore
),
1565 (unsigned char)(RD_HARPOON((ioport
+hp_semaphore
)) | SCCB_MGR_PRESENT
));
1567 return((unsigned long)CurrCard
);
1570 static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard
)
1573 unsigned long portBase
;
1574 unsigned long regOffset
;
1575 unsigned long scamData
;
1576 unsigned long *pScamTbl
;
1577 PNVRamInfo pCurrNvRam
;
1579 pCurrNvRam
= ((PSCCBcard
)pCurrCard
)->pNvRamInfo
;
1582 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 0, pCurrNvRam
->niModel
);
1583 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 1, pCurrNvRam
->niSysConf
);
1584 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 2, pCurrNvRam
->niScsiConf
);
1585 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 3, pCurrNvRam
->niScamConf
);
1586 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 4, pCurrNvRam
->niAdapId
);
1588 for(i
= 0; i
< MAX_SCSI_TAR
/ 2; i
++)
1589 FPT_WrStack(pCurrNvRam
->niBaseAddr
, (unsigned char)(i
+5), pCurrNvRam
->niSyncTbl
[i
]);
1591 portBase
= pCurrNvRam
->niBaseAddr
;
1593 for(i
= 0; i
< MAX_SCSI_TAR
; i
++){
1594 regOffset
= hp_aramBase
+ 64 + i
*4;
1595 pScamTbl
= (unsigned long *) &pCurrNvRam
->niScamTbl
[i
];
1596 scamData
= *pScamTbl
;
1597 WR_HARP32(portBase
, regOffset
, scamData
);
1601 FPT_WrStack(((PSCCBcard
)pCurrCard
)->ioPort
, 0, 0);
1606 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo
)
1609 unsigned long portBase
;
1610 unsigned long regOffset
;
1611 unsigned long scamData
;
1612 unsigned long *pScamTbl
;
1614 pNvRamInfo
->niModel
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 0);
1615 pNvRamInfo
->niSysConf
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 1);
1616 pNvRamInfo
->niScsiConf
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 2);
1617 pNvRamInfo
->niScamConf
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 3);
1618 pNvRamInfo
->niAdapId
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 4);
1620 for(i
= 0; i
< MAX_SCSI_TAR
/ 2; i
++)
1621 pNvRamInfo
->niSyncTbl
[i
] = FPT_RdStack(pNvRamInfo
->niBaseAddr
, (unsigned char)(i
+5));
1623 portBase
= pNvRamInfo
->niBaseAddr
;
1625 for(i
= 0; i
< MAX_SCSI_TAR
; i
++){
1626 regOffset
= hp_aramBase
+ 64 + i
*4;
1627 RD_HARP32(portBase
, regOffset
, scamData
);
1628 pScamTbl
= (unsigned long *) &pNvRamInfo
->niScamTbl
[i
];
1629 *pScamTbl
= scamData
;
1634 static unsigned char FPT_RdStack(unsigned long portBase
, unsigned char index
)
1636 WR_HARPOON(portBase
+ hp_stack_addr
, index
);
1637 return(RD_HARPOON(portBase
+ hp_stack_data
));
1640 static void FPT_WrStack(unsigned long portBase
, unsigned char index
, unsigned char data
)
1642 WR_HARPOON(portBase
+ hp_stack_addr
, index
);
1643 WR_HARPOON(portBase
+ hp_stack_data
, data
);
1647 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort
)
1649 if((RD_HARPOON(ioPort
+ hp_arb_id
) & 0x0f) != FPT_RdStack(ioPort
, 4))
1651 if((RD_HARPOON(ioPort
+ hp_clkctrl_0
) & CLKCTRL_DEFAULT
)
1654 if((RD_HARPOON(ioPort
+ hp_seltimeout
) == TO_250ms
) ||
1655 (RD_HARPOON(ioPort
+ hp_seltimeout
) == TO_290ms
))
1660 /*---------------------------------------------------------------------
1662 * Function: FlashPoint_StartCCB
1664 * Description: Start a command pointed to by p_Sccb. When the
1665 * command is completed it will be returned via the
1666 * callback function.
1668 *---------------------------------------------------------------------*/
1669 static void FlashPoint_StartCCB(unsigned long pCurrCard
, struct sccb
* p_Sccb
)
1671 unsigned long ioport
;
1672 unsigned char thisCard
, lun
;
1673 struct sccb
* pSaveSccb
;
1674 CALL_BK_FN callback
;
1676 thisCard
= ((PSCCBcard
) pCurrCard
)->cardIndex
;
1677 ioport
= ((PSCCBcard
) pCurrCard
)->ioPort
;
1679 if((p_Sccb
->TargID
> MAX_SCSI_TAR
) || (p_Sccb
->Lun
> MAX_LUN
))
1682 p_Sccb
->HostStatus
= SCCB_COMPLETE
;
1683 p_Sccb
->SccbStatus
= SCCB_ERROR
;
1684 callback
= (CALL_BK_FN
)p_Sccb
->SccbCallback
;
1691 FPT_sinits(p_Sccb
,thisCard
);
1694 if (!((PSCCBcard
) pCurrCard
)->cmdCounter
)
1696 WR_HARPOON(ioport
+hp_semaphore
, (RD_HARPOON(ioport
+hp_semaphore
)
1697 | SCCB_MGR_ACTIVE
));
1699 if (((PSCCBcard
) pCurrCard
)->globalFlags
& F_GREEN_PC
)
1701 WR_HARPOON(ioport
+hp_clkctrl_0
, CLKCTRL_DEFAULT
);
1702 WR_HARPOON(ioport
+hp_sys_ctrl
, 0x00);
1706 ((PSCCBcard
)pCurrCard
)->cmdCounter
++;
1708 if (RD_HARPOON(ioport
+hp_semaphore
) & BIOS_IN_USE
) {
1710 WR_HARPOON(ioport
+hp_semaphore
, (RD_HARPOON(ioport
+hp_semaphore
)
1712 if(p_Sccb
->OperationCode
== RESET_COMMAND
)
1714 pSaveSccb
= ((PSCCBcard
) pCurrCard
)->currentSCCB
;
1715 ((PSCCBcard
) pCurrCard
)->currentSCCB
= p_Sccb
;
1716 FPT_queueSelectFail(&FPT_BL_Card
[thisCard
], thisCard
);
1717 ((PSCCBcard
) pCurrCard
)->currentSCCB
= pSaveSccb
;
1721 FPT_queueAddSccb(p_Sccb
,thisCard
);
1725 else if ((RD_HARPOON(ioport
+hp_page_ctrl
) & G_INT_DISABLE
)) {
1727 if(p_Sccb
->OperationCode
== RESET_COMMAND
)
1729 pSaveSccb
= ((PSCCBcard
) pCurrCard
)->currentSCCB
;
1730 ((PSCCBcard
) pCurrCard
)->currentSCCB
= p_Sccb
;
1731 FPT_queueSelectFail(&FPT_BL_Card
[thisCard
], thisCard
);
1732 ((PSCCBcard
) pCurrCard
)->currentSCCB
= pSaveSccb
;
1736 FPT_queueAddSccb(p_Sccb
,thisCard
);
1742 MDISABLE_INT(ioport
);
1744 if((((PSCCBcard
) pCurrCard
)->globalFlags
& F_CONLUN_IO
) &&
1745 ((FPT_sccbMgrTbl
[thisCard
][p_Sccb
->TargID
].TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
1749 if ((((PSCCBcard
) pCurrCard
)->currentSCCB
== NULL
) &&
1750 (FPT_sccbMgrTbl
[thisCard
][p_Sccb
->TargID
].TarSelQ_Cnt
== 0) &&
1751 (FPT_sccbMgrTbl
[thisCard
][p_Sccb
->TargID
].TarLUNBusy
[lun
]
1754 ((PSCCBcard
) pCurrCard
)->currentSCCB
= p_Sccb
;
1755 FPT_ssel(p_Sccb
->SccbIOPort
,thisCard
);
1760 if(p_Sccb
->OperationCode
== RESET_COMMAND
)
1762 pSaveSccb
= ((PSCCBcard
) pCurrCard
)->currentSCCB
;
1763 ((PSCCBcard
) pCurrCard
)->currentSCCB
= p_Sccb
;
1764 FPT_queueSelectFail(&FPT_BL_Card
[thisCard
], thisCard
);
1765 ((PSCCBcard
) pCurrCard
)->currentSCCB
= pSaveSccb
;
1769 FPT_queueAddSccb(p_Sccb
,thisCard
);
1774 MENABLE_INT(ioport
);
1780 /*---------------------------------------------------------------------
1782 * Function: FlashPoint_AbortCCB
1784 * Description: Abort the command pointed to by p_Sccb. When the
1785 * command is completed it will be returned via the
1786 * callback function.
1788 *---------------------------------------------------------------------*/
1789 static int FlashPoint_AbortCCB(unsigned long pCurrCard
, struct sccb
* p_Sccb
)
1791 unsigned long ioport
;
1793 unsigned char thisCard
;
1794 CALL_BK_FN callback
;
1796 struct sccb
* pSaveSCCB
;
1797 PSCCBMgr_tar_info currTar_Info
;
1800 ioport
= ((PSCCBcard
) pCurrCard
)->ioPort
;
1802 thisCard
= ((PSCCBcard
)pCurrCard
)->cardIndex
;
1804 if (!(RD_HARPOON(ioport
+hp_page_ctrl
) & G_INT_DISABLE
))
1807 if (FPT_queueFindSccb(p_Sccb
,thisCard
))
1810 ((PSCCBcard
)pCurrCard
)->cmdCounter
--;
1812 if (!((PSCCBcard
)pCurrCard
)->cmdCounter
)
1813 WR_HARPOON(ioport
+hp_semaphore
,(RD_HARPOON(ioport
+hp_semaphore
)
1814 & (unsigned char)(~(SCCB_MGR_ACTIVE
| TICKLE_ME
)) ));
1816 p_Sccb
->SccbStatus
= SCCB_ABORT
;
1817 callback
= p_Sccb
->SccbCallback
;
1825 if (((PSCCBcard
)pCurrCard
)->currentSCCB
== p_Sccb
)
1827 p_Sccb
->SccbStatus
= SCCB_ABORT
;
1835 TID
= p_Sccb
->TargID
;
1838 if(p_Sccb
->Sccb_tag
)
1840 MDISABLE_INT(ioport
);
1841 if (((PSCCBcard
) pCurrCard
)->discQ_Tbl
[p_Sccb
->Sccb_tag
]==p_Sccb
)
1843 p_Sccb
->SccbStatus
= SCCB_ABORT
;
1844 p_Sccb
->Sccb_scsistat
= ABORT_ST
;
1845 p_Sccb
->Sccb_scsimsg
= SMABORT_TAG
;
1847 if(((PSCCBcard
) pCurrCard
)->currentSCCB
== NULL
)
1849 ((PSCCBcard
) pCurrCard
)->currentSCCB
= p_Sccb
;
1850 FPT_ssel(ioport
, thisCard
);
1854 pSaveSCCB
= ((PSCCBcard
) pCurrCard
)->currentSCCB
;
1855 ((PSCCBcard
) pCurrCard
)->currentSCCB
= p_Sccb
;
1856 FPT_queueSelectFail((PSCCBcard
) pCurrCard
, thisCard
);
1857 ((PSCCBcard
) pCurrCard
)->currentSCCB
= pSaveSCCB
;
1860 MENABLE_INT(ioport
);
1865 currTar_Info
= &FPT_sccbMgrTbl
[thisCard
][p_Sccb
->TargID
];
1867 if(FPT_BL_Card
[thisCard
].discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[p_Sccb
->Lun
]]
1870 p_Sccb
->SccbStatus
= SCCB_ABORT
;
1881 /*---------------------------------------------------------------------
1883 * Function: FlashPoint_InterruptPending
1885 * Description: Do a quick check to determine if there is a pending
1886 * interrupt for this card and disable the IRQ Pin if so.
1888 *---------------------------------------------------------------------*/
1889 static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard
)
1891 unsigned long ioport
;
1893 ioport
= ((PSCCBcard
)pCurrCard
)->ioPort
;
1895 if (RD_HARPOON(ioport
+hp_int_status
) & INT_ASSERTED
)
1907 /*---------------------------------------------------------------------
1909 * Function: FlashPoint_HandleInterrupt
1911 * Description: This is our entry point when an interrupt is generated
1912 * by the card and the upper level driver passes it on to
1915 *---------------------------------------------------------------------*/
1916 static int FlashPoint_HandleInterrupt(unsigned long pCurrCard
)
1918 struct sccb
* currSCCB
;
1919 unsigned char thisCard
,result
,bm_status
, bm_int_st
;
1920 unsigned short hp_int
;
1921 unsigned char i
, target
;
1922 unsigned long ioport
;
1924 thisCard
= ((PSCCBcard
)pCurrCard
)->cardIndex
;
1925 ioport
= ((PSCCBcard
)pCurrCard
)->ioPort
;
1927 MDISABLE_INT(ioport
);
1929 if ((bm_int_st
=RD_HARPOON(ioport
+hp_int_status
)) & EXT_STATUS_ON
)
1930 bm_status
= RD_HARPOON(ioport
+hp_ext_status
) & (unsigned char)BAD_EXT_STATUS
;
1934 WR_HARPOON(ioport
+hp_int_mask
, (INT_CMD_COMPL
| SCSI_INTERRUPT
));
1936 while ((hp_int
= RDW_HARPOON((ioport
+hp_intstat
)) & FPT_default_intena
) |
1940 currSCCB
= ((PSCCBcard
)pCurrCard
)->currentSCCB
;
1942 if (hp_int
& (FIFO
| TIMEOUT
| RESET
| SCAM_SEL
) || bm_status
) {
1943 result
= FPT_SccbMgr_bad_isr(ioport
,thisCard
,((PSCCBcard
)pCurrCard
),hp_int
);
1944 WRW_HARPOON((ioport
+hp_intstat
), (FIFO
| TIMEOUT
| RESET
| SCAM_SEL
));
1949 MENABLE_INT(ioport
);
1955 else if (hp_int
& ICMD_COMP
) {
1957 if ( !(hp_int
& BUS_FREE
) ) {
1958 /* Wait for the BusFree before starting a new command. We
1959 must also check for being reselected since the BusFree
1960 may not show up if another device reselects us in 1.5us or
1961 less. SRR Wednesday, 3/8/1995.
1963 while (!(RDW_HARPOON((ioport
+hp_intstat
)) & (BUS_FREE
| RSEL
))) ;
1966 if (((PSCCBcard
)pCurrCard
)->globalFlags
& F_HOST_XFER_ACT
)
1968 FPT_phaseChkFifo(ioport
, thisCard
);
1970 /* WRW_HARPOON((ioport+hp_intstat),
1971 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1974 WRW_HARPOON((ioport
+hp_intstat
), CLR_ALL_INT_1
);
1976 FPT_autoCmdCmplt(ioport
,thisCard
);
1981 else if (hp_int
& ITAR_DISC
)
1984 if (((PSCCBcard
)pCurrCard
)->globalFlags
& F_HOST_XFER_ACT
) {
1986 FPT_phaseChkFifo(ioport
, thisCard
);
1990 if (RD_HARPOON(ioport
+hp_gp_reg_1
) == SMSAVE_DATA_PTR
) {
1992 WR_HARPOON(ioport
+hp_gp_reg_1
, 0x00);
1993 currSCCB
->Sccb_XferState
|= F_NO_DATA_YET
;
1995 currSCCB
->Sccb_savedATC
= currSCCB
->Sccb_ATC
;
1998 currSCCB
->Sccb_scsistat
= DISCONNECT_ST
;
1999 FPT_queueDisconnect(currSCCB
,thisCard
);
2001 /* Wait for the BusFree before starting a new command. We
2002 must also check for being reselected since the BusFree
2003 may not show up if another device reselects us in 1.5us or
2004 less. SRR Wednesday, 3/8/1995.
2006 while (!(RDW_HARPOON((ioport
+hp_intstat
)) & (BUS_FREE
| RSEL
)) &&
2007 !((RDW_HARPOON((ioport
+hp_intstat
)) & PHASE
) &&
2008 RD_HARPOON((ioport
+hp_scsisig
)) ==
2009 (SCSI_BSY
| SCSI_REQ
| SCSI_CD
| SCSI_MSG
| SCSI_IOBIT
))) ;
2012 The additional loop exit condition above detects a timing problem
2013 with the revision D/E harpoon chips. The caller should reset the
2014 host adapter to recover when 0xFE is returned.
2016 if (!(RDW_HARPOON((ioport
+hp_intstat
)) & (BUS_FREE
| RSEL
)))
2018 MENABLE_INT(ioport
);
2022 WRW_HARPOON((ioport
+hp_intstat
), (BUS_FREE
| ITAR_DISC
));
2025 ((PSCCBcard
)pCurrCard
)->globalFlags
|= F_NEW_SCCB_CMD
;
2030 else if (hp_int
& RSEL
) {
2032 WRW_HARPOON((ioport
+hp_intstat
), (PROG_HLT
| RSEL
| PHASE
| BUS_FREE
));
2034 if (RDW_HARPOON((ioport
+hp_intstat
)) & ITAR_DISC
)
2036 if (((PSCCBcard
)pCurrCard
)->globalFlags
& F_HOST_XFER_ACT
)
2038 FPT_phaseChkFifo(ioport
, thisCard
);
2041 if (RD_HARPOON(ioport
+hp_gp_reg_1
) == SMSAVE_DATA_PTR
)
2043 WR_HARPOON(ioport
+hp_gp_reg_1
, 0x00);
2044 currSCCB
->Sccb_XferState
|= F_NO_DATA_YET
;
2045 currSCCB
->Sccb_savedATC
= currSCCB
->Sccb_ATC
;
2048 WRW_HARPOON((ioport
+hp_intstat
), (BUS_FREE
| ITAR_DISC
));
2049 currSCCB
->Sccb_scsistat
= DISCONNECT_ST
;
2050 FPT_queueDisconnect(currSCCB
,thisCard
);
2053 FPT_sres(ioport
,thisCard
,((PSCCBcard
)pCurrCard
));
2054 FPT_phaseDecode(ioport
,thisCard
);
2059 else if ((hp_int
& IDO_STRT
) && (!(hp_int
& BUS_FREE
)))
2062 WRW_HARPOON((ioport
+hp_intstat
), (IDO_STRT
| XFER_CNT_0
));
2063 FPT_phaseDecode(ioport
,thisCard
);
2068 else if ( (hp_int
& IUNKWN
) || (hp_int
& PROG_HLT
) )
2070 WRW_HARPOON((ioport
+hp_intstat
), (PHASE
| IUNKWN
| PROG_HLT
));
2071 if ((RD_HARPOON(ioport
+hp_prgmcnt_0
) & (unsigned char)0x3f)< (unsigned char)SELCHK
)
2073 FPT_phaseDecode(ioport
,thisCard
);
2077 /* Harpoon problem some SCSI target device respond to selection
2078 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2079 to latch the correct Target ID into reg. x53.
2080 The work around require to correct this reg. But when write to this
2081 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2082 need to read this reg first then restore it later. After update to 0x53 */
2084 i
= (unsigned char)(RD_HARPOON(ioport
+hp_fifowrite
));
2085 target
= (unsigned char)(RD_HARPOON(ioport
+hp_gp_reg_3
));
2086 WR_HARPOON(ioport
+hp_xfer_pad
, (unsigned char) ID_UNLOCK
);
2087 WR_HARPOON(ioport
+hp_select_id
, (unsigned char)(target
| target
<<4));
2088 WR_HARPOON(ioport
+hp_xfer_pad
, (unsigned char) 0x00);
2089 WR_HARPOON(ioport
+hp_fifowrite
, i
);
2090 WR_HARPOON(ioport
+hp_autostart_3
, (AUTO_IMMED
+TAG_STRT
));
2094 else if (hp_int
& XFER_CNT_0
) {
2096 WRW_HARPOON((ioport
+hp_intstat
), XFER_CNT_0
);
2098 FPT_schkdd(ioport
,thisCard
);
2103 else if (hp_int
& BUS_FREE
) {
2105 WRW_HARPOON((ioport
+hp_intstat
), BUS_FREE
);
2107 if (((PSCCBcard
)pCurrCard
)->globalFlags
& F_HOST_XFER_ACT
) {
2109 FPT_hostDataXferAbort(ioport
,thisCard
,currSCCB
);
2112 FPT_phaseBusFree(ioport
,thisCard
);
2116 else if (hp_int
& ITICKLE
) {
2118 WRW_HARPOON((ioport
+hp_intstat
), ITICKLE
);
2119 ((PSCCBcard
)pCurrCard
)->globalFlags
|= F_NEW_SCCB_CMD
;
2124 if (((PSCCBcard
)pCurrCard
)->globalFlags
& F_NEW_SCCB_CMD
) {
2127 ((PSCCBcard
)pCurrCard
)->globalFlags
&= ~F_NEW_SCCB_CMD
;
2130 if (((PSCCBcard
)pCurrCard
)->currentSCCB
== NULL
) {
2132 FPT_queueSearchSelect(((PSCCBcard
)pCurrCard
),thisCard
);
2135 if (((PSCCBcard
)pCurrCard
)->currentSCCB
!= NULL
) {
2136 ((PSCCBcard
)pCurrCard
)->globalFlags
&= ~F_NEW_SCCB_CMD
;
2137 FPT_ssel(ioport
,thisCard
);
2146 MENABLE_INT(ioport
);
2151 /*---------------------------------------------------------------------
2153 * Function: Sccb_bad_isr
2155 * Description: Some type of interrupt has occurred which is slightly
2156 * out of the ordinary. We will now decode it fully, in
2157 * this routine. This is broken up in an attempt to save
2160 *---------------------------------------------------------------------*/
2161 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port
, unsigned char p_card
,
2162 PSCCBcard pCurrCard
, unsigned short p_int
)
2164 unsigned char temp
, ScamFlg
;
2165 PSCCBMgr_tar_info currTar_Info
;
2166 PNVRamInfo pCurrNvRam
;
2169 if (RD_HARPOON(p_port
+hp_ext_status
) &
2170 (BM_FORCE_OFF
| PCI_DEV_TMOUT
| BM_PARITY_ERR
| PIO_OVERRUN
) )
2173 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
)
2176 FPT_hostDataXferAbort(p_port
,p_card
, pCurrCard
->currentSCCB
);
2179 if (RD_HARPOON(p_port
+hp_pci_stat_cfg
) & REC_MASTER_ABORT
)
2182 WR_HARPOON(p_port
+hp_pci_stat_cfg
,
2183 (RD_HARPOON(p_port
+hp_pci_stat_cfg
) & ~REC_MASTER_ABORT
));
2185 WR_HARPOON(p_port
+hp_host_blk_cnt
, 0x00);
2189 if (pCurrCard
->currentSCCB
!= NULL
)
2192 if (!pCurrCard
->currentSCCB
->HostStatus
)
2193 pCurrCard
->currentSCCB
->HostStatus
= SCCB_BM_ERR
;
2195 FPT_sxfrp(p_port
,p_card
);
2197 temp
= (unsigned char)(RD_HARPOON(p_port
+hp_ee_ctrl
) &
2198 (EXT_ARB_ACK
| SCSI_TERM_ENA_H
));
2199 WR_HARPOON(p_port
+hp_ee_ctrl
, ((unsigned char)temp
| SEE_MS
| SEE_CS
));
2200 WR_HARPOON(p_port
+hp_ee_ctrl
, temp
);
2202 if (!(RDW_HARPOON((p_port
+hp_intstat
)) & (BUS_FREE
| RESET
)))
2204 FPT_phaseDecode(p_port
,p_card
);
2210 else if (p_int
& RESET
)
2213 WR_HARPOON(p_port
+hp_clkctrl_0
, CLKCTRL_DEFAULT
);
2214 WR_HARPOON(p_port
+hp_sys_ctrl
, 0x00);
2215 if (pCurrCard
->currentSCCB
!= NULL
) {
2217 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
)
2219 FPT_hostDataXferAbort(p_port
,p_card
, pCurrCard
->currentSCCB
);
2223 DISABLE_AUTO(p_port
);
2225 FPT_sresb(p_port
,p_card
);
2227 while(RD_HARPOON(p_port
+hp_scsictrl_0
) & SCSI_RST
) {}
2229 pCurrNvRam
= pCurrCard
->pNvRamInfo
;
2231 ScamFlg
= pCurrNvRam
->niScamConf
;
2234 ScamFlg
= (unsigned char) FPT_utilEERead(p_port
, SCAM_CONFIG
/2);
2237 FPT_XbowInit(p_port
, ScamFlg
);
2239 FPT_scini(p_card
, pCurrCard
->ourId
, 0);
2245 else if (p_int
& FIFO
) {
2247 WRW_HARPOON((p_port
+hp_intstat
), FIFO
);
2249 if (pCurrCard
->currentSCCB
!= NULL
)
2250 FPT_sxfrp(p_port
,p_card
);
2253 else if (p_int
& TIMEOUT
)
2256 DISABLE_AUTO(p_port
);
2258 WRW_HARPOON((p_port
+hp_intstat
),
2259 (PROG_HLT
| TIMEOUT
| SEL
|BUS_FREE
| PHASE
| IUNKWN
));
2261 pCurrCard
->currentSCCB
->HostStatus
= SCCB_SELECTION_TIMEOUT
;
2264 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][pCurrCard
->currentSCCB
->TargID
];
2265 if((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
2266 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
2267 currTar_Info
->TarLUNBusy
[pCurrCard
->currentSCCB
->Lun
] = 0;
2269 currTar_Info
->TarLUNBusy
[0] = 0;
2272 if (currTar_Info
->TarEEValue
& EE_SYNC_MASK
)
2274 currTar_Info
->TarSyncCtrl
= 0;
2275 currTar_Info
->TarStatus
&= ~TAR_SYNC_MASK
;
2278 if (currTar_Info
->TarEEValue
& EE_WIDE_SCSI
)
2280 currTar_Info
->TarStatus
&= ~TAR_WIDE_MASK
;
2283 FPT_sssyncv(p_port
, pCurrCard
->currentSCCB
->TargID
, NARROW_SCSI
,currTar_Info
);
2285 FPT_queueCmdComplete(pCurrCard
, pCurrCard
->currentSCCB
, p_card
);
2289 else if (p_int
& SCAM_SEL
)
2292 FPT_scarb(p_port
,LEVEL2_TAR
);
2294 FPT_scasid(p_card
, p_port
);
2298 WRW_HARPOON((p_port
+hp_intstat
), SCAM_SEL
);
2305 /*---------------------------------------------------------------------
2307 * Function: SccbMgrTableInit
2309 * Description: Initialize all Sccb manager data structures.
2311 *---------------------------------------------------------------------*/
2313 static void FPT_SccbMgrTableInitAll()
2315 unsigned char thisCard
;
2317 for (thisCard
= 0; thisCard
< MAX_CARDS
; thisCard
++)
2319 FPT_SccbMgrTableInitCard(&FPT_BL_Card
[thisCard
],thisCard
);
2321 FPT_BL_Card
[thisCard
].ioPort
= 0x00;
2322 FPT_BL_Card
[thisCard
].cardInfo
= NULL
;
2323 FPT_BL_Card
[thisCard
].cardIndex
= 0xFF;
2324 FPT_BL_Card
[thisCard
].ourId
= 0x00;
2325 FPT_BL_Card
[thisCard
].pNvRamInfo
= NULL
;
2330 /*---------------------------------------------------------------------
2332 * Function: SccbMgrTableInit
2334 * Description: Initialize all Sccb manager data structures.
2336 *---------------------------------------------------------------------*/
2338 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard
, unsigned char p_card
)
2340 unsigned char scsiID
, qtag
;
2342 for (qtag
= 0; qtag
< QUEUE_DEPTH
; qtag
++)
2344 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] = NULL
;
2347 for (scsiID
= 0; scsiID
< MAX_SCSI_TAR
; scsiID
++)
2349 FPT_sccbMgrTbl
[p_card
][scsiID
].TarStatus
= 0;
2350 FPT_sccbMgrTbl
[p_card
][scsiID
].TarEEValue
= 0;
2351 FPT_SccbMgrTableInitTarget(p_card
, scsiID
);
2354 pCurrCard
->scanIndex
= 0x00;
2355 pCurrCard
->currentSCCB
= NULL
;
2356 pCurrCard
->globalFlags
= 0x00;
2357 pCurrCard
->cmdCounter
= 0x00;
2358 pCurrCard
->tagQ_Lst
= 0x01;
2359 pCurrCard
->discQCount
= 0;
2365 /*---------------------------------------------------------------------
2367 * Function: SccbMgrTableInit
2369 * Description: Initialize all Sccb manager data structures.
2371 *---------------------------------------------------------------------*/
2373 static void FPT_SccbMgrTableInitTarget(unsigned char p_card
, unsigned char target
)
2376 unsigned char lun
, qtag
;
2377 PSCCBMgr_tar_info currTar_Info
;
2379 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][target
];
2381 currTar_Info
->TarSelQ_Cnt
= 0;
2382 currTar_Info
->TarSyncCtrl
= 0;
2384 currTar_Info
->TarSelQ_Head
= NULL
;
2385 currTar_Info
->TarSelQ_Tail
= NULL
;
2386 currTar_Info
->TarTagQ_Cnt
= 0;
2387 currTar_Info
->TarLUN_CA
= 0;
2390 for (lun
= 0; lun
< MAX_LUN
; lun
++)
2392 currTar_Info
->TarLUNBusy
[lun
] = 0;
2393 currTar_Info
->LunDiscQ_Idx
[lun
] = 0;
2396 for (qtag
= 0; qtag
< QUEUE_DEPTH
; qtag
++)
2398 if(FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] != NULL
)
2400 if(FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->TargID
== target
)
2402 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] = NULL
;
2403 FPT_BL_Card
[p_card
].discQCount
--;
2410 /*---------------------------------------------------------------------
2414 * Description: Read in a message byte from the SCSI bus, and check
2415 * for a parity error.
2417 *---------------------------------------------------------------------*/
2419 static unsigned char FPT_sfm(unsigned long port
, struct sccb
* pCurrSCCB
)
2421 unsigned char message
;
2422 unsigned short TimeOutLoop
;
2425 while( (!(RD_HARPOON(port
+hp_scsisig
) & SCSI_REQ
)) &&
2426 (TimeOutLoop
++ < 20000) ){}
2429 WR_HARPOON(port
+hp_portctrl_0
, SCSI_PORT
);
2431 message
= RD_HARPOON(port
+hp_scsidata_0
);
2433 WR_HARPOON(port
+hp_scsisig
, SCSI_ACK
+ S_MSGI_PH
);
2436 if (TimeOutLoop
> 20000)
2437 message
= 0x00; /* force message byte = 0 if Time Out on Req */
2439 if ((RDW_HARPOON((port
+hp_intstat
)) & PARITY
) &&
2440 (RD_HARPOON(port
+hp_addstat
) & SCSI_PAR_ERR
))
2442 WR_HARPOON(port
+hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
2443 WR_HARPOON(port
+hp_xferstat
, 0);
2444 WR_HARPOON(port
+hp_fiforead
, 0);
2445 WR_HARPOON(port
+hp_fifowrite
, 0);
2446 if (pCurrSCCB
!= NULL
)
2448 pCurrSCCB
->Sccb_scsimsg
= SMPARITY
;
2453 ACCEPT_MSG_ATN(port
);
2455 while( (!(RD_HARPOON(port
+hp_scsisig
) & SCSI_REQ
)) &&
2456 (TimeOutLoop
++ < 20000) ){}
2457 if (TimeOutLoop
> 20000)
2459 WRW_HARPOON((port
+hp_intstat
), PARITY
);
2462 if ((RD_HARPOON(port
+hp_scsisig
) & S_SCSI_PHZ
) != S_MSGI_PH
)
2464 WRW_HARPOON((port
+hp_intstat
), PARITY
);
2467 WR_HARPOON(port
+hp_portctrl_0
, SCSI_PORT
);
2469 RD_HARPOON(port
+hp_scsidata_0
);
2471 WR_HARPOON(port
+hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
2476 WR_HARPOON(port
+hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
2477 WR_HARPOON(port
+hp_xferstat
, 0);
2478 WR_HARPOON(port
+hp_fiforead
, 0);
2479 WR_HARPOON(port
+hp_fifowrite
, 0);
2484 /*---------------------------------------------------------------------
2486 * Function: FPT_ssel
2488 * Description: Load up automation and select target device.
2490 *---------------------------------------------------------------------*/
2492 static void FPT_ssel(unsigned long port
, unsigned char p_card
)
2495 unsigned char auto_loaded
, i
, target
, *theCCB
;
2497 unsigned long cdb_reg
;
2499 struct sccb
* currSCCB
;
2500 PSCCBMgr_tar_info currTar_Info
;
2501 unsigned char lastTag
, lun
;
2503 CurrCard
= &FPT_BL_Card
[p_card
];
2504 currSCCB
= CurrCard
->currentSCCB
;
2505 target
= currSCCB
->TargID
;
2506 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][target
];
2507 lastTag
= CurrCard
->tagQ_Lst
;
2512 if ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) == TAG_Q_REJECT
)
2513 currSCCB
->ControlByte
&= ~F_USE_CMD_Q
;
2515 if(((CurrCard
->globalFlags
& F_CONLUN_IO
) &&
2516 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
)))
2518 lun
= currSCCB
->Lun
;
2523 if (CurrCard
->globalFlags
& F_TAG_STARTED
)
2525 if (!(currSCCB
->ControlByte
& F_USE_CMD_Q
))
2527 if ((currTar_Info
->TarLUN_CA
== 0)
2528 && ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
)
2532 if (currTar_Info
->TarTagQ_Cnt
!=0)
2534 currTar_Info
->TarLUNBusy
[lun
] = 1;
2535 FPT_queueSelectFail(CurrCard
,p_card
);
2541 currTar_Info
->TarLUNBusy
[lun
] = 1;
2544 } /*End non-tagged */
2547 currTar_Info
->TarLUNBusy
[lun
] = 1;
2550 } /*!Use cmd Q Tagged */
2553 if (currTar_Info
->TarLUN_CA
== 1)
2555 FPT_queueSelectFail(CurrCard
,p_card
);
2560 currTar_Info
->TarLUNBusy
[lun
] = 1;
2562 } /*else use cmd Q tagged */
2564 } /*if glob tagged started */
2567 currTar_Info
->TarLUNBusy
[lun
] = 1;
2572 if((((CurrCard
->globalFlags
& F_CONLUN_IO
) &&
2573 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
2574 || (!(currSCCB
->ControlByte
& F_USE_CMD_Q
))))
2576 if(CurrCard
->discQCount
>= QUEUE_DEPTH
)
2578 currTar_Info
->TarLUNBusy
[lun
] = 1;
2579 FPT_queueSelectFail(CurrCard
,p_card
);
2583 for (i
= 1; i
< QUEUE_DEPTH
; i
++)
2585 if (++lastTag
>= QUEUE_DEPTH
) lastTag
= 1;
2586 if (CurrCard
->discQ_Tbl
[lastTag
] == NULL
)
2588 CurrCard
->tagQ_Lst
= lastTag
;
2589 currTar_Info
->LunDiscQ_Idx
[lun
] = lastTag
;
2590 CurrCard
->discQ_Tbl
[lastTag
] = currSCCB
;
2591 CurrCard
->discQCount
++;
2595 if(i
== QUEUE_DEPTH
)
2597 currTar_Info
->TarLUNBusy
[lun
] = 1;
2598 FPT_queueSelectFail(CurrCard
,p_card
);
2608 WR_HARPOON(port
+hp_select_id
, target
);
2609 WR_HARPOON(port
+hp_gp_reg_3
, target
); /* Use by new automation logic */
2611 if (currSCCB
->OperationCode
== RESET_COMMAND
) {
2612 WRW_HARPOON((port
+ID_MSG_STRT
), (MPM_OP
+AMSG_OUT
+
2613 (currSCCB
->Sccb_idmsg
& ~DISC_PRIV
)));
2615 WRW_HARPOON((port
+ID_MSG_STRT
+2),BRH_OP
+ALWAYS
+NP
);
2617 currSCCB
->Sccb_scsimsg
= SMDEV_RESET
;
2619 WR_HARPOON(port
+hp_autostart_3
, (SELECT
+SELCHK_STRT
));
2621 currSCCB
->Sccb_scsistat
= SELECT_BDR_ST
;
2623 if (currTar_Info
->TarEEValue
& EE_SYNC_MASK
)
2625 currTar_Info
->TarSyncCtrl
= 0;
2626 currTar_Info
->TarStatus
&= ~TAR_SYNC_MASK
;
2629 if (currTar_Info
->TarEEValue
& EE_WIDE_SCSI
)
2631 currTar_Info
->TarStatus
&= ~TAR_WIDE_MASK
;
2634 FPT_sssyncv(port
, target
, NARROW_SCSI
,currTar_Info
);
2635 FPT_SccbMgrTableInitTarget(p_card
, target
);
2639 else if(currSCCB
->Sccb_scsistat
== ABORT_ST
)
2641 WRW_HARPOON((port
+ID_MSG_STRT
), (MPM_OP
+AMSG_OUT
+
2642 (currSCCB
->Sccb_idmsg
& ~DISC_PRIV
)));
2644 WRW_HARPOON((port
+ID_MSG_STRT
+2),BRH_OP
+ALWAYS
+CMDPZ
);
2646 WRW_HARPOON((port
+SYNC_MSGS
+0), (MPM_OP
+AMSG_OUT
+
2647 (((unsigned char)(currSCCB
->ControlByte
& TAG_TYPE_MASK
)
2648 >> 6) | (unsigned char)0x20)));
2649 WRW_HARPOON((port
+SYNC_MSGS
+2),
2650 (MPM_OP
+AMSG_OUT
+currSCCB
->Sccb_tag
));
2651 WRW_HARPOON((port
+SYNC_MSGS
+4), (BRH_OP
+ALWAYS
+NP
));
2653 WR_HARPOON(port
+hp_autostart_3
, (SELECT
+SELCHK_STRT
));
2658 else if (!(currTar_Info
->TarStatus
& WIDE_NEGOCIATED
)) {
2659 auto_loaded
= FPT_siwidn(port
,p_card
);
2660 currSCCB
->Sccb_scsistat
= SELECT_WN_ST
;
2663 else if (!((currTar_Info
->TarStatus
& TAR_SYNC_MASK
)
2664 == SYNC_SUPPORTED
)) {
2665 auto_loaded
= FPT_sisyncn(port
,p_card
, 0);
2666 currSCCB
->Sccb_scsistat
= SELECT_SN_ST
;
2673 if (currSCCB
->ControlByte
& F_USE_CMD_Q
)
2676 CurrCard
->globalFlags
|= F_TAG_STARTED
;
2678 if ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
)
2681 currSCCB
->ControlByte
&= ~F_USE_CMD_Q
;
2683 /* Fix up the start instruction with a jump to
2684 Non-Tag-CMD handling */
2685 WRW_HARPOON((port
+ID_MSG_STRT
),BRH_OP
+ALWAYS
+NTCMD
);
2687 WRW_HARPOON((port
+NON_TAG_ID_MSG
),
2688 (MPM_OP
+AMSG_OUT
+currSCCB
->Sccb_idmsg
));
2690 WR_HARPOON(port
+hp_autostart_3
, (SELECT
+SELCHK_STRT
));
2692 /* Setup our STATE so we know what happend when
2693 the wheels fall off. */
2694 currSCCB
->Sccb_scsistat
= SELECT_ST
;
2696 currTar_Info
->TarLUNBusy
[lun
] = 1;
2701 WRW_HARPOON((port
+ID_MSG_STRT
), (MPM_OP
+AMSG_OUT
+currSCCB
->Sccb_idmsg
));
2703 WRW_HARPOON((port
+ID_MSG_STRT
+2), (MPM_OP
+AMSG_OUT
+
2704 (((unsigned char)(currSCCB
->ControlByte
& TAG_TYPE_MASK
)
2705 >> 6) | (unsigned char)0x20)));
2707 for (i
= 1; i
< QUEUE_DEPTH
; i
++)
2709 if (++lastTag
>= QUEUE_DEPTH
) lastTag
= 1;
2710 if (CurrCard
->discQ_Tbl
[lastTag
] == NULL
)
2712 WRW_HARPOON((port
+ID_MSG_STRT
+6),
2713 (MPM_OP
+AMSG_OUT
+lastTag
));
2714 CurrCard
->tagQ_Lst
= lastTag
;
2715 currSCCB
->Sccb_tag
= lastTag
;
2716 CurrCard
->discQ_Tbl
[lastTag
] = currSCCB
;
2717 CurrCard
->discQCount
++;
2723 if ( i
== QUEUE_DEPTH
)
2725 currTar_Info
->TarLUNBusy
[lun
] = 1;
2726 FPT_queueSelectFail(CurrCard
,p_card
);
2731 currSCCB
->Sccb_scsistat
= SELECT_Q_ST
;
2733 WR_HARPOON(port
+hp_autostart_3
, (SELECT
+SELCHK_STRT
));
2740 WRW_HARPOON((port
+ID_MSG_STRT
),BRH_OP
+ALWAYS
+NTCMD
);
2742 WRW_HARPOON((port
+NON_TAG_ID_MSG
),
2743 (MPM_OP
+AMSG_OUT
+currSCCB
->Sccb_idmsg
));
2745 currSCCB
->Sccb_scsistat
= SELECT_ST
;
2747 WR_HARPOON(port
+hp_autostart_3
, (SELECT
+SELCHK_STRT
));
2751 theCCB
= (unsigned char *)&currSCCB
->Cdb
[0];
2753 cdb_reg
= port
+ CMD_STRT
;
2755 for (i
=0; i
< currSCCB
->CdbLength
; i
++)
2757 WRW_HARPOON(cdb_reg
, (MPM_OP
+ ACOMMAND
+ *theCCB
));
2762 if (currSCCB
->CdbLength
!= TWELVE_BYTE_CMD
)
2763 WRW_HARPOON(cdb_reg
, (BRH_OP
+ALWAYS
+ NP
));
2767 WRW_HARPOON((port
+hp_fiforead
), (unsigned short) 0x00);
2768 WR_HARPOON(port
+hp_xferstat
, 0x00);
2770 WRW_HARPOON((port
+hp_intstat
), (PROG_HLT
| TIMEOUT
| SEL
| BUS_FREE
));
2772 WR_HARPOON(port
+hp_portctrl_0
,(SCSI_PORT
));
2775 if (!(currSCCB
->Sccb_MGRFlags
& F_DEV_SELECTED
))
2777 WR_HARPOON(port
+hp_scsictrl_0
, (SEL_TAR
| ENA_ATN
| ENA_RESEL
| ENA_SCAM_SEL
));
2782 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2783 auto_loaded |= AUTO_IMMED; */
2784 auto_loaded
= AUTO_IMMED
;
2788 WR_HARPOON(port
+hp_autostart_3
, auto_loaded
);
2795 /*---------------------------------------------------------------------
2797 * Function: FPT_sres
2799 * Description: Hookup the correct CCB and handle the incoming messages.
2801 *---------------------------------------------------------------------*/
2803 static void FPT_sres(unsigned long port
, unsigned char p_card
, PSCCBcard pCurrCard
)
2806 unsigned char our_target
, message
, lun
= 0, tag
, msgRetryCount
;
2809 PSCCBMgr_tar_info currTar_Info
;
2810 struct sccb
* currSCCB
;
2815 if(pCurrCard
->currentSCCB
!= NULL
)
2817 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][pCurrCard
->currentSCCB
->TargID
];
2821 WR_HARPOON((port
+hp_scsictrl_0
),(ENA_RESEL
| ENA_SCAM_SEL
));
2824 currSCCB
= pCurrCard
->currentSCCB
;
2825 if(currSCCB
->Sccb_scsistat
== SELECT_WN_ST
)
2827 currTar_Info
->TarStatus
&= ~TAR_WIDE_MASK
;
2828 currSCCB
->Sccb_scsistat
= BUS_FREE_ST
;
2830 if(currSCCB
->Sccb_scsistat
== SELECT_SN_ST
)
2832 currTar_Info
->TarStatus
&= ~TAR_SYNC_MASK
;
2833 currSCCB
->Sccb_scsistat
= BUS_FREE_ST
;
2835 if(((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
2836 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
)))
2838 currTar_Info
->TarLUNBusy
[currSCCB
->Lun
] = 0;
2839 if(currSCCB
->Sccb_scsistat
!= ABORT_ST
)
2841 pCurrCard
->discQCount
--;
2842 pCurrCard
->discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[currSCCB
->Lun
]]
2848 currTar_Info
->TarLUNBusy
[0] = 0;
2849 if(currSCCB
->Sccb_tag
)
2851 if(currSCCB
->Sccb_scsistat
!= ABORT_ST
)
2853 pCurrCard
->discQCount
--;
2854 pCurrCard
->discQ_Tbl
[currSCCB
->Sccb_tag
] = NULL
;
2858 if(currSCCB
->Sccb_scsistat
!= ABORT_ST
)
2860 pCurrCard
->discQCount
--;
2861 pCurrCard
->discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[0]] = NULL
;
2866 FPT_queueSelectFail(&FPT_BL_Card
[p_card
],p_card
);
2869 WRW_HARPOON((port
+hp_fiforead
), (unsigned short) 0x00);
2872 our_target
= (unsigned char)(RD_HARPOON(port
+hp_select_id
) >> 4);
2873 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][our_target
];
2880 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][our_target
];
2884 while(!(RD_HARPOON(port
+hp_scsisig
) & SCSI_REQ
))
2886 if (! (RD_HARPOON(port
+hp_scsisig
) & SCSI_BSY
))
2889 WRW_HARPOON((port
+hp_intstat
), PHASE
);
2894 WRW_HARPOON((port
+hp_intstat
), PHASE
);
2895 if ((RD_HARPOON(port
+hp_scsisig
) & S_SCSI_PHZ
) == S_MSGI_PH
)
2898 message
= FPT_sfm(port
,pCurrCard
->currentSCCB
);
2902 if (message
<= (0x80 | LUN_MASK
))
2904 lun
= message
& (unsigned char)LUN_MASK
;
2906 if ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) == TAG_Q_TRYING
)
2908 if (currTar_Info
->TarTagQ_Cnt
!= 0)
2911 if (!(currTar_Info
->TarLUN_CA
))
2913 ACCEPT_MSG(port
); /*Release the ACK for ID msg. */
2916 message
= FPT_sfm(port
,pCurrCard
->currentSCCB
);
2927 tag
= FPT_sfm(port
,pCurrCard
->currentSCCB
);
2935 } /*End Q cnt != 0 */
2937 } /*End Tag cmds supported! */
2939 } /*End valid ID message. */
2944 ACCEPT_MSG_ATN(port
);
2947 } /* End good id message. */
2957 ACCEPT_MSG_ATN(port
);
2959 while (!(RDW_HARPOON((port
+hp_intstat
)) & (PHASE
| RESET
)) &&
2960 !(RD_HARPOON(port
+hp_scsisig
) & SCSI_REQ
) &&
2961 (RD_HARPOON(port
+hp_scsisig
) & SCSI_BSY
)) ;
2969 if(msgRetryCount
== 1)
2971 FPT_SendMsg(port
, SMPARITY
);
2975 FPT_SendMsg(port
, SMDEV_RESET
);
2977 FPT_sssyncv(port
, our_target
, NARROW_SCSI
,currTar_Info
);
2979 if (FPT_sccbMgrTbl
[p_card
][our_target
].TarEEValue
& EE_SYNC_MASK
)
2982 FPT_sccbMgrTbl
[p_card
][our_target
].TarStatus
&= ~TAR_SYNC_MASK
;
2986 if (FPT_sccbMgrTbl
[p_card
][our_target
].TarEEValue
& EE_WIDE_SCSI
)
2989 FPT_sccbMgrTbl
[p_card
][our_target
].TarStatus
&= ~TAR_WIDE_MASK
;
2993 FPT_queueFlushTargSccb(p_card
, our_target
, SCCB_COMPLETE
);
2994 FPT_SccbMgrTableInitTarget(p_card
,our_target
);
2998 }while(message
== 0);
3002 if(((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
3003 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
)))
3005 currTar_Info
->TarLUNBusy
[lun
] = 1;
3006 pCurrCard
->currentSCCB
= pCurrCard
->discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[lun
]];
3007 if(pCurrCard
->currentSCCB
!= NULL
)
3013 ACCEPT_MSG_ATN(port
);
3018 currTar_Info
->TarLUNBusy
[0] = 1;
3023 if (pCurrCard
->discQ_Tbl
[tag
] != NULL
)
3025 pCurrCard
->currentSCCB
= pCurrCard
->discQ_Tbl
[tag
];
3026 currTar_Info
->TarTagQ_Cnt
--;
3031 ACCEPT_MSG_ATN(port
);
3035 pCurrCard
->currentSCCB
= pCurrCard
->discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[0]];
3036 if(pCurrCard
->currentSCCB
!= NULL
)
3042 ACCEPT_MSG_ATN(port
);
3047 if(pCurrCard
->currentSCCB
!= NULL
)
3049 if(pCurrCard
->currentSCCB
->Sccb_scsistat
== ABORT_ST
)
3051 /* During Abort Tag command, the target could have got re-selected
3052 and completed the command. Check the select Q and remove the CCB
3053 if it is in the Select Q */
3054 FPT_queueFindSccb(pCurrCard
->currentSCCB
, p_card
);
3059 while (!(RDW_HARPOON((port
+hp_intstat
)) & (PHASE
| RESET
)) &&
3060 !(RD_HARPOON(port
+hp_scsisig
) & SCSI_REQ
) &&
3061 (RD_HARPOON(port
+hp_scsisig
) & SCSI_BSY
)) ;
3064 static void FPT_SendMsg(unsigned long port
, unsigned char message
)
3066 while(!(RD_HARPOON(port
+hp_scsisig
) & SCSI_REQ
))
3068 if (! (RD_HARPOON(port
+hp_scsisig
) & SCSI_BSY
))
3071 WRW_HARPOON((port
+hp_intstat
), PHASE
);
3076 WRW_HARPOON((port
+hp_intstat
), PHASE
);
3077 if ((RD_HARPOON(port
+hp_scsisig
) & S_SCSI_PHZ
) == S_MSGO_PH
)
3079 WRW_HARPOON((port
+hp_intstat
), (BUS_FREE
| PHASE
| XFER_CNT_0
));
3082 WR_HARPOON(port
+hp_portctrl_0
, SCSI_BUS_EN
);
3084 WR_HARPOON(port
+hp_scsidata_0
,message
);
3086 WR_HARPOON(port
+hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
3090 WR_HARPOON(port
+hp_portctrl_0
, 0x00);
3092 if ((message
== SMABORT
) || (message
== SMDEV_RESET
) ||
3093 (message
== SMABORT_TAG
) )
3095 while(!(RDW_HARPOON((port
+hp_intstat
)) & (BUS_FREE
| PHASE
))) {}
3097 if (RDW_HARPOON((port
+hp_intstat
)) & BUS_FREE
)
3099 WRW_HARPOON((port
+hp_intstat
), BUS_FREE
);
3105 /*---------------------------------------------------------------------
3107 * Function: FPT_sdecm
3109 * Description: Determine the proper responce to the message from the
3112 *---------------------------------------------------------------------*/
3113 static void FPT_sdecm(unsigned char message
, unsigned long port
, unsigned char p_card
)
3115 struct sccb
* currSCCB
;
3117 PSCCBMgr_tar_info currTar_Info
;
3119 CurrCard
= &FPT_BL_Card
[p_card
];
3120 currSCCB
= CurrCard
->currentSCCB
;
3122 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3124 if (message
== SMREST_DATA_PTR
)
3126 if (!(currSCCB
->Sccb_XferState
& F_NO_DATA_YET
))
3128 currSCCB
->Sccb_ATC
= currSCCB
->Sccb_savedATC
;
3130 FPT_hostDataXferRestart(currSCCB
);
3134 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3137 else if (message
== SMCMD_COMP
)
3141 if (currSCCB
->Sccb_scsistat
== SELECT_Q_ST
)
3143 currTar_Info
->TarStatus
&= ~(unsigned char)TAR_TAG_Q_MASK
;
3144 currTar_Info
->TarStatus
|= (unsigned char)TAG_Q_REJECT
;
3151 else if ((message
== SMNO_OP
) || (message
>= SMIDENT
)
3152 || (message
== SMINIT_RECOVERY
) || (message
== SMREL_RECOVERY
))
3156 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3159 else if (message
== SMREJECT
)
3162 if ((currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) ||
3163 (currSCCB
->Sccb_scsistat
== SELECT_WN_ST
) ||
3164 ((currTar_Info
->TarStatus
& TAR_SYNC_MASK
) == SYNC_TRYING
) ||
3165 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) == TAG_Q_TRYING
) )
3168 WRW_HARPOON((port
+hp_intstat
), BUS_FREE
);
3173 while ((!(RD_HARPOON(port
+hp_scsisig
) & SCSI_REQ
)) &&
3174 (!(RDW_HARPOON((port
+hp_intstat
)) & BUS_FREE
))) {}
3176 if(currSCCB
->Lun
== 0x00)
3178 if ((currSCCB
->Sccb_scsistat
== SELECT_SN_ST
))
3181 currTar_Info
->TarStatus
|= (unsigned char)SYNC_SUPPORTED
;
3183 currTar_Info
->TarEEValue
&= ~EE_SYNC_MASK
;
3186 else if ((currSCCB
->Sccb_scsistat
== SELECT_WN_ST
))
3190 currTar_Info
->TarStatus
= (currTar_Info
->TarStatus
&
3191 ~WIDE_ENABLED
) | WIDE_NEGOCIATED
;
3193 currTar_Info
->TarEEValue
&= ~EE_WIDE_SCSI
;
3197 else if ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) == TAG_Q_TRYING
)
3199 currTar_Info
->TarStatus
= (currTar_Info
->TarStatus
&
3200 ~(unsigned char)TAR_TAG_Q_MASK
) | TAG_Q_REJECT
;
3203 currSCCB
->ControlByte
&= ~F_USE_CMD_Q
;
3204 CurrCard
->discQCount
--;
3205 CurrCard
->discQ_Tbl
[currSCCB
->Sccb_tag
] = NULL
;
3206 currSCCB
->Sccb_tag
= 0x00;
3211 if (RDW_HARPOON((port
+hp_intstat
)) & BUS_FREE
)
3215 if(currSCCB
->Lun
== 0x00)
3217 WRW_HARPOON((port
+hp_intstat
), BUS_FREE
);
3218 CurrCard
->globalFlags
|= F_NEW_SCCB_CMD
;
3225 if((CurrCard
->globalFlags
& F_CONLUN_IO
) &&
3226 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
3227 currTar_Info
->TarLUNBusy
[currSCCB
->Lun
] = 1;
3229 currTar_Info
->TarLUNBusy
[0] = 1;
3232 currSCCB
->ControlByte
&= ~(unsigned char)F_USE_CMD_Q
;
3234 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3243 while ((!(RD_HARPOON(port
+hp_scsisig
) & SCSI_REQ
)) &&
3244 (!(RDW_HARPOON((port
+hp_intstat
)) & BUS_FREE
))) {}
3246 if (!(RDW_HARPOON((port
+hp_intstat
)) & BUS_FREE
))
3248 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3253 else if (message
== SMEXT
)
3257 FPT_shandem(port
,p_card
,currSCCB
);
3260 else if (message
== SMIGNORWR
)
3263 ACCEPT_MSG(port
); /* ACK the RESIDUE MSG */
3265 message
= FPT_sfm(port
,currSCCB
);
3267 if(currSCCB
->Sccb_scsimsg
!= SMPARITY
)
3269 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3276 currSCCB
->HostStatus
= SCCB_PHASE_SEQUENCE_FAIL
;
3277 currSCCB
->Sccb_scsimsg
= SMREJECT
;
3279 ACCEPT_MSG_ATN(port
);
3280 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3285 /*---------------------------------------------------------------------
3287 * Function: FPT_shandem
3289 * Description: Decide what to do with the extended message.
3291 *---------------------------------------------------------------------*/
3292 static void FPT_shandem(unsigned long port
, unsigned char p_card
, struct sccb
* pCurrSCCB
)
3294 unsigned char length
,message
;
3296 length
= FPT_sfm(port
,pCurrSCCB
);
3301 message
= FPT_sfm(port
,pCurrSCCB
);
3305 if (message
== SMSYNC
)
3312 FPT_stsyncn(port
,p_card
);
3317 pCurrSCCB
->Sccb_scsimsg
= SMREJECT
;
3318 ACCEPT_MSG_ATN(port
);
3321 else if (message
== SMWDTR
)
3328 FPT_stwidn(port
,p_card
);
3333 pCurrSCCB
->Sccb_scsimsg
= SMREJECT
;
3334 ACCEPT_MSG_ATN(port
);
3336 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3342 pCurrSCCB
->Sccb_scsimsg
= SMREJECT
;
3343 ACCEPT_MSG_ATN(port
);
3345 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3350 if(pCurrSCCB
->Sccb_scsimsg
!= SMPARITY
)
3352 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3356 if(pCurrSCCB
->Sccb_scsimsg
== SMPARITY
)
3357 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3362 /*---------------------------------------------------------------------
3364 * Function: FPT_sisyncn
3366 * Description: Read in a message byte from the SCSI bus, and check
3367 * for a parity error.
3369 *---------------------------------------------------------------------*/
3371 static unsigned char FPT_sisyncn(unsigned long port
, unsigned char p_card
, unsigned char syncFlag
)
3373 struct sccb
* currSCCB
;
3374 PSCCBMgr_tar_info currTar_Info
;
3376 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3377 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3379 if (!((currTar_Info
->TarStatus
& TAR_SYNC_MASK
) == SYNC_TRYING
)) {
3382 WRW_HARPOON((port
+ID_MSG_STRT
),
3383 (MPM_OP
+AMSG_OUT
+(currSCCB
->Sccb_idmsg
& ~(unsigned char)DISC_PRIV
)));
3385 WRW_HARPOON((port
+ID_MSG_STRT
+2),BRH_OP
+ALWAYS
+CMDPZ
);
3387 WRW_HARPOON((port
+SYNC_MSGS
+0), (MPM_OP
+AMSG_OUT
+SMEXT
));
3388 WRW_HARPOON((port
+SYNC_MSGS
+2), (MPM_OP
+AMSG_OUT
+0x03 ));
3389 WRW_HARPOON((port
+SYNC_MSGS
+4), (MPM_OP
+AMSG_OUT
+SMSYNC
));
3392 if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_20MB
)
3394 WRW_HARPOON((port
+SYNC_MSGS
+6), (MPM_OP
+AMSG_OUT
+ 12));
3396 else if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_10MB
)
3398 WRW_HARPOON((port
+SYNC_MSGS
+6), (MPM_OP
+AMSG_OUT
+ 25));
3400 else if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_5MB
)
3402 WRW_HARPOON((port
+SYNC_MSGS
+6), (MPM_OP
+AMSG_OUT
+ 50));
3405 WRW_HARPOON((port
+SYNC_MSGS
+6), (MPM_OP
+AMSG_OUT
+ 00));
3408 WRW_HARPOON((port
+SYNC_MSGS
+8), (RAT_OP
));
3409 WRW_HARPOON((port
+SYNC_MSGS
+10),(MPM_OP
+AMSG_OUT
+DEFAULT_OFFSET
));
3410 WRW_HARPOON((port
+SYNC_MSGS
+12),(BRH_OP
+ALWAYS
+NP
));
3415 WR_HARPOON(port
+hp_autostart_3
, (SELECT
+SELCHK_STRT
));
3416 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3417 ~(unsigned char)TAR_SYNC_MASK
) | (unsigned char)SYNC_TRYING
);
3421 WR_HARPOON(port
+hp_autostart_3
, (AUTO_IMMED
+ CMD_ONLY_STRT
));
3430 currTar_Info
->TarStatus
|= (unsigned char)SYNC_SUPPORTED
;
3431 currTar_Info
->TarEEValue
&= ~EE_SYNC_MASK
;
3438 /*---------------------------------------------------------------------
3440 * Function: FPT_stsyncn
3442 * Description: The has sent us a Sync Nego message so handle it as
3445 *---------------------------------------------------------------------*/
3446 static void FPT_stsyncn(unsigned long port
, unsigned char p_card
)
3448 unsigned char sync_msg
,offset
,sync_reg
,our_sync_msg
;
3449 struct sccb
* currSCCB
;
3450 PSCCBMgr_tar_info currTar_Info
;
3452 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3453 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3455 sync_msg
= FPT_sfm(port
,currSCCB
);
3457 if((sync_msg
== 0x00) && (currSCCB
->Sccb_scsimsg
== SMPARITY
))
3459 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3466 offset
= FPT_sfm(port
,currSCCB
);
3468 if((offset
== 0x00) && (currSCCB
->Sccb_scsimsg
== SMPARITY
))
3470 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3474 if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_20MB
)
3476 our_sync_msg
= 12; /* Setup our Message to 20mb/s */
3478 else if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_10MB
)
3480 our_sync_msg
= 25; /* Setup our Message to 10mb/s */
3482 else if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_5MB
)
3484 our_sync_msg
= 50; /* Setup our Message to 5mb/s */
3487 our_sync_msg
= 0; /* Message = Async */
3489 if (sync_msg
< our_sync_msg
) {
3490 sync_msg
= our_sync_msg
; /*if faster, then set to max. */
3493 if (offset
== ASYNC
)
3496 if (offset
> MAX_OFFSET
)
3497 offset
= MAX_OFFSET
;
3503 sync_reg
= 0x20; /* Use 10MB/s */
3507 sync_reg
= 0x40; /* Use 6.6MB/s */
3511 sync_reg
= 0x60; /* Use 5MB/s */
3515 sync_reg
= 0x80; /* Use 4MB/s */
3519 sync_reg
= 0xA0; /* Use 3.33MB/s */
3523 sync_reg
= 0xC0; /* Use 2.85MB/s */
3527 sync_reg
= 0xE0; /* Use 2.5MB/s */
3529 if (sync_msg
> 100) {
3531 sync_reg
= 0x00; /* Use ASYNC */
3536 if (currTar_Info
->TarStatus
& WIDE_ENABLED
)
3542 sync_reg
|= (offset
| NARROW_SCSI
);
3544 FPT_sssyncv(port
,currSCCB
->TargID
,sync_reg
,currTar_Info
);
3547 if (currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) {
3552 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3553 ~(unsigned char)TAR_SYNC_MASK
) | (unsigned char)SYNC_SUPPORTED
);
3555 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3561 ACCEPT_MSG_ATN(port
);
3563 FPT_sisyncr(port
,sync_msg
,offset
);
3565 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3566 ~(unsigned char)TAR_SYNC_MASK
) | (unsigned char)SYNC_SUPPORTED
);
3571 /*---------------------------------------------------------------------
3573 * Function: FPT_sisyncr
3575 * Description: Answer the targets sync message.
3577 *---------------------------------------------------------------------*/
3578 static void FPT_sisyncr(unsigned long port
,unsigned char sync_pulse
, unsigned char offset
)
3581 WRW_HARPOON((port
+SYNC_MSGS
+0), (MPM_OP
+AMSG_OUT
+SMEXT
));
3582 WRW_HARPOON((port
+SYNC_MSGS
+2), (MPM_OP
+AMSG_OUT
+0x03 ));
3583 WRW_HARPOON((port
+SYNC_MSGS
+4), (MPM_OP
+AMSG_OUT
+SMSYNC
));
3584 WRW_HARPOON((port
+SYNC_MSGS
+6), (MPM_OP
+AMSG_OUT
+sync_pulse
));
3585 WRW_HARPOON((port
+SYNC_MSGS
+8), (RAT_OP
));
3586 WRW_HARPOON((port
+SYNC_MSGS
+10),(MPM_OP
+AMSG_OUT
+offset
));
3587 WRW_HARPOON((port
+SYNC_MSGS
+12),(BRH_OP
+ALWAYS
+NP
));
3590 WR_HARPOON(port
+hp_portctrl_0
, SCSI_PORT
);
3591 WRW_HARPOON((port
+hp_intstat
), CLR_ALL_INT_1
);
3593 WR_HARPOON(port
+hp_autostart_3
, (AUTO_IMMED
+CMD_ONLY_STRT
));
3595 while (!(RDW_HARPOON((port
+hp_intstat
)) & (BUS_FREE
| AUTO_INT
))) {}
3600 /*---------------------------------------------------------------------
3602 * Function: FPT_siwidn
3604 * Description: Read in a message byte from the SCSI bus, and check
3605 * for a parity error.
3607 *---------------------------------------------------------------------*/
3609 static unsigned char FPT_siwidn(unsigned long port
, unsigned char p_card
)
3611 struct sccb
* currSCCB
;
3612 PSCCBMgr_tar_info currTar_Info
;
3614 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3615 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3617 if (!((currTar_Info
->TarStatus
& TAR_WIDE_MASK
) == WIDE_NEGOCIATED
)) {
3620 WRW_HARPOON((port
+ID_MSG_STRT
),
3621 (MPM_OP
+AMSG_OUT
+(currSCCB
->Sccb_idmsg
& ~(unsigned char)DISC_PRIV
)));
3623 WRW_HARPOON((port
+ID_MSG_STRT
+2),BRH_OP
+ALWAYS
+CMDPZ
);
3625 WRW_HARPOON((port
+SYNC_MSGS
+0), (MPM_OP
+AMSG_OUT
+SMEXT
));
3626 WRW_HARPOON((port
+SYNC_MSGS
+2), (MPM_OP
+AMSG_OUT
+0x02 ));
3627 WRW_HARPOON((port
+SYNC_MSGS
+4), (MPM_OP
+AMSG_OUT
+SMWDTR
));
3628 WRW_HARPOON((port
+SYNC_MSGS
+6), (RAT_OP
));
3629 WRW_HARPOON((port
+SYNC_MSGS
+8), (MPM_OP
+AMSG_OUT
+ SM16BIT
));
3630 WRW_HARPOON((port
+SYNC_MSGS
+10),(BRH_OP
+ALWAYS
+NP
));
3632 WR_HARPOON(port
+hp_autostart_3
, (SELECT
+SELCHK_STRT
));
3635 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3636 ~(unsigned char)TAR_WIDE_MASK
) | (unsigned char)WIDE_ENABLED
);
3643 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3644 ~(unsigned char)TAR_WIDE_MASK
) | WIDE_NEGOCIATED
);
3646 currTar_Info
->TarEEValue
&= ~EE_WIDE_SCSI
;
3653 /*---------------------------------------------------------------------
3655 * Function: FPT_stwidn
3657 * Description: The has sent us a Wide Nego message so handle it as
3660 *---------------------------------------------------------------------*/
3661 static void FPT_stwidn(unsigned long port
, unsigned char p_card
)
3663 unsigned char width
;
3664 struct sccb
* currSCCB
;
3665 PSCCBMgr_tar_info currTar_Info
;
3667 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3668 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3670 width
= FPT_sfm(port
,currSCCB
);
3672 if((width
== 0x00) && (currSCCB
->Sccb_scsimsg
== SMPARITY
))
3674 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3679 if (!(currTar_Info
->TarEEValue
& EE_WIDE_SCSI
))
3683 currTar_Info
->TarStatus
|= WIDE_ENABLED
;
3687 width
= NARROW_SCSI
;
3688 currTar_Info
->TarStatus
&= ~WIDE_ENABLED
;
3692 FPT_sssyncv(port
,currSCCB
->TargID
,width
,currTar_Info
);
3695 if (currSCCB
->Sccb_scsistat
== SELECT_WN_ST
)
3700 currTar_Info
->TarStatus
|= WIDE_NEGOCIATED
;
3702 if (!((currTar_Info
->TarStatus
& TAR_SYNC_MASK
) == SYNC_SUPPORTED
))
3704 ACCEPT_MSG_ATN(port
);
3706 FPT_sisyncn(port
,p_card
, 1);
3707 currSCCB
->Sccb_scsistat
= SELECT_SN_ST
;
3713 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
3720 ACCEPT_MSG_ATN(port
);
3722 if (currTar_Info
->TarEEValue
& EE_WIDE_SCSI
)
3727 FPT_siwidr(port
,width
);
3729 currTar_Info
->TarStatus
|= (WIDE_NEGOCIATED
| WIDE_ENABLED
);
3734 /*---------------------------------------------------------------------
3736 * Function: FPT_siwidr
3738 * Description: Answer the targets Wide nego message.
3740 *---------------------------------------------------------------------*/
3741 static void FPT_siwidr(unsigned long port
, unsigned char width
)
3744 WRW_HARPOON((port
+SYNC_MSGS
+0), (MPM_OP
+AMSG_OUT
+SMEXT
));
3745 WRW_HARPOON((port
+SYNC_MSGS
+2), (MPM_OP
+AMSG_OUT
+0x02 ));
3746 WRW_HARPOON((port
+SYNC_MSGS
+4), (MPM_OP
+AMSG_OUT
+SMWDTR
));
3747 WRW_HARPOON((port
+SYNC_MSGS
+6), (RAT_OP
));
3748 WRW_HARPOON((port
+SYNC_MSGS
+8),(MPM_OP
+AMSG_OUT
+width
));
3749 WRW_HARPOON((port
+SYNC_MSGS
+10),(BRH_OP
+ALWAYS
+NP
));
3752 WR_HARPOON(port
+hp_portctrl_0
, SCSI_PORT
);
3753 WRW_HARPOON((port
+hp_intstat
), CLR_ALL_INT_1
);
3755 WR_HARPOON(port
+hp_autostart_3
, (AUTO_IMMED
+CMD_ONLY_STRT
));
3757 while (!(RDW_HARPOON((port
+hp_intstat
)) & (BUS_FREE
| AUTO_INT
))) {}
3762 /*---------------------------------------------------------------------
3764 * Function: FPT_sssyncv
3766 * Description: Write the desired value to the Sync Register for the
3769 *---------------------------------------------------------------------*/
3770 static void FPT_sssyncv(unsigned long p_port
, unsigned char p_id
, unsigned char p_sync_value
,
3771 PSCCBMgr_tar_info currTar_Info
)
3773 unsigned char index
;
3780 index
= 12; /* hp_synctarg_0 */
3783 index
= 13; /* hp_synctarg_1 */
3786 index
= 14; /* hp_synctarg_2 */
3789 index
= 15; /* hp_synctarg_3 */
3792 index
= 8; /* hp_synctarg_4 */
3795 index
= 9; /* hp_synctarg_5 */
3798 index
= 10; /* hp_synctarg_6 */
3801 index
= 11; /* hp_synctarg_7 */
3804 index
= 4; /* hp_synctarg_8 */
3807 index
= 5; /* hp_synctarg_9 */
3810 index
= 6; /* hp_synctarg_10 */
3813 index
= 7; /* hp_synctarg_11 */
3816 index
= 0; /* hp_synctarg_12 */
3819 index
= 1; /* hp_synctarg_13 */
3822 index
= 2; /* hp_synctarg_14 */
3825 index
= 3; /* hp_synctarg_15 */
3829 WR_HARPOON(p_port
+hp_synctarg_base
+index
, p_sync_value
);
3831 currTar_Info
->TarSyncCtrl
= p_sync_value
;
3835 /*---------------------------------------------------------------------
3837 * Function: FPT_sresb
3839 * Description: Reset the desired card's SCSI bus.
3841 *---------------------------------------------------------------------*/
3842 static void FPT_sresb(unsigned long port
, unsigned char p_card
)
3844 unsigned char scsiID
, i
;
3846 PSCCBMgr_tar_info currTar_Info
;
3848 WR_HARPOON(port
+hp_page_ctrl
,
3849 (RD_HARPOON(port
+hp_page_ctrl
) | G_INT_DISABLE
));
3850 WRW_HARPOON((port
+hp_intstat
), CLR_ALL_INT
);
3852 WR_HARPOON(port
+hp_scsictrl_0
, SCSI_RST
);
3854 scsiID
= RD_HARPOON(port
+hp_seltimeout
);
3855 WR_HARPOON(port
+hp_seltimeout
,TO_5ms
);
3856 WRW_HARPOON((port
+hp_intstat
), TIMEOUT
);
3858 WR_HARPOON(port
+hp_portctrl_0
,(SCSI_PORT
| START_TO
));
3860 while (!(RDW_HARPOON((port
+hp_intstat
)) & TIMEOUT
)) {}
3862 WR_HARPOON(port
+hp_seltimeout
,scsiID
);
3864 WR_HARPOON(port
+hp_scsictrl_0
, ENA_SCAM_SEL
);
3866 FPT_Wait(port
, TO_5ms
);
3868 WRW_HARPOON((port
+hp_intstat
), CLR_ALL_INT
);
3870 WR_HARPOON(port
+hp_int_mask
, (RD_HARPOON(port
+hp_int_mask
) | 0x00));
3872 for (scsiID
= 0; scsiID
< MAX_SCSI_TAR
; scsiID
++)
3874 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][scsiID
];
3876 if (currTar_Info
->TarEEValue
& EE_SYNC_MASK
)
3878 currTar_Info
->TarSyncCtrl
= 0;
3879 currTar_Info
->TarStatus
&= ~TAR_SYNC_MASK
;
3882 if (currTar_Info
->TarEEValue
& EE_WIDE_SCSI
)
3884 currTar_Info
->TarStatus
&= ~TAR_WIDE_MASK
;
3887 FPT_sssyncv(port
, scsiID
, NARROW_SCSI
,currTar_Info
);
3889 FPT_SccbMgrTableInitTarget(p_card
, scsiID
);
3892 FPT_BL_Card
[p_card
].scanIndex
= 0x00;
3893 FPT_BL_Card
[p_card
].currentSCCB
= NULL
;
3894 FPT_BL_Card
[p_card
].globalFlags
&= ~(F_TAG_STARTED
| F_HOST_XFER_ACT
3896 FPT_BL_Card
[p_card
].cmdCounter
= 0x00;
3897 FPT_BL_Card
[p_card
].discQCount
= 0x00;
3898 FPT_BL_Card
[p_card
].tagQ_Lst
= 0x01;
3900 for(i
= 0; i
< QUEUE_DEPTH
; i
++)
3901 FPT_BL_Card
[p_card
].discQ_Tbl
[i
] = NULL
;
3903 WR_HARPOON(port
+hp_page_ctrl
,
3904 (RD_HARPOON(port
+hp_page_ctrl
) & ~G_INT_DISABLE
));
3908 /*---------------------------------------------------------------------
3910 * Function: FPT_ssenss
3912 * Description: Setup for the Auto Sense command.
3914 *---------------------------------------------------------------------*/
3915 static void FPT_ssenss(PSCCBcard pCurrCard
)
3918 struct sccb
* currSCCB
;
3920 currSCCB
= pCurrCard
->currentSCCB
;
3923 currSCCB
->Save_CdbLen
= currSCCB
->CdbLength
;
3925 for (i
= 0; i
< 6; i
++) {
3927 currSCCB
->Save_Cdb
[i
] = currSCCB
->Cdb
[i
];
3930 currSCCB
->CdbLength
= SIX_BYTE_CMD
;
3931 currSCCB
->Cdb
[0] = SCSI_REQUEST_SENSE
;
3932 currSCCB
->Cdb
[1] = currSCCB
->Cdb
[1] & (unsigned char)0xE0; /*Keep LUN. */
3933 currSCCB
->Cdb
[2] = 0x00;
3934 currSCCB
->Cdb
[3] = 0x00;
3935 currSCCB
->Cdb
[4] = currSCCB
->RequestSenseLength
;
3936 currSCCB
->Cdb
[5] = 0x00;
3938 currSCCB
->Sccb_XferCnt
= (unsigned long)currSCCB
->RequestSenseLength
;
3940 currSCCB
->Sccb_ATC
= 0x00;
3942 currSCCB
->Sccb_XferState
|= F_AUTO_SENSE
;
3944 currSCCB
->Sccb_XferState
&= ~F_SG_XFER
;
3946 currSCCB
->Sccb_idmsg
= currSCCB
->Sccb_idmsg
& ~(unsigned char)DISC_PRIV
;
3948 currSCCB
->ControlByte
= 0x00;
3950 currSCCB
->Sccb_MGRFlags
&= F_STATUSLOADED
;
3955 /*---------------------------------------------------------------------
3957 * Function: FPT_sxfrp
3959 * Description: Transfer data into the bit bucket until the device
3960 * decides to switch phase.
3962 *---------------------------------------------------------------------*/
3964 static void FPT_sxfrp(unsigned long p_port
, unsigned char p_card
)
3966 unsigned char curr_phz
;
3969 DISABLE_AUTO(p_port
);
3971 if (FPT_BL_Card
[p_card
].globalFlags
& F_HOST_XFER_ACT
) {
3973 FPT_hostDataXferAbort(p_port
,p_card
,FPT_BL_Card
[p_card
].currentSCCB
);
3977 /* If the Automation handled the end of the transfer then do not
3978 match the phase or we will get out of sync with the ISR. */
3980 if (RDW_HARPOON((p_port
+hp_intstat
)) & (BUS_FREE
| XFER_CNT_0
| AUTO_INT
))
3983 WR_HARPOON(p_port
+hp_xfercnt_0
, 0x00);
3985 curr_phz
= RD_HARPOON(p_port
+hp_scsisig
) & (unsigned char)S_SCSI_PHZ
;
3987 WRW_HARPOON((p_port
+hp_intstat
), XFER_CNT_0
);
3990 WR_HARPOON(p_port
+hp_scsisig
, curr_phz
);
3992 while ( !(RDW_HARPOON((p_port
+hp_intstat
)) & (BUS_FREE
| RESET
)) &&
3993 (curr_phz
== (RD_HARPOON(p_port
+hp_scsisig
) & (unsigned char)S_SCSI_PHZ
)) )
3995 if (curr_phz
& (unsigned char)SCSI_IOBIT
)
3997 WR_HARPOON(p_port
+hp_portctrl_0
, (SCSI_PORT
| HOST_PORT
| SCSI_INBIT
));
3999 if (!(RD_HARPOON(p_port
+hp_xferstat
) & FIFO_EMPTY
))
4001 RD_HARPOON(p_port
+hp_fifodata_0
);
4006 WR_HARPOON(p_port
+hp_portctrl_0
, (SCSI_PORT
| HOST_PORT
| HOST_WRT
));
4007 if (RD_HARPOON(p_port
+hp_xferstat
) & FIFO_EMPTY
)
4009 WR_HARPOON(p_port
+hp_fifodata_0
,0xFA);
4012 } /* End of While loop for padding data I/O phase */
4014 while ( !(RDW_HARPOON((p_port
+hp_intstat
)) & (BUS_FREE
| RESET
)))
4016 if (RD_HARPOON(p_port
+hp_scsisig
) & SCSI_REQ
)
4020 WR_HARPOON(p_port
+hp_portctrl_0
, (SCSI_PORT
| HOST_PORT
| SCSI_INBIT
));
4021 while (!(RD_HARPOON(p_port
+hp_xferstat
) & FIFO_EMPTY
))
4023 RD_HARPOON(p_port
+hp_fifodata_0
);
4026 if ( !(RDW_HARPOON((p_port
+hp_intstat
)) & (BUS_FREE
| RESET
)))
4028 WR_HARPOON(p_port
+hp_autostart_0
, (AUTO_IMMED
+DISCONNECT_START
));
4029 while (!(RDW_HARPOON((p_port
+hp_intstat
)) & AUTO_INT
)) {}
4031 if (RDW_HARPOON((p_port
+hp_intstat
)) & (ICMD_COMP
| ITAR_DISC
))
4032 while (!(RDW_HARPOON((p_port
+hp_intstat
)) & (BUS_FREE
| RSEL
))) ;
4037 /*---------------------------------------------------------------------
4039 * Function: FPT_schkdd
4041 * Description: Make sure data has been flushed from both FIFOs and abort
4042 * the operations if necessary.
4044 *---------------------------------------------------------------------*/
4046 static void FPT_schkdd(unsigned long port
, unsigned char p_card
)
4048 unsigned short TimeOutLoop
;
4049 unsigned char sPhase
;
4051 struct sccb
* currSCCB
;
4053 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4056 if ((currSCCB
->Sccb_scsistat
!= DATA_OUT_ST
) &&
4057 (currSCCB
->Sccb_scsistat
!= DATA_IN_ST
)) {
4063 if (currSCCB
->Sccb_XferState
& F_ODD_BALL_CNT
)
4066 currSCCB
->Sccb_ATC
+= (currSCCB
->Sccb_XferCnt
-1);
4068 currSCCB
->Sccb_XferCnt
= 1;
4070 currSCCB
->Sccb_XferState
&= ~F_ODD_BALL_CNT
;
4071 WRW_HARPOON((port
+hp_fiforead
), (unsigned short) 0x00);
4072 WR_HARPOON(port
+hp_xferstat
, 0x00);
4078 currSCCB
->Sccb_ATC
+= currSCCB
->Sccb_XferCnt
;
4080 currSCCB
->Sccb_XferCnt
= 0;
4083 if ((RDW_HARPOON((port
+hp_intstat
)) & PARITY
) &&
4084 (currSCCB
->HostStatus
== SCCB_COMPLETE
)) {
4086 currSCCB
->HostStatus
= SCCB_PARITY_ERR
;
4087 WRW_HARPOON((port
+hp_intstat
), PARITY
);
4091 FPT_hostDataXferAbort(port
,p_card
,currSCCB
);
4094 while (RD_HARPOON(port
+hp_scsisig
) & SCSI_ACK
) {}
4098 while(RD_HARPOON(port
+hp_xferstat
) & FIFO_EMPTY
)
4100 if (RDW_HARPOON((port
+hp_intstat
)) & BUS_FREE
) {
4103 if (RD_HARPOON(port
+hp_offsetctr
) & (unsigned char)0x1F) {
4106 if (RDW_HARPOON((port
+hp_intstat
)) & RESET
) {
4109 if ((RD_HARPOON(port
+hp_scsisig
) & SCSI_REQ
) || (TimeOutLoop
++>0x3000) )
4113 sPhase
= RD_HARPOON(port
+hp_scsisig
) & (SCSI_BSY
| S_SCSI_PHZ
);
4114 if ((!(RD_HARPOON(port
+hp_xferstat
) & FIFO_EMPTY
)) ||
4115 (RD_HARPOON(port
+hp_offsetctr
) & (unsigned char)0x1F) ||
4116 (sPhase
== (SCSI_BSY
| S_DATAO_PH
)) ||
4117 (sPhase
== (SCSI_BSY
| S_DATAI_PH
)))
4120 WR_HARPOON(port
+hp_portctrl_0
, SCSI_PORT
);
4122 if (!(currSCCB
->Sccb_XferState
& F_ALL_XFERRED
))
4124 if (currSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
) {
4125 FPT_phaseDataIn(port
,p_card
);
4129 FPT_phaseDataOut(port
,p_card
);
4134 FPT_sxfrp(port
,p_card
);
4135 if (!(RDW_HARPOON((port
+hp_intstat
)) &
4136 (BUS_FREE
| ICMD_COMP
| ITAR_DISC
| RESET
)))
4138 WRW_HARPOON((port
+hp_intstat
), AUTO_INT
);
4139 FPT_phaseDecode(port
,p_card
);
4146 WR_HARPOON(port
+hp_portctrl_0
, 0x00);
4151 /*---------------------------------------------------------------------
4153 * Function: FPT_sinits
4155 * Description: Setup SCCB manager fields in this SCCB.
4157 *---------------------------------------------------------------------*/
4159 static void FPT_sinits(struct sccb
* p_sccb
, unsigned char p_card
)
4161 PSCCBMgr_tar_info currTar_Info
;
4163 if((p_sccb
->TargID
> MAX_SCSI_TAR
) || (p_sccb
->Lun
> MAX_LUN
))
4167 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
];
4169 p_sccb
->Sccb_XferState
= 0x00;
4170 p_sccb
->Sccb_XferCnt
= p_sccb
->DataLength
;
4172 if ((p_sccb
->OperationCode
== SCATTER_GATHER_COMMAND
) ||
4173 (p_sccb
->OperationCode
== RESIDUAL_SG_COMMAND
)) {
4175 p_sccb
->Sccb_SGoffset
= 0;
4176 p_sccb
->Sccb_XferState
= F_SG_XFER
;
4177 p_sccb
->Sccb_XferCnt
= 0x00;
4180 if (p_sccb
->DataLength
== 0x00)
4182 p_sccb
->Sccb_XferState
|= F_ALL_XFERRED
;
4184 if (p_sccb
->ControlByte
& F_USE_CMD_Q
)
4186 if ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) == TAG_Q_REJECT
)
4187 p_sccb
->ControlByte
&= ~F_USE_CMD_Q
;
4190 currTar_Info
->TarStatus
|= TAG_Q_TRYING
;
4193 /* For !single SCSI device in system & device allow Disconnect
4194 or command is tag_q type then send Cmd with Disconnect Enable
4195 else send Cmd with Disconnect Disable */
4198 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4199 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4200 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4202 if ((currTar_Info
->TarStatus
& TAR_ALLOW_DISC
) ||
4203 (currTar_Info
->TarStatus
& TAG_Q_TRYING
)) {
4204 p_sccb
->Sccb_idmsg
= (unsigned char)(SMIDENT
| DISC_PRIV
) | p_sccb
->Lun
;
4209 p_sccb
->Sccb_idmsg
= (unsigned char)SMIDENT
| p_sccb
->Lun
;
4212 p_sccb
->HostStatus
= 0x00;
4213 p_sccb
->TargetStatus
= 0x00;
4214 p_sccb
->Sccb_tag
= 0x00;
4215 p_sccb
->Sccb_MGRFlags
= 0x00;
4216 p_sccb
->Sccb_sgseg
= 0x00;
4217 p_sccb
->Sccb_ATC
= 0x00;
4218 p_sccb
->Sccb_savedATC
= 0x00;
4220 p_sccb->SccbVirtDataPtr = 0x00;
4221 p_sccb->Sccb_forwardlink = NULL;
4222 p_sccb->Sccb_backlink = NULL;
4224 p_sccb
->Sccb_scsistat
= BUS_FREE_ST
;
4225 p_sccb
->SccbStatus
= SCCB_IN_PROCESS
;
4226 p_sccb
->Sccb_scsimsg
= SMNO_OP
;
4231 /*---------------------------------------------------------------------
4233 * Function: Phase Decode
4235 * Description: Determine the phase and call the appropriate function.
4237 *---------------------------------------------------------------------*/
4239 static void FPT_phaseDecode(unsigned long p_port
, unsigned char p_card
)
4241 unsigned char phase_ref
;
4242 void (*phase
) (unsigned long, unsigned char);
4245 DISABLE_AUTO(p_port
);
4247 phase_ref
= (unsigned char) (RD_HARPOON(p_port
+hp_scsisig
) & S_SCSI_PHZ
);
4249 phase
= FPT_s_PhaseTbl
[phase_ref
];
4251 (*phase
)(p_port
, p_card
); /* Call the correct phase func */
4256 /*---------------------------------------------------------------------
4258 * Function: Data Out Phase
4260 * Description: Start up both the BusMaster and Xbow.
4262 *---------------------------------------------------------------------*/
4264 static void FPT_phaseDataOut(unsigned long port
, unsigned char p_card
)
4267 struct sccb
* currSCCB
;
4269 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4270 if (currSCCB
== NULL
)
4272 return; /* Exit if No SCCB record */
4275 currSCCB
->Sccb_scsistat
= DATA_OUT_ST
;
4276 currSCCB
->Sccb_XferState
&= ~(F_HOST_XFER_DIR
| F_NO_DATA_YET
);
4278 WR_HARPOON(port
+hp_portctrl_0
, SCSI_PORT
);
4280 WRW_HARPOON((port
+hp_intstat
), XFER_CNT_0
);
4282 WR_HARPOON(port
+hp_autostart_0
, (END_DATA
+END_DATA_START
));
4284 FPT_dataXferProcessor(port
, &FPT_BL_Card
[p_card
]);
4286 if (currSCCB
->Sccb_XferCnt
== 0) {
4289 if ((currSCCB
->ControlByte
& SCCB_DATA_XFER_OUT
) &&
4290 (currSCCB
->HostStatus
== SCCB_COMPLETE
))
4291 currSCCB
->HostStatus
= SCCB_DATA_OVER_RUN
;
4293 FPT_sxfrp(port
,p_card
);
4294 if (!(RDW_HARPOON((port
+hp_intstat
)) & (BUS_FREE
| RESET
)))
4295 FPT_phaseDecode(port
,p_card
);
4300 /*---------------------------------------------------------------------
4302 * Function: Data In Phase
4304 * Description: Startup the BusMaster and the XBOW.
4306 *---------------------------------------------------------------------*/
4308 static void FPT_phaseDataIn(unsigned long port
, unsigned char p_card
)
4311 struct sccb
* currSCCB
;
4313 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4315 if (currSCCB
== NULL
)
4317 return; /* Exit if No SCCB record */
4321 currSCCB
->Sccb_scsistat
= DATA_IN_ST
;
4322 currSCCB
->Sccb_XferState
|= F_HOST_XFER_DIR
;
4323 currSCCB
->Sccb_XferState
&= ~F_NO_DATA_YET
;
4325 WR_HARPOON(port
+hp_portctrl_0
, SCSI_PORT
);
4327 WRW_HARPOON((port
+hp_intstat
), XFER_CNT_0
);
4329 WR_HARPOON(port
+hp_autostart_0
, (END_DATA
+END_DATA_START
));
4331 FPT_dataXferProcessor(port
, &FPT_BL_Card
[p_card
]);
4333 if (currSCCB
->Sccb_XferCnt
== 0) {
4336 if ((currSCCB
->ControlByte
& SCCB_DATA_XFER_IN
) &&
4337 (currSCCB
->HostStatus
== SCCB_COMPLETE
))
4338 currSCCB
->HostStatus
= SCCB_DATA_OVER_RUN
;
4340 FPT_sxfrp(port
,p_card
);
4341 if (!(RDW_HARPOON((port
+hp_intstat
)) & (BUS_FREE
| RESET
)))
4342 FPT_phaseDecode(port
,p_card
);
4347 /*---------------------------------------------------------------------
4349 * Function: Command Phase
4351 * Description: Load the CDB into the automation and start it up.
4353 *---------------------------------------------------------------------*/
4355 static void FPT_phaseCommand(unsigned long p_port
, unsigned char p_card
)
4357 struct sccb
* currSCCB
;
4358 unsigned long cdb_reg
;
4361 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4363 if (currSCCB
->OperationCode
== RESET_COMMAND
) {
4365 currSCCB
->HostStatus
= SCCB_PHASE_SEQUENCE_FAIL
;
4366 currSCCB
->CdbLength
= SIX_BYTE_CMD
;
4369 WR_HARPOON(p_port
+hp_scsisig
, 0x00);
4371 ARAM_ACCESS(p_port
);
4374 cdb_reg
= p_port
+ CMD_STRT
;
4376 for (i
=0; i
< currSCCB
->CdbLength
; i
++) {
4378 if (currSCCB
->OperationCode
== RESET_COMMAND
)
4380 WRW_HARPOON(cdb_reg
, (MPM_OP
+ ACOMMAND
+ 0x00));
4383 WRW_HARPOON(cdb_reg
, (MPM_OP
+ ACOMMAND
+ currSCCB
->Cdb
[i
]));
4387 if (currSCCB
->CdbLength
!= TWELVE_BYTE_CMD
)
4388 WRW_HARPOON(cdb_reg
, (BRH_OP
+ALWAYS
+ NP
));
4390 WR_HARPOON(p_port
+hp_portctrl_0
,(SCSI_PORT
));
4392 currSCCB
->Sccb_scsistat
= COMMAND_ST
;
4394 WR_HARPOON(p_port
+hp_autostart_3
, (AUTO_IMMED
| CMD_ONLY_STRT
));
4395 SGRAM_ACCESS(p_port
);
4399 /*---------------------------------------------------------------------
4401 * Function: Status phase
4403 * Description: Bring in the status and command complete message bytes
4405 *---------------------------------------------------------------------*/
4407 static void FPT_phaseStatus(unsigned long port
, unsigned char p_card
)
4409 /* Start-up the automation to finish off this command and let the
4410 isr handle the interrupt for command complete when it comes in.
4411 We could wait here for the interrupt to be generated?
4414 WR_HARPOON(port
+hp_scsisig
, 0x00);
4416 WR_HARPOON(port
+hp_autostart_0
, (AUTO_IMMED
+END_DATA_START
));
4420 /*---------------------------------------------------------------------
4422 * Function: Phase Message Out
4424 * Description: Send out our message (if we have one) and handle whatever
4427 *---------------------------------------------------------------------*/
4429 static void FPT_phaseMsgOut(unsigned long port
, unsigned char p_card
)
4431 unsigned char message
,scsiID
;
4432 struct sccb
* currSCCB
;
4433 PSCCBMgr_tar_info currTar_Info
;
4435 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4437 if (currSCCB
!= NULL
) {
4439 message
= currSCCB
->Sccb_scsimsg
;
4440 scsiID
= currSCCB
->TargID
;
4442 if (message
== SMDEV_RESET
)
4446 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][scsiID
];
4447 currTar_Info
->TarSyncCtrl
= 0;
4448 FPT_sssyncv(port
, scsiID
, NARROW_SCSI
,currTar_Info
);
4450 if (FPT_sccbMgrTbl
[p_card
][scsiID
].TarEEValue
& EE_SYNC_MASK
)
4453 FPT_sccbMgrTbl
[p_card
][scsiID
].TarStatus
&= ~TAR_SYNC_MASK
;
4457 if (FPT_sccbMgrTbl
[p_card
][scsiID
].TarEEValue
& EE_WIDE_SCSI
)
4460 FPT_sccbMgrTbl
[p_card
][scsiID
].TarStatus
&= ~TAR_WIDE_MASK
;
4464 FPT_queueFlushSccb(p_card
,SCCB_COMPLETE
);
4465 FPT_SccbMgrTableInitTarget(p_card
,scsiID
);
4467 else if (currSCCB
->Sccb_scsistat
== ABORT_ST
)
4469 currSCCB
->HostStatus
= SCCB_COMPLETE
;
4470 if(FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->Sccb_tag
] != NULL
)
4472 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->Sccb_tag
] = NULL
;
4473 FPT_sccbMgrTbl
[p_card
][scsiID
].TarTagQ_Cnt
--;
4478 else if (currSCCB
->Sccb_scsistat
< COMMAND_ST
)
4482 if(message
== SMNO_OP
)
4484 currSCCB
->Sccb_MGRFlags
|= F_DEV_SELECTED
;
4486 FPT_ssel(port
,p_card
);
4494 if (message
== SMABORT
)
4496 FPT_queueFlushSccb(p_card
,SCCB_COMPLETE
);
4505 WRW_HARPOON((port
+hp_intstat
), (BUS_FREE
| PHASE
| XFER_CNT_0
));
4508 WR_HARPOON(port
+hp_portctrl_0
, SCSI_BUS_EN
);
4510 WR_HARPOON(port
+hp_scsidata_0
,message
);
4512 WR_HARPOON(port
+hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
4516 WR_HARPOON(port
+hp_portctrl_0
, 0x00);
4518 if ((message
== SMABORT
) || (message
== SMDEV_RESET
) ||
4519 (message
== SMABORT_TAG
) )
4522 while(!(RDW_HARPOON((port
+hp_intstat
)) & (BUS_FREE
| PHASE
))) {}
4524 if (RDW_HARPOON((port
+hp_intstat
)) & BUS_FREE
)
4526 WRW_HARPOON((port
+hp_intstat
), BUS_FREE
);
4528 if (currSCCB
!= NULL
)
4531 if((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4532 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
4533 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[currSCCB
->Lun
] = 0;
4535 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[0] = 0;
4537 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
],currSCCB
, p_card
);
4542 FPT_BL_Card
[p_card
].globalFlags
|= F_NEW_SCCB_CMD
;
4549 FPT_sxfrp(port
,p_card
);
4556 if(message
== SMPARITY
)
4558 currSCCB
->Sccb_scsimsg
= SMNO_OP
;
4559 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
4563 FPT_sxfrp(port
,p_card
);
4569 /*---------------------------------------------------------------------
4571 * Function: Message In phase
4573 * Description: Bring in the message and determine what to do with it.
4575 *---------------------------------------------------------------------*/
4577 static void FPT_phaseMsgIn(unsigned long port
, unsigned char p_card
)
4579 unsigned char message
;
4580 struct sccb
* currSCCB
;
4582 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4584 if (FPT_BL_Card
[p_card
].globalFlags
& F_HOST_XFER_ACT
)
4587 FPT_phaseChkFifo(port
, p_card
);
4590 message
= RD_HARPOON(port
+hp_scsidata_0
);
4591 if ((message
== SMDISC
) || (message
== SMSAVE_DATA_PTR
))
4594 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+END_DATA_START
));
4601 message
= FPT_sfm(port
,currSCCB
);
4606 FPT_sdecm(message
,port
,p_card
);
4611 if(currSCCB
->Sccb_scsimsg
!= SMPARITY
)
4613 WR_HARPOON(port
+hp_autostart_1
, (AUTO_IMMED
+DISCONNECT_START
));
4620 /*---------------------------------------------------------------------
4622 * Function: Illegal phase
4624 * Description: Target switched to some illegal phase, so all we can do
4625 * is report an error back to the host (if that is possible)
4626 * and send an ABORT message to the misbehaving target.
4628 *---------------------------------------------------------------------*/
4630 static void FPT_phaseIllegal(unsigned long port
, unsigned char p_card
)
4632 struct sccb
* currSCCB
;
4634 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4636 WR_HARPOON(port
+hp_scsisig
, RD_HARPOON(port
+hp_scsisig
));
4637 if (currSCCB
!= NULL
) {
4639 currSCCB
->HostStatus
= SCCB_PHASE_SEQUENCE_FAIL
;
4640 currSCCB
->Sccb_scsistat
= ABORT_ST
;
4641 currSCCB
->Sccb_scsimsg
= SMABORT
;
4644 ACCEPT_MSG_ATN(port
);
4649 /*---------------------------------------------------------------------
4651 * Function: Phase Check FIFO
4653 * Description: Make sure data has been flushed from both FIFOs and abort
4654 * the operations if necessary.
4656 *---------------------------------------------------------------------*/
4658 static void FPT_phaseChkFifo(unsigned long port
, unsigned char p_card
)
4660 unsigned long xfercnt
;
4661 struct sccb
* currSCCB
;
4663 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4665 if (currSCCB
->Sccb_scsistat
== DATA_IN_ST
)
4668 while((!(RD_HARPOON(port
+hp_xferstat
) & FIFO_EMPTY
)) &&
4669 (RD_HARPOON(port
+hp_ext_status
) & BM_CMD_BUSY
)) {}
4672 if (!(RD_HARPOON(port
+hp_xferstat
) & FIFO_EMPTY
))
4674 currSCCB
->Sccb_ATC
+= currSCCB
->Sccb_XferCnt
;
4676 currSCCB
->Sccb_XferCnt
= 0;
4678 if ((RDW_HARPOON((port
+hp_intstat
)) & PARITY
) &&
4679 (currSCCB
->HostStatus
== SCCB_COMPLETE
))
4681 currSCCB
->HostStatus
= SCCB_PARITY_ERR
;
4682 WRW_HARPOON((port
+hp_intstat
), PARITY
);
4685 FPT_hostDataXferAbort(port
,p_card
,currSCCB
);
4687 FPT_dataXferProcessor(port
, &FPT_BL_Card
[p_card
]);
4689 while((!(RD_HARPOON(port
+hp_xferstat
) & FIFO_EMPTY
)) &&
4690 (RD_HARPOON(port
+hp_ext_status
) & BM_CMD_BUSY
)) {}
4693 } /*End Data In specific code. */
4697 GET_XFER_CNT(port
,xfercnt
);
4700 WR_HARPOON(port
+hp_xfercnt_0
, 0x00);
4703 WR_HARPOON(port
+hp_portctrl_0
, 0x00);
4705 currSCCB
->Sccb_ATC
+= (currSCCB
->Sccb_XferCnt
- xfercnt
);
4707 currSCCB
->Sccb_XferCnt
= xfercnt
;
4709 if ((RDW_HARPOON((port
+hp_intstat
)) & PARITY
) &&
4710 (currSCCB
->HostStatus
== SCCB_COMPLETE
)) {
4712 currSCCB
->HostStatus
= SCCB_PARITY_ERR
;
4713 WRW_HARPOON((port
+hp_intstat
), PARITY
);
4717 FPT_hostDataXferAbort(port
,p_card
,currSCCB
);
4720 WR_HARPOON(port
+hp_fifowrite
, 0x00);
4721 WR_HARPOON(port
+hp_fiforead
, 0x00);
4722 WR_HARPOON(port
+hp_xferstat
, 0x00);
4724 WRW_HARPOON((port
+hp_intstat
), XFER_CNT_0
);
4728 /*---------------------------------------------------------------------
4730 * Function: Phase Bus Free
4732 * Description: We just went bus free so figure out if it was
4733 * because of command complete or from a disconnect.
4735 *---------------------------------------------------------------------*/
4736 static void FPT_phaseBusFree(unsigned long port
, unsigned char p_card
)
4738 struct sccb
* currSCCB
;
4740 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4742 if (currSCCB
!= NULL
)
4748 if (currSCCB
->OperationCode
== RESET_COMMAND
)
4751 if((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4752 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
4753 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[currSCCB
->Lun
] = 0;
4755 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[0] = 0;
4757 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
], currSCCB
, p_card
);
4759 FPT_queueSearchSelect(&FPT_BL_Card
[p_card
],p_card
);
4763 else if(currSCCB
->Sccb_scsistat
== SELECT_SN_ST
)
4765 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
|=
4766 (unsigned char)SYNC_SUPPORTED
;
4767 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
&= ~EE_SYNC_MASK
;
4770 else if(currSCCB
->Sccb_scsistat
== SELECT_WN_ST
)
4772 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
=
4773 (FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4774 TarStatus
& ~WIDE_ENABLED
) | WIDE_NEGOCIATED
;
4776 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
&= ~EE_WIDE_SCSI
;
4779 else if(currSCCB
->Sccb_scsistat
== SELECT_Q_ST
)
4781 /* Make sure this is not a phony BUS_FREE. If we were
4782 reselected or if BUSY is NOT on then this is a
4783 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4785 if ((!(RD_HARPOON(port
+hp_scsisig
) & SCSI_BSY
)) ||
4786 (RDW_HARPOON((port
+hp_intstat
)) & RSEL
))
4788 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
&= ~TAR_TAG_Q_MASK
;
4789 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
|= TAG_Q_REJECT
;
4801 currSCCB
->Sccb_scsistat
= BUS_FREE_ST
;
4803 if (!currSCCB
->HostStatus
)
4805 currSCCB
->HostStatus
= SCCB_PHASE_SEQUENCE_FAIL
;
4808 if((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4809 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
4810 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[currSCCB
->Lun
] = 0;
4812 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[0] = 0;
4814 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
], currSCCB
, p_card
);
4819 FPT_BL_Card
[p_card
].globalFlags
|= F_NEW_SCCB_CMD
;
4821 } /*end if !=null */
4827 /*---------------------------------------------------------------------
4829 * Function: Auto Load Default Map
4831 * Description: Load the Automation RAM with the defualt map values.
4833 *---------------------------------------------------------------------*/
4834 static void FPT_autoLoadDefaultMap(unsigned long p_port
)
4836 unsigned long map_addr
;
4838 ARAM_ACCESS(p_port
);
4839 map_addr
= p_port
+ hp_aramBase
;
4841 WRW_HARPOON(map_addr
, (MPM_OP
+AMSG_OUT
+ 0xC0)); /*ID MESSAGE */
4843 WRW_HARPOON(map_addr
, (MPM_OP
+AMSG_OUT
+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4845 WRW_HARPOON(map_addr
, RAT_OP
); /*RESET ATTENTION */
4847 WRW_HARPOON(map_addr
, (MPM_OP
+AMSG_OUT
+ 0x00)); /*TAG ID MSG */
4849 WRW_HARPOON(map_addr
, (MPM_OP
+ACOMMAND
+ 0x00)); /*CDB BYTE 0 */
4851 WRW_HARPOON(map_addr
, (MPM_OP
+ACOMMAND
+ 0x00)); /*CDB BYTE 1 */
4853 WRW_HARPOON(map_addr
, (MPM_OP
+ACOMMAND
+ 0x00)); /*CDB BYTE 2 */
4855 WRW_HARPOON(map_addr
, (MPM_OP
+ACOMMAND
+ 0x00)); /*CDB BYTE 3 */
4857 WRW_HARPOON(map_addr
, (MPM_OP
+ACOMMAND
+ 0x00)); /*CDB BYTE 4 */
4859 WRW_HARPOON(map_addr
, (MPM_OP
+ACOMMAND
+ 0x00)); /*CDB BYTE 5 */
4861 WRW_HARPOON(map_addr
, (MPM_OP
+ACOMMAND
+ 0x00)); /*CDB BYTE 6 */
4863 WRW_HARPOON(map_addr
, (MPM_OP
+ACOMMAND
+ 0x00)); /*CDB BYTE 7 */
4865 WRW_HARPOON(map_addr
, (MPM_OP
+ACOMMAND
+ 0x00)); /*CDB BYTE 8 */
4867 WRW_HARPOON(map_addr
, (MPM_OP
+ACOMMAND
+ 0x00)); /*CDB BYTE 9 */
4869 WRW_HARPOON(map_addr
, (MPM_OP
+ACOMMAND
+ 0x00)); /*CDB BYTE 10 */
4871 WRW_HARPOON(map_addr
, (MPM_OP
+ACOMMAND
+ 0x00)); /*CDB BYTE 11 */
4873 WRW_HARPOON(map_addr
, (CPE_OP
+ADATA_OUT
+ DINT
)); /*JUMP IF DATA OUT */
4875 WRW_HARPOON(map_addr
, (TCB_OP
+FIFO_0
+ DI
)); /*JUMP IF NO DATA IN FIFO */
4876 map_addr
+=2; /*This means AYNC DATA IN */
4877 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_IDO_STRT
)); /*STOP AND INTERRUPT */
4879 WRW_HARPOON(map_addr
, (CPE_OP
+ADATA_IN
+DINT
)); /*JUMP IF NOT DATA IN PHZ */
4881 WRW_HARPOON(map_addr
, (CPN_OP
+AMSG_IN
+ ST
)); /*IF NOT MSG IN CHECK 4 DATA IN */
4883 WRW_HARPOON(map_addr
, (CRD_OP
+SDATA
+ 0x02)); /*SAVE DATA PTR MSG? */
4885 WRW_HARPOON(map_addr
, (BRH_OP
+NOT_EQ
+ DC
)); /*GO CHECK FOR DISCONNECT MSG */
4887 WRW_HARPOON(map_addr
, (MRR_OP
+SDATA
+ D_AR1
)); /*SAVE DATA PTRS MSG */
4889 WRW_HARPOON(map_addr
, (CPN_OP
+AMSG_IN
+ ST
)); /*IF NOT MSG IN CHECK DATA IN */
4891 WRW_HARPOON(map_addr
, (CRD_OP
+SDATA
+ 0x04)); /*DISCONNECT MSG? */
4893 WRW_HARPOON(map_addr
, (BRH_OP
+NOT_EQ
+ UNKNWN
));/*UKNKNOWN MSG */
4895 WRW_HARPOON(map_addr
, (MRR_OP
+SDATA
+ D_BUCKET
));/*XFER DISCONNECT MSG */
4897 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_ITAR_DISC
));/*STOP AND INTERRUPT */
4899 WRW_HARPOON(map_addr
, (CPN_OP
+ASTATUS
+ UNKNWN
));/*JUMP IF NOT STATUS PHZ. */
4901 WRW_HARPOON(map_addr
, (MRR_OP
+SDATA
+ D_AR0
)); /*GET STATUS BYTE */
4903 WRW_HARPOON(map_addr
, (CPN_OP
+AMSG_IN
+ CC
)); /*ERROR IF NOT MSG IN PHZ */
4905 WRW_HARPOON(map_addr
, (CRD_OP
+SDATA
+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4907 WRW_HARPOON(map_addr
, (BRH_OP
+NOT_EQ
+ CC
)); /*ERROR IF NOT CMD COMPLETE MSG. */
4909 WRW_HARPOON(map_addr
, (MRR_OP
+SDATA
+ D_BUCKET
));/*GET CMD COMPLETE MSG */
4911 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_ICMD_COMP
));/*END OF COMMAND */
4914 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_IUNKWN
)); /*RECEIVED UNKNOWN MSG BYTE */
4916 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_INO_CC
)); /*NO COMMAND COMPLETE AFTER STATUS */
4918 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_ITICKLE
)); /*BIOS Tickled the Mgr */
4920 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_IRFAIL
)); /*EXPECTED ID/TAG MESSAGES AND */
4921 map_addr
+=2; /* DIDN'T GET ONE */
4922 WRW_HARPOON(map_addr
, (CRR_OP
+AR3
+ S_IDREG
)); /* comp SCSI SEL ID & AR3*/
4924 WRW_HARPOON(map_addr
, (BRH_OP
+EQUAL
+ 0x00)); /*SEL ID OK then Conti. */
4926 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_INO_CC
)); /*NO COMMAND COMPLETE AFTER STATUS */
4930 SGRAM_ACCESS(p_port
);
4933 /*---------------------------------------------------------------------
4935 * Function: Auto Command Complete
4937 * Description: Post command back to host and find another command
4940 *---------------------------------------------------------------------*/
4942 static void FPT_autoCmdCmplt(unsigned long p_port
, unsigned char p_card
)
4944 struct sccb
* currSCCB
;
4945 unsigned char status_byte
;
4947 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4949 status_byte
= RD_HARPOON(p_port
+hp_gp_reg_0
);
4951 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUN_CA
= 0;
4953 if (status_byte
!= SSGOOD
) {
4955 if (status_byte
== SSQ_FULL
) {
4958 if(((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4959 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
)))
4961 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[currSCCB
->Lun
] = 1;
4962 if(FPT_BL_Card
[p_card
].discQCount
!= 0)
4963 FPT_BL_Card
[p_card
].discQCount
--;
4964 FPT_BL_Card
[p_card
].discQ_Tbl
[FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].LunDiscQ_Idx
[currSCCB
->Lun
]] = NULL
;
4968 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[0] = 1;
4969 if(currSCCB
->Sccb_tag
)
4971 if(FPT_BL_Card
[p_card
].discQCount
!= 0)
4972 FPT_BL_Card
[p_card
].discQCount
--;
4973 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->Sccb_tag
] = NULL
;
4976 if(FPT_BL_Card
[p_card
].discQCount
!= 0)
4977 FPT_BL_Card
[p_card
].discQCount
--;
4978 FPT_BL_Card
[p_card
].discQ_Tbl
[FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].LunDiscQ_Idx
[0]] = NULL
;
4982 currSCCB
->Sccb_MGRFlags
|= F_STATUSLOADED
;
4984 FPT_queueSelectFail(&FPT_BL_Card
[p_card
],p_card
);
4989 if(currSCCB
->Sccb_scsistat
== SELECT_SN_ST
)
4991 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
|=
4992 (unsigned char)SYNC_SUPPORTED
;
4994 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
&= ~EE_SYNC_MASK
;
4995 FPT_BL_Card
[p_card
].globalFlags
|= F_NEW_SCCB_CMD
;
4997 if(((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4998 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
)))
5000 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[currSCCB
->Lun
] = 1;
5001 if(FPT_BL_Card
[p_card
].discQCount
!= 0)
5002 FPT_BL_Card
[p_card
].discQCount
--;
5003 FPT_BL_Card
[p_card
].discQ_Tbl
[FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].LunDiscQ_Idx
[currSCCB
->Lun
]] = NULL
;
5007 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[0] = 1;
5008 if(currSCCB
->Sccb_tag
)
5010 if(FPT_BL_Card
[p_card
].discQCount
!= 0)
5011 FPT_BL_Card
[p_card
].discQCount
--;
5012 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->Sccb_tag
] = NULL
;
5015 if(FPT_BL_Card
[p_card
].discQCount
!= 0)
5016 FPT_BL_Card
[p_card
].discQCount
--;
5017 FPT_BL_Card
[p_card
].discQ_Tbl
[FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].LunDiscQ_Idx
[0]] = NULL
;
5024 if(currSCCB
->Sccb_scsistat
== SELECT_WN_ST
)
5027 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
=
5028 (FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
5029 TarStatus
& ~WIDE_ENABLED
) | WIDE_NEGOCIATED
;
5031 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
&= ~EE_WIDE_SCSI
;
5032 FPT_BL_Card
[p_card
].globalFlags
|= F_NEW_SCCB_CMD
;
5034 if(((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
5035 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
)))
5037 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[currSCCB
->Lun
] = 1;
5038 if(FPT_BL_Card
[p_card
].discQCount
!= 0)
5039 FPT_BL_Card
[p_card
].discQCount
--;
5040 FPT_BL_Card
[p_card
].discQ_Tbl
[FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].LunDiscQ_Idx
[currSCCB
->Lun
]] = NULL
;
5044 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[0] = 1;
5045 if(currSCCB
->Sccb_tag
)
5047 if(FPT_BL_Card
[p_card
].discQCount
!= 0)
5048 FPT_BL_Card
[p_card
].discQCount
--;
5049 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->Sccb_tag
] = NULL
;
5052 if(FPT_BL_Card
[p_card
].discQCount
!= 0)
5053 FPT_BL_Card
[p_card
].discQCount
--;
5054 FPT_BL_Card
[p_card
].discQ_Tbl
[FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].LunDiscQ_Idx
[0]] = NULL
;
5061 if (status_byte
== SSCHECK
)
5063 if(FPT_BL_Card
[p_card
].globalFlags
& F_DO_RENEGO
)
5065 if (FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
& EE_SYNC_MASK
)
5067 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
&= ~TAR_SYNC_MASK
;
5069 if (FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
& EE_WIDE_SCSI
)
5071 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
&= ~TAR_WIDE_MASK
;
5076 if (!(currSCCB
->Sccb_XferState
& F_AUTO_SENSE
)) {
5078 currSCCB
->SccbStatus
= SCCB_ERROR
;
5079 currSCCB
->TargetStatus
= status_byte
;
5081 if (status_byte
== SSCHECK
) {
5083 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUN_CA
5087 if (currSCCB
->RequestSenseLength
!= NO_AUTO_REQUEST_SENSE
) {
5089 if (currSCCB
->RequestSenseLength
== 0)
5090 currSCCB
->RequestSenseLength
= 14;
5092 FPT_ssenss(&FPT_BL_Card
[p_card
]);
5093 FPT_BL_Card
[p_card
].globalFlags
|= F_NEW_SCCB_CMD
;
5095 if(((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
5096 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
)))
5098 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[currSCCB
->Lun
] = 1;
5099 if(FPT_BL_Card
[p_card
].discQCount
!= 0)
5100 FPT_BL_Card
[p_card
].discQCount
--;
5101 FPT_BL_Card
[p_card
].discQ_Tbl
[FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].LunDiscQ_Idx
[currSCCB
->Lun
]] = NULL
;
5105 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[0] = 1;
5106 if(currSCCB
->Sccb_tag
)
5108 if(FPT_BL_Card
[p_card
].discQCount
!= 0)
5109 FPT_BL_Card
[p_card
].discQCount
--;
5110 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->Sccb_tag
] = NULL
;
5113 if(FPT_BL_Card
[p_card
].discQCount
!= 0)
5114 FPT_BL_Card
[p_card
].discQCount
--;
5115 FPT_BL_Card
[p_card
].discQ_Tbl
[FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].LunDiscQ_Idx
[0]] = NULL
;
5125 if((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
5126 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
5127 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[currSCCB
->Lun
] = 0;
5129 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[0] = 0;
5132 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
], currSCCB
, p_card
);
5135 #define SHORT_WAIT 0x0000000F
5136 #define LONG_WAIT 0x0000FFFFL
5139 /*---------------------------------------------------------------------
5141 * Function: Data Transfer Processor
5143 * Description: This routine performs two tasks.
5144 * (1) Start data transfer by calling HOST_DATA_XFER_START
5145 * function. Once data transfer is started, (2) Depends
5146 * on the type of data transfer mode Scatter/Gather mode
5147 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5148 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5149 * data transfer done. In Scatter/Gather mode, this routine
5150 * checks bus master command complete and dual rank busy
5151 * bit to keep chaining SC transfer command. Similarly,
5152 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5153 * (F_HOST_XFER_ACT bit) for data transfer done.
5155 *---------------------------------------------------------------------*/
5157 static void FPT_dataXferProcessor(unsigned long port
, PSCCBcard pCurrCard
)
5159 struct sccb
* currSCCB
;
5161 currSCCB
= pCurrCard
->currentSCCB
;
5163 if (currSCCB
->Sccb_XferState
& F_SG_XFER
)
5165 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
)
5168 currSCCB
->Sccb_sgseg
+= (unsigned char)SG_BUF_CNT
;
5169 currSCCB
->Sccb_SGoffset
= 0x00;
5171 pCurrCard
->globalFlags
|= F_HOST_XFER_ACT
;
5173 FPT_busMstrSGDataXferStart(port
, currSCCB
);
5178 if (!(pCurrCard
->globalFlags
& F_HOST_XFER_ACT
))
5180 pCurrCard
->globalFlags
|= F_HOST_XFER_ACT
;
5182 FPT_busMstrDataXferStart(port
, currSCCB
);
5188 /*---------------------------------------------------------------------
5190 * Function: BusMaster Scatter Gather Data Transfer Start
5194 *---------------------------------------------------------------------*/
5195 static void FPT_busMstrSGDataXferStart(unsigned long p_port
, struct sccb
* pcurrSCCB
)
5197 unsigned long count
,addr
,tmpSGCnt
;
5198 unsigned int sg_index
;
5199 unsigned char sg_count
, i
;
5200 unsigned long reg_offset
;
5203 if (pcurrSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
) {
5205 count
= ((unsigned long) HOST_RD_CMD
)<<24;
5209 count
= ((unsigned long) HOST_WRT_CMD
)<<24;
5214 sg_index
= pcurrSCCB
->Sccb_sgseg
;
5215 reg_offset
= hp_aramBase
;
5218 i
= (unsigned char) (RD_HARPOON(p_port
+hp_page_ctrl
) & ~(SGRAM_ARAM
|SCATTER_EN
));
5221 WR_HARPOON(p_port
+hp_page_ctrl
, i
);
5223 while ((sg_count
< (unsigned char)SG_BUF_CNT
) &&
5224 ((unsigned long)(sg_index
* (unsigned int)SG_ELEMENT_SIZE
) < pcurrSCCB
->DataLength
) ) {
5226 tmpSGCnt
+= *(((unsigned long *)pcurrSCCB
->DataPointer
)+
5229 count
|= *(((unsigned long *)pcurrSCCB
->DataPointer
)+
5232 addr
= *(((unsigned long *)pcurrSCCB
->DataPointer
)+
5233 ((sg_index
* 2) + 1));
5236 if ((!sg_count
) && (pcurrSCCB
->Sccb_SGoffset
)) {
5238 addr
+= ((count
& 0x00FFFFFFL
) - pcurrSCCB
->Sccb_SGoffset
);
5239 count
= (count
& 0xFF000000L
) | pcurrSCCB
->Sccb_SGoffset
;
5241 tmpSGCnt
= count
& 0x00FFFFFFL
;
5244 WR_HARP32(p_port
,reg_offset
,addr
);
5247 WR_HARP32(p_port
,reg_offset
,count
);
5250 count
&= 0xFF000000L
;
5256 pcurrSCCB
->Sccb_XferCnt
= tmpSGCnt
;
5258 WR_HARPOON(p_port
+hp_sg_addr
,(sg_count
<<4));
5260 if (pcurrSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
) {
5262 WR_HARP32(p_port
,hp_xfercnt_0
,tmpSGCnt
);
5265 WR_HARPOON(p_port
+hp_portctrl_0
,(DMA_PORT
| SCSI_PORT
| SCSI_INBIT
));
5266 WR_HARPOON(p_port
+hp_scsisig
, S_DATAI_PH
);
5272 if ((!(RD_HARPOON(p_port
+hp_synctarg_0
) & NARROW_SCSI
)) &&
5273 (tmpSGCnt
& 0x000000001))
5276 pcurrSCCB
->Sccb_XferState
|= F_ODD_BALL_CNT
;
5281 WR_HARP32(p_port
,hp_xfercnt_0
,tmpSGCnt
);
5283 WR_HARPOON(p_port
+hp_portctrl_0
,(SCSI_PORT
| DMA_PORT
| DMA_RD
));
5284 WR_HARPOON(p_port
+hp_scsisig
, S_DATAO_PH
);
5288 WR_HARPOON(p_port
+hp_page_ctrl
, (unsigned char) (i
| SCATTER_EN
));
5293 /*---------------------------------------------------------------------
5295 * Function: BusMaster Data Transfer Start
5299 *---------------------------------------------------------------------*/
5300 static void FPT_busMstrDataXferStart(unsigned long p_port
, struct sccb
* pcurrSCCB
)
5302 unsigned long addr
,count
;
5304 if (!(pcurrSCCB
->Sccb_XferState
& F_AUTO_SENSE
)) {
5306 count
= pcurrSCCB
->Sccb_XferCnt
;
5308 addr
= (unsigned long) pcurrSCCB
->DataPointer
+ pcurrSCCB
->Sccb_ATC
;
5312 addr
= pcurrSCCB
->SensePointer
;
5313 count
= pcurrSCCB
->RequestSenseLength
;
5317 HP_SETUP_ADDR_CNT(p_port
,addr
,count
);
5320 if (pcurrSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
) {
5322 WR_HARPOON(p_port
+hp_portctrl_0
,(DMA_PORT
| SCSI_PORT
| SCSI_INBIT
));
5323 WR_HARPOON(p_port
+hp_scsisig
, S_DATAI_PH
);
5325 WR_HARPOON(p_port
+hp_xfer_cmd
,
5326 (XFER_DMA_HOST
| XFER_HOST_AUTO
| XFER_DMA_8BIT
));
5331 WR_HARPOON(p_port
+hp_portctrl_0
,(SCSI_PORT
| DMA_PORT
| DMA_RD
));
5332 WR_HARPOON(p_port
+hp_scsisig
, S_DATAO_PH
);
5334 WR_HARPOON(p_port
+hp_xfer_cmd
,
5335 (XFER_HOST_DMA
| XFER_HOST_AUTO
| XFER_DMA_8BIT
));
5341 /*---------------------------------------------------------------------
5343 * Function: BusMaster Timeout Handler
5345 * Description: This function is called after a bus master command busy time
5346 * out is detected. This routines issue halt state machine
5347 * with a software time out for command busy. If command busy
5348 * is still asserted at the end of the time out, it issues
5349 * hard abort with another software time out. It hard abort
5350 * command busy is also time out, it'll just give up.
5352 *---------------------------------------------------------------------*/
5353 static unsigned char FPT_busMstrTimeOut(unsigned long p_port
)
5355 unsigned long timeout
;
5357 timeout
= LONG_WAIT
;
5359 WR_HARPOON(p_port
+hp_sys_ctrl
, HALT_MACH
);
5361 while ((!(RD_HARPOON(p_port
+hp_ext_status
) & CMD_ABORTED
)) && timeout
--) {}
5365 if (RD_HARPOON(p_port
+hp_ext_status
) & BM_CMD_BUSY
) {
5366 WR_HARPOON(p_port
+hp_sys_ctrl
, HARD_ABORT
);
5368 timeout
= LONG_WAIT
;
5369 while ((RD_HARPOON(p_port
+hp_ext_status
) & BM_CMD_BUSY
) && timeout
--) {}
5372 RD_HARPOON(p_port
+hp_int_status
); /*Clear command complete */
5374 if (RD_HARPOON(p_port
+hp_ext_status
) & BM_CMD_BUSY
) {
5384 /*---------------------------------------------------------------------
5386 * Function: Host Data Transfer Abort
5388 * Description: Abort any in progress transfer.
5390 *---------------------------------------------------------------------*/
5391 static void FPT_hostDataXferAbort(unsigned long port
, unsigned char p_card
, struct sccb
* pCurrSCCB
)
5394 unsigned long timeout
;
5395 unsigned long remain_cnt
;
5396 unsigned int sg_ptr
;
5398 FPT_BL_Card
[p_card
].globalFlags
&= ~F_HOST_XFER_ACT
;
5400 if (pCurrSCCB
->Sccb_XferState
& F_AUTO_SENSE
) {
5403 if (!(RD_HARPOON(port
+hp_int_status
) & INT_CMD_COMPL
)) {
5405 WR_HARPOON(port
+hp_bm_ctrl
, (RD_HARPOON(port
+hp_bm_ctrl
) | FLUSH_XFER_CNTR
));
5406 timeout
= LONG_WAIT
;
5408 while ((RD_HARPOON(port
+hp_ext_status
) & BM_CMD_BUSY
) && timeout
--) {}
5410 WR_HARPOON(port
+hp_bm_ctrl
, (RD_HARPOON(port
+hp_bm_ctrl
) & ~FLUSH_XFER_CNTR
));
5412 if (RD_HARPOON(port
+hp_ext_status
) & BM_CMD_BUSY
) {
5414 if (FPT_busMstrTimeOut(port
)) {
5416 if (pCurrSCCB
->HostStatus
== 0x00)
5418 pCurrSCCB
->HostStatus
= SCCB_BM_ERR
;
5422 if (RD_HARPOON(port
+hp_int_status
) & INT_EXT_STATUS
)
5424 if (RD_HARPOON(port
+hp_ext_status
) & BAD_EXT_STATUS
)
5426 if (pCurrSCCB
->HostStatus
== 0x00)
5429 pCurrSCCB
->HostStatus
= SCCB_BM_ERR
;
5435 else if (pCurrSCCB
->Sccb_XferCnt
) {
5437 if (pCurrSCCB
->Sccb_XferState
& F_SG_XFER
) {
5440 WR_HARPOON(port
+hp_page_ctrl
, (RD_HARPOON(port
+hp_page_ctrl
) &
5443 WR_HARPOON(port
+hp_sg_addr
,0x00);
5445 sg_ptr
= pCurrSCCB
->Sccb_sgseg
+ SG_BUF_CNT
;
5447 if (sg_ptr
> (unsigned int)(pCurrSCCB
->DataLength
/ SG_ELEMENT_SIZE
)) {
5449 sg_ptr
= (unsigned int)(pCurrSCCB
->DataLength
/ SG_ELEMENT_SIZE
);
5452 remain_cnt
= pCurrSCCB
->Sccb_XferCnt
;
5454 while (remain_cnt
< 0x01000000L
) {
5458 if (remain_cnt
> (unsigned long)(*(((unsigned long *)pCurrSCCB
->
5459 DataPointer
) + (sg_ptr
* 2)))) {
5461 remain_cnt
-= (unsigned long)(*(((unsigned long *)pCurrSCCB
->
5462 DataPointer
) + (sg_ptr
* 2)));
5473 if (remain_cnt
< 0x01000000L
) {
5476 pCurrSCCB
->Sccb_SGoffset
= remain_cnt
;
5478 pCurrSCCB
->Sccb_sgseg
= (unsigned short)sg_ptr
;
5481 if ((unsigned long)(sg_ptr
* SG_ELEMENT_SIZE
) == pCurrSCCB
->DataLength
5482 && (remain_cnt
== 0))
5484 pCurrSCCB
->Sccb_XferState
|= F_ALL_XFERRED
;
5490 if (pCurrSCCB
->HostStatus
== 0x00) {
5492 pCurrSCCB
->HostStatus
= SCCB_GROSS_FW_ERR
;
5498 if (!(pCurrSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
)) {
5501 if (RD_HARPOON(port
+hp_ext_status
) & BM_CMD_BUSY
) {
5503 FPT_busMstrTimeOut(port
);
5508 if (RD_HARPOON(port
+hp_int_status
) & INT_EXT_STATUS
) {
5510 if (RD_HARPOON(port
+hp_ext_status
) & BAD_EXT_STATUS
) {
5512 if (pCurrSCCB
->HostStatus
== 0x00) {
5514 pCurrSCCB
->HostStatus
= SCCB_BM_ERR
;
5525 if ((RD_HARPOON(port
+hp_fifo_cnt
)) >= BM_THRESHOLD
) {
5527 timeout
= SHORT_WAIT
;
5529 while ((RD_HARPOON(port
+hp_ext_status
) & BM_CMD_BUSY
) &&
5530 ((RD_HARPOON(port
+hp_fifo_cnt
)) >= BM_THRESHOLD
) &&
5534 if (RD_HARPOON(port
+hp_ext_status
) & BM_CMD_BUSY
) {
5536 WR_HARPOON(port
+hp_bm_ctrl
, (RD_HARPOON(port
+hp_bm_ctrl
) |
5539 timeout
= LONG_WAIT
;
5541 while ((RD_HARPOON(port
+hp_ext_status
) & BM_CMD_BUSY
) &&
5544 WR_HARPOON(port
+hp_bm_ctrl
, (RD_HARPOON(port
+hp_bm_ctrl
) &
5548 if (RD_HARPOON(port
+hp_ext_status
) & BM_CMD_BUSY
) {
5550 if (pCurrSCCB
->HostStatus
== 0x00) {
5552 pCurrSCCB
->HostStatus
= SCCB_BM_ERR
;
5555 FPT_busMstrTimeOut(port
);
5559 if (RD_HARPOON(port
+hp_int_status
) & INT_EXT_STATUS
) {
5561 if (RD_HARPOON(port
+hp_ext_status
) & BAD_EXT_STATUS
) {
5563 if (pCurrSCCB
->HostStatus
== 0x00) {
5565 pCurrSCCB
->HostStatus
= SCCB_BM_ERR
;
5576 if (RD_HARPOON(port
+hp_ext_status
) & BM_CMD_BUSY
) {
5578 timeout
= LONG_WAIT
;
5580 while ((RD_HARPOON(port
+hp_ext_status
) & BM_CMD_BUSY
) && timeout
--) {}
5582 if (RD_HARPOON(port
+hp_ext_status
) & BM_CMD_BUSY
) {
5584 if (pCurrSCCB
->HostStatus
== 0x00) {
5586 pCurrSCCB
->HostStatus
= SCCB_BM_ERR
;
5589 FPT_busMstrTimeOut(port
);
5594 if (RD_HARPOON(port
+hp_int_status
) & INT_EXT_STATUS
) {
5596 if (RD_HARPOON(port
+hp_ext_status
) & BAD_EXT_STATUS
) {
5598 if (pCurrSCCB
->HostStatus
== 0x00) {
5600 pCurrSCCB
->HostStatus
= SCCB_BM_ERR
;
5606 if (pCurrSCCB
->Sccb_XferState
& F_SG_XFER
) {
5608 WR_HARPOON(port
+hp_page_ctrl
, (RD_HARPOON(port
+hp_page_ctrl
) &
5611 WR_HARPOON(port
+hp_sg_addr
,0x00);
5613 pCurrSCCB
->Sccb_sgseg
+= SG_BUF_CNT
;
5615 pCurrSCCB
->Sccb_SGoffset
= 0x00;
5618 if ((unsigned long)(pCurrSCCB
->Sccb_sgseg
* SG_ELEMENT_SIZE
) >=
5619 pCurrSCCB
->DataLength
) {
5621 pCurrSCCB
->Sccb_XferState
|= F_ALL_XFERRED
;
5623 pCurrSCCB
->Sccb_sgseg
= (unsigned short)(pCurrSCCB
->DataLength
/ SG_ELEMENT_SIZE
);
5630 if (!(pCurrSCCB
->Sccb_XferState
& F_AUTO_SENSE
))
5632 pCurrSCCB
->Sccb_XferState
|= F_ALL_XFERRED
;
5636 WR_HARPOON(port
+hp_int_mask
,(INT_CMD_COMPL
| SCSI_INTERRUPT
));
5641 /*---------------------------------------------------------------------
5643 * Function: Host Data Transfer Restart
5645 * Description: Reset the available count due to a restore data
5648 *---------------------------------------------------------------------*/
5649 static void FPT_hostDataXferRestart(struct sccb
* currSCCB
)
5651 unsigned long data_count
;
5652 unsigned int sg_index
;
5653 unsigned long *sg_ptr
;
5655 if (currSCCB
->Sccb_XferState
& F_SG_XFER
) {
5657 currSCCB
->Sccb_XferCnt
= 0;
5659 sg_index
= 0xffff; /*Index by long words into sg list. */
5660 data_count
= 0; /*Running count of SG xfer counts. */
5662 sg_ptr
= (unsigned long *)currSCCB
->DataPointer
;
5664 while (data_count
< currSCCB
->Sccb_ATC
) {
5667 data_count
+= *(sg_ptr
+(sg_index
* 2));
5670 if (data_count
== currSCCB
->Sccb_ATC
) {
5672 currSCCB
->Sccb_SGoffset
= 0;
5677 currSCCB
->Sccb_SGoffset
= data_count
- currSCCB
->Sccb_ATC
;
5680 currSCCB
->Sccb_sgseg
= (unsigned short)sg_index
;
5684 currSCCB
->Sccb_XferCnt
= currSCCB
->DataLength
- currSCCB
->Sccb_ATC
;
5690 /*---------------------------------------------------------------------
5692 * Function: FPT_scini
5694 * Description: Setup all data structures necessary for SCAM selection.
5696 *---------------------------------------------------------------------*/
5698 static void FPT_scini(unsigned char p_card
, unsigned char p_our_id
, unsigned char p_power_up
)
5701 unsigned char loser
,assigned_id
;
5702 unsigned long p_port
;
5704 unsigned char i
,k
,ScamFlg
;
5706 PNVRamInfo pCurrNvRam
;
5708 currCard
= &FPT_BL_Card
[p_card
];
5709 p_port
= currCard
->ioPort
;
5710 pCurrNvRam
= currCard
->pNvRamInfo
;
5714 ScamFlg
= pCurrNvRam
->niScamConf
;
5715 i
= pCurrNvRam
->niSysConf
;
5718 ScamFlg
= (unsigned char) FPT_utilEERead(p_port
, SCAM_CONFIG
/2);
5719 i
= (unsigned char)(FPT_utilEERead(p_port
, (SYSTEM_CONFIG
/2)));
5721 if(!(i
& 0x02)) /* check if reset bus in AutoSCSI parameter set */
5724 FPT_inisci(p_card
,p_port
, p_our_id
);
5726 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5727 too slow to return to SCAM selection */
5730 FPT_Wait1Second(p_port);
5732 FPT_Wait(p_port, TO_250ms); */
5734 FPT_Wait1Second(p_port
);
5736 if ((ScamFlg
& SCAM_ENABLED
) && (ScamFlg
& SCAM_LEVEL2
))
5738 while (!(FPT_scarb(p_port
,INIT_SELTD
))) {}
5743 FPT_scxferc(p_port
,SYNC_PTRN
);
5744 FPT_scxferc(p_port
,DOM_MSTR
);
5745 loser
= FPT_scsendi(p_port
,&FPT_scamInfo
[p_our_id
].id_string
[0]);
5746 } while ( loser
== 0xFF );
5750 if ((p_power_up
) && (!loser
))
5752 FPT_sresb(p_port
,p_card
);
5753 FPT_Wait(p_port
, TO_250ms
);
5755 while (!(FPT_scarb(p_port
,INIT_SELTD
))) {}
5760 FPT_scxferc(p_port
, SYNC_PTRN
);
5761 FPT_scxferc(p_port
, DOM_MSTR
);
5762 loser
= FPT_scsendi(p_port
,&FPT_scamInfo
[p_our_id
].
5764 } while ( loser
== 0xFF );
5779 FPT_scamInfo
[p_our_id
].state
= ID_ASSIGNED
;
5782 if (ScamFlg
& SCAM_ENABLED
)
5785 for (i
=0; i
< MAX_SCSI_TAR
; i
++)
5787 if ((FPT_scamInfo
[i
].state
== ID_UNASSIGNED
) ||
5788 (FPT_scamInfo
[i
].state
== ID_UNUSED
))
5790 if (FPT_scsell(p_port
,i
))
5792 FPT_scamInfo
[i
].state
= LEGACY
;
5793 if ((FPT_scamInfo
[i
].id_string
[0] != 0xFF) ||
5794 (FPT_scamInfo
[i
].id_string
[1] != 0xFA))
5797 FPT_scamInfo
[i
].id_string
[0] = 0xFF;
5798 FPT_scamInfo
[i
].id_string
[1] = 0xFA;
5799 if(pCurrNvRam
== NULL
)
5800 currCard
->globalFlags
|= F_UPDATE_EEPROM
;
5806 FPT_sresb(p_port
,p_card
);
5807 FPT_Wait1Second(p_port
);
5808 while (!(FPT_scarb(p_port
,INIT_SELTD
))) {}
5810 FPT_scasid(p_card
, p_port
);
5815 else if ((loser
) && (ScamFlg
& SCAM_ENABLED
))
5817 FPT_scamInfo
[p_our_id
].id_string
[0] = SLV_TYPE_CODE0
;
5819 FPT_scwtsel(p_port
);
5822 while (FPT_scxferc(p_port
,0x00) != SYNC_PTRN
) {}
5824 i
= FPT_scxferc(p_port
,0x00);
5827 if (!(FPT_scsendi(p_port
,&FPT_scamInfo
[p_our_id
].id_string
[0])))
5829 i
= FPT_scxferc(p_port
,0x00);
5832 k
= FPT_scxferc(p_port
,0x00);
5837 ((unsigned char)(i
<<3)+(k
& (unsigned char)7)) & (unsigned char) 0x3F;
5838 FPT_inisci(p_card
, p_port
, p_our_id
);
5839 FPT_scamInfo
[currCard
->ourId
].state
= ID_ASSIGNED
;
5840 FPT_scamInfo
[currCard
->ourId
].id_string
[0]
5848 else if (i
== SET_P_FLAG
)
5850 if (!(FPT_scsendi(p_port
,
5851 &FPT_scamInfo
[p_our_id
].id_string
[0])))
5852 FPT_scamInfo
[p_our_id
].id_string
[0] |= 0x80;
5854 }while (!assigned_id
);
5856 while (FPT_scxferc(p_port
,0x00) != CFG_CMPLT
) {}
5859 if (ScamFlg
& SCAM_ENABLED
)
5862 if (currCard
->globalFlags
& F_UPDATE_EEPROM
)
5864 FPT_scsavdi(p_card
, p_port
);
5865 currCard
->globalFlags
&= ~F_UPDATE_EEPROM
;
5871 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5873 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5874 (FPT_scamInfo[i].state == LEGACY))
5879 currCard->globalFlags |= F_SINGLE_DEVICE;
5881 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5886 /*---------------------------------------------------------------------
5888 * Function: FPT_scarb
5890 * Description: Gain control of the bus and wait SCAM select time (250ms)
5892 *---------------------------------------------------------------------*/
5894 static int FPT_scarb(unsigned long p_port
, unsigned char p_sel_type
)
5896 if (p_sel_type
== INIT_SELTD
)
5899 while (RD_HARPOON(p_port
+hp_scsisig
) & (SCSI_SEL
| SCSI_BSY
)) {}
5902 if (RD_HARPOON(p_port
+hp_scsisig
) & SCSI_SEL
)
5905 if (RD_HARPOON(p_port
+hp_scsidata_0
) != 00)
5908 WR_HARPOON(p_port
+hp_scsisig
, (RD_HARPOON(p_port
+hp_scsisig
) | SCSI_BSY
));
5910 if (RD_HARPOON(p_port
+hp_scsisig
) & SCSI_SEL
) {
5912 WR_HARPOON(p_port
+hp_scsisig
, (RD_HARPOON(p_port
+hp_scsisig
) &
5918 WR_HARPOON(p_port
+hp_scsisig
, (RD_HARPOON(p_port
+hp_scsisig
) | SCSI_SEL
));
5920 if (RD_HARPOON(p_port
+hp_scsidata_0
) != 00) {
5922 WR_HARPOON(p_port
+hp_scsisig
, (RD_HARPOON(p_port
+hp_scsisig
) &
5923 ~(SCSI_BSY
| SCSI_SEL
)));
5929 WR_HARPOON(p_port
+hp_clkctrl_0
, (RD_HARPOON(p_port
+hp_clkctrl_0
)
5931 WR_HARPOON(p_port
+hp_scsireset
, SCAM_EN
);
5932 WR_HARPOON(p_port
+hp_scsidata_0
, 0x00);
5933 WR_HARPOON(p_port
+hp_scsidata_1
, 0x00);
5934 WR_HARPOON(p_port
+hp_portctrl_0
, SCSI_BUS_EN
);
5936 WR_HARPOON(p_port
+hp_scsisig
, (RD_HARPOON(p_port
+hp_scsisig
) | SCSI_MSG
));
5938 WR_HARPOON(p_port
+hp_scsisig
, (RD_HARPOON(p_port
+hp_scsisig
)
5941 FPT_Wait(p_port
,TO_250ms
);
5947 /*---------------------------------------------------------------------
5949 * Function: FPT_scbusf
5951 * Description: Release the SCSI bus and disable SCAM selection.
5953 *---------------------------------------------------------------------*/
5955 static void FPT_scbusf(unsigned long p_port
)
5957 WR_HARPOON(p_port
+hp_page_ctrl
,
5958 (RD_HARPOON(p_port
+hp_page_ctrl
) | G_INT_DISABLE
));
5961 WR_HARPOON(p_port
+hp_scsidata_0
, 0x00);
5963 WR_HARPOON(p_port
+hp_portctrl_0
, (RD_HARPOON(p_port
+hp_portctrl_0
)
5966 WR_HARPOON(p_port
+hp_scsisig
, 0x00);
5969 WR_HARPOON(p_port
+hp_scsireset
, (RD_HARPOON(p_port
+hp_scsireset
)
5972 WR_HARPOON(p_port
+hp_clkctrl_0
, (RD_HARPOON(p_port
+hp_clkctrl_0
)
5975 WRW_HARPOON((p_port
+hp_intstat
), (BUS_FREE
| AUTO_INT
| SCAM_SEL
));
5977 WR_HARPOON(p_port
+hp_page_ctrl
,
5978 (RD_HARPOON(p_port
+hp_page_ctrl
) & ~G_INT_DISABLE
));
5983 /*---------------------------------------------------------------------
5985 * Function: FPT_scasid
5987 * Description: Assign an ID to all the SCAM devices.
5989 *---------------------------------------------------------------------*/
5991 static void FPT_scasid(unsigned char p_card
, unsigned long p_port
)
5993 unsigned char temp_id_string
[ID_STRING_LENGTH
];
5995 unsigned char i
,k
,scam_id
;
5996 unsigned char crcBytes
[3];
5997 PNVRamInfo pCurrNvRam
;
5998 unsigned short * pCrcBytes
;
6000 pCurrNvRam
= FPT_BL_Card
[p_card
].pNvRamInfo
;
6007 for (k
=0; k
< ID_STRING_LENGTH
; k
++)
6009 temp_id_string
[k
] = (unsigned char) 0x00;
6012 FPT_scxferc(p_port
,SYNC_PTRN
);
6013 FPT_scxferc(p_port
,ASSIGN_ID
);
6015 if (!(FPT_sciso(p_port
,&temp_id_string
[0])))
6018 pCrcBytes
= (unsigned short *)&crcBytes
[0];
6019 *pCrcBytes
= FPT_CalcCrc16(&temp_id_string
[0]);
6020 crcBytes
[2] = FPT_CalcLrc(&temp_id_string
[0]);
6021 temp_id_string
[1] = crcBytes
[2];
6022 temp_id_string
[2] = crcBytes
[0];
6023 temp_id_string
[3] = crcBytes
[1];
6024 for(k
= 4; k
< ID_STRING_LENGTH
; k
++)
6025 temp_id_string
[k
] = (unsigned char) 0x00;
6027 i
= FPT_scmachid(p_card
,temp_id_string
);
6029 if (i
== CLR_PRIORITY
)
6031 FPT_scxferc(p_port
,MISC_CODE
);
6032 FPT_scxferc(p_port
,CLR_P_FLAG
);
6033 i
= 0; /*Not the last ID yet. */
6036 else if (i
!= NO_ID_AVAIL
)
6039 FPT_scxferc(p_port
,ID_0_7
);
6041 FPT_scxferc(p_port
,ID_8_F
);
6043 scam_id
= (i
& (unsigned char) 0x07);
6046 for (k
=1; k
< 0x08; k
<<= 1)
6048 scam_id
+= 0x08; /*Count number of zeros in DB0-3. */
6050 FPT_scxferc(p_port
,scam_id
);
6052 i
= 0; /*Not the last ID yet. */
6063 FPT_scxferc(p_port
,SYNC_PTRN
);
6064 FPT_scxferc(p_port
,CFG_CMPLT
);
6071 /*---------------------------------------------------------------------
6073 * Function: FPT_scsel
6075 * Description: Select all the SCAM devices.
6077 *---------------------------------------------------------------------*/
6079 static void FPT_scsel(unsigned long p_port
)
6082 WR_HARPOON(p_port
+hp_scsisig
, SCSI_SEL
);
6083 FPT_scwiros(p_port
, SCSI_MSG
);
6085 WR_HARPOON(p_port
+hp_scsisig
, (SCSI_SEL
| SCSI_BSY
));
6088 WR_HARPOON(p_port
+hp_scsisig
, (SCSI_SEL
| SCSI_BSY
| SCSI_IOBIT
| SCSI_CD
));
6089 WR_HARPOON(p_port
+hp_scsidata_0
, (unsigned char)(RD_HARPOON(p_port
+hp_scsidata_0
) |
6090 (unsigned char)(BIT(7)+BIT(6))));
6093 WR_HARPOON(p_port
+hp_scsisig
, (SCSI_BSY
| SCSI_IOBIT
| SCSI_CD
));
6094 FPT_scwiros(p_port
, SCSI_SEL
);
6096 WR_HARPOON(p_port
+hp_scsidata_0
, (unsigned char)(RD_HARPOON(p_port
+hp_scsidata_0
) &
6097 ~(unsigned char)BIT(6)));
6098 FPT_scwirod(p_port
, BIT(6));
6100 WR_HARPOON(p_port
+hp_scsisig
, (SCSI_SEL
| SCSI_BSY
| SCSI_IOBIT
| SCSI_CD
));
6105 /*---------------------------------------------------------------------
6107 * Function: FPT_scxferc
6109 * Description: Handshake the p_data (DB4-0) across the bus.
6111 *---------------------------------------------------------------------*/
6113 static unsigned char FPT_scxferc(unsigned long p_port
, unsigned char p_data
)
6115 unsigned char curr_data
, ret_data
;
6117 curr_data
= p_data
| BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6119 WR_HARPOON(p_port
+hp_scsidata_0
, curr_data
);
6121 curr_data
&= ~BIT(7);
6123 WR_HARPOON(p_port
+hp_scsidata_0
, curr_data
);
6125 FPT_scwirod(p_port
,BIT(7)); /*Wait for DB7 to be released. */
6126 while (!(RD_HARPOON(p_port
+hp_scsidata_0
) & BIT(5)));
6128 ret_data
= (RD_HARPOON(p_port
+hp_scsidata_0
) & (unsigned char) 0x1F);
6130 curr_data
|= BIT(6);
6132 WR_HARPOON(p_port
+hp_scsidata_0
, curr_data
);
6134 curr_data
&= ~BIT(5);
6136 WR_HARPOON(p_port
+hp_scsidata_0
, curr_data
);
6138 FPT_scwirod(p_port
,BIT(5)); /*Wait for DB5 to be released. */
6140 curr_data
&= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6141 curr_data
|= BIT(7);
6143 WR_HARPOON(p_port
+hp_scsidata_0
, curr_data
);
6145 curr_data
&= ~BIT(6);
6147 WR_HARPOON(p_port
+hp_scsidata_0
, curr_data
);
6149 FPT_scwirod(p_port
,BIT(6)); /*Wait for DB6 to be released. */
6155 /*---------------------------------------------------------------------
6157 * Function: FPT_scsendi
6159 * Description: Transfer our Identification string to determine if we
6160 * will be the dominant master.
6162 *---------------------------------------------------------------------*/
6164 static unsigned char FPT_scsendi(unsigned long p_port
, unsigned char p_id_string
[])
6166 unsigned char ret_data
,byte_cnt
,bit_cnt
,defer
;
6170 for (byte_cnt
= 0; byte_cnt
< ID_STRING_LENGTH
; byte_cnt
++) {
6172 for (bit_cnt
= 0x80; bit_cnt
!= 0 ; bit_cnt
>>= 1) {
6175 ret_data
= FPT_scxferc(p_port
,00);
6177 else if (p_id_string
[byte_cnt
] & bit_cnt
)
6179 ret_data
= FPT_scxferc(p_port
,02);
6183 ret_data
= FPT_scxferc(p_port
,01);
6188 if ((ret_data
& 0x1C) == 0x10)
6189 return(0x00); /*End of isolation stage, we won! */
6191 if (ret_data
& 0x1C)
6194 if ((defer
) && (!(ret_data
& 0x1F)))
6195 return(0x01); /*End of isolation stage, we lost. */
6202 return(0x01); /*We lost */
6204 return(0); /*We WON! Yeeessss! */
6209 /*---------------------------------------------------------------------
6211 * Function: FPT_sciso
6213 * Description: Transfer the Identification string.
6215 *---------------------------------------------------------------------*/
6217 static unsigned char FPT_sciso(unsigned long p_port
, unsigned char p_id_string
[])
6219 unsigned char ret_data
,the_data
,byte_cnt
,bit_cnt
;
6223 for (byte_cnt
= 0; byte_cnt
< ID_STRING_LENGTH
; byte_cnt
++) {
6225 for (bit_cnt
= 0; bit_cnt
< 8; bit_cnt
++) {
6227 ret_data
= FPT_scxferc(p_port
,0);
6229 if (ret_data
& 0xFC)
6235 if (ret_data
& BIT(1)) {
6240 if ((ret_data
& 0x1F) == 0)
6243 if(bit_cnt != 0 || bit_cnt != 8)
6247 FPT_scxferc(p_port, SYNC_PTRN);
6248 FPT_scxferc(p_port, ASSIGN_ID);
6260 p_id_string
[byte_cnt
] = the_data
;
6269 /*---------------------------------------------------------------------
6271 * Function: FPT_scwirod
6273 * Description: Sample the SCSI data bus making sure the signal has been
6274 * deasserted for the correct number of consecutive samples.
6276 *---------------------------------------------------------------------*/
6278 static void FPT_scwirod(unsigned long p_port
, unsigned char p_data_bit
)
6283 while ( i
< MAX_SCSI_TAR
) {
6285 if (RD_HARPOON(p_port
+hp_scsidata_0
) & p_data_bit
)
6298 /*---------------------------------------------------------------------
6300 * Function: FPT_scwiros
6302 * Description: Sample the SCSI Signal lines making sure the signal has been
6303 * deasserted for the correct number of consecutive samples.
6305 *---------------------------------------------------------------------*/
6307 static void FPT_scwiros(unsigned long p_port
, unsigned char p_data_bit
)
6312 while ( i
< MAX_SCSI_TAR
) {
6314 if (RD_HARPOON(p_port
+hp_scsisig
) & p_data_bit
)
6326 /*---------------------------------------------------------------------
6328 * Function: FPT_scvalq
6330 * Description: Make sure we received a valid data byte.
6332 *---------------------------------------------------------------------*/
6334 static unsigned char FPT_scvalq(unsigned char p_quintet
)
6336 unsigned char count
;
6338 for (count
=1; count
< 0x08; count
<<=1) {
6339 if (!(p_quintet
& count
))
6343 if (p_quintet
& 0x18)
6351 /*---------------------------------------------------------------------
6353 * Function: FPT_scsell
6355 * Description: Select the specified device ID using a selection timeout
6356 * less than 4ms. If somebody responds then it is a legacy
6357 * drive and this ID must be marked as such.
6359 *---------------------------------------------------------------------*/
6361 static unsigned char FPT_scsell(unsigned long p_port
, unsigned char targ_id
)
6365 WR_HARPOON(p_port
+hp_page_ctrl
,
6366 (RD_HARPOON(p_port
+hp_page_ctrl
) | G_INT_DISABLE
));
6368 ARAM_ACCESS(p_port
);
6370 WR_HARPOON(p_port
+hp_addstat
,(RD_HARPOON(p_port
+hp_addstat
) | SCAM_TIMER
));
6371 WR_HARPOON(p_port
+hp_seltimeout
,TO_4ms
);
6374 for (i
= p_port
+CMD_STRT
; i
< p_port
+CMD_STRT
+12; i
+=2) {
6375 WRW_HARPOON(i
, (MPM_OP
+ACOMMAND
));
6377 WRW_HARPOON(i
, (BRH_OP
+ALWAYS
+ NP
));
6379 WRW_HARPOON((p_port
+hp_intstat
),
6380 (RESET
| TIMEOUT
| SEL
| BUS_FREE
| AUTO_INT
));
6382 WR_HARPOON(p_port
+hp_select_id
, targ_id
);
6384 WR_HARPOON(p_port
+hp_portctrl_0
, SCSI_PORT
);
6385 WR_HARPOON(p_port
+hp_autostart_3
, (SELECT
| CMD_ONLY_STRT
));
6386 WR_HARPOON(p_port
+hp_scsictrl_0
, (SEL_TAR
| ENA_RESEL
));
6389 while (!(RDW_HARPOON((p_port
+hp_intstat
)) &
6390 (RESET
| PROG_HLT
| TIMEOUT
| AUTO_INT
))) {}
6392 if (RDW_HARPOON((p_port
+hp_intstat
)) & RESET
)
6393 FPT_Wait(p_port
, TO_250ms
);
6395 DISABLE_AUTO(p_port
);
6397 WR_HARPOON(p_port
+hp_addstat
,(RD_HARPOON(p_port
+hp_addstat
) & ~SCAM_TIMER
));
6398 WR_HARPOON(p_port
+hp_seltimeout
,TO_290ms
);
6400 SGRAM_ACCESS(p_port
);
6402 if (RDW_HARPOON((p_port
+hp_intstat
)) & (RESET
| TIMEOUT
) ) {
6404 WRW_HARPOON((p_port
+hp_intstat
),
6405 (RESET
| TIMEOUT
| SEL
| BUS_FREE
| PHASE
));
6407 WR_HARPOON(p_port
+hp_page_ctrl
,
6408 (RD_HARPOON(p_port
+hp_page_ctrl
) & ~G_INT_DISABLE
));
6410 return(0); /*No legacy device */
6415 while(!(RDW_HARPOON((p_port
+hp_intstat
)) & BUS_FREE
)) {
6416 if (RD_HARPOON(p_port
+hp_scsisig
) & SCSI_REQ
)
6418 WR_HARPOON(p_port
+hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
6423 WRW_HARPOON((p_port
+hp_intstat
), CLR_ALL_INT_1
);
6425 WR_HARPOON(p_port
+hp_page_ctrl
,
6426 (RD_HARPOON(p_port
+hp_page_ctrl
) & ~G_INT_DISABLE
));
6428 return(1); /*Found one of them oldies! */
6432 /*---------------------------------------------------------------------
6434 * Function: FPT_scwtsel
6436 * Description: Wait to be selected by another SCAM initiator.
6438 *---------------------------------------------------------------------*/
6440 static void FPT_scwtsel(unsigned long p_port
)
6442 while(!(RDW_HARPOON((p_port
+hp_intstat
)) & SCAM_SEL
)) {}
6446 /*---------------------------------------------------------------------
6448 * Function: FPT_inisci
6450 * Description: Setup the data Structure with the info from the EEPROM.
6452 *---------------------------------------------------------------------*/
6454 static void FPT_inisci(unsigned char p_card
, unsigned long p_port
, unsigned char p_our_id
)
6456 unsigned char i
,k
,max_id
;
6457 unsigned short ee_data
;
6458 PNVRamInfo pCurrNvRam
;
6460 pCurrNvRam
= FPT_BL_Card
[p_card
].pNvRamInfo
;
6462 if (RD_HARPOON(p_port
+hp_page_ctrl
) & NARROW_SCSI_CARD
)
6469 for(i
= 0; i
< max_id
; i
++){
6471 for(k
= 0; k
< 4; k
++)
6472 FPT_scamInfo
[i
].id_string
[k
] = pCurrNvRam
->niScamTbl
[i
][k
];
6473 for(k
= 4; k
< ID_STRING_LENGTH
; k
++)
6474 FPT_scamInfo
[i
].id_string
[k
] = (unsigned char) 0x00;
6476 if(FPT_scamInfo
[i
].id_string
[0] == 0x00)
6477 FPT_scamInfo
[i
].state
= ID_UNUSED
; /*Default to unused ID. */
6479 FPT_scamInfo
[i
].state
= ID_UNASSIGNED
; /*Default to unassigned ID. */
6483 for (i
=0; i
< max_id
; i
++)
6485 for (k
=0; k
< ID_STRING_LENGTH
; k
+=2)
6487 ee_data
= FPT_utilEERead(p_port
, (unsigned short)((EE_SCAMBASE
/2) +
6488 (unsigned short) (i
*((unsigned short)ID_STRING_LENGTH
/2)) + (unsigned short)(k
/2)));
6489 FPT_scamInfo
[i
].id_string
[k
] = (unsigned char) ee_data
;
6491 FPT_scamInfo
[i
].id_string
[k
+1] = (unsigned char) ee_data
;
6494 if ((FPT_scamInfo
[i
].id_string
[0] == 0x00) ||
6495 (FPT_scamInfo
[i
].id_string
[0] == 0xFF))
6497 FPT_scamInfo
[i
].state
= ID_UNUSED
; /*Default to unused ID. */
6500 FPT_scamInfo
[i
].state
= ID_UNASSIGNED
; /*Default to unassigned ID. */
6504 for(k
= 0; k
< ID_STRING_LENGTH
; k
++)
6505 FPT_scamInfo
[p_our_id
].id_string
[k
] = FPT_scamHAString
[k
];
6509 /*---------------------------------------------------------------------
6511 * Function: FPT_scmachid
6513 * Description: Match the Device ID string with our values stored in
6516 *---------------------------------------------------------------------*/
6518 static unsigned char FPT_scmachid(unsigned char p_card
, unsigned char p_id_string
[])
6521 unsigned char i
,k
,match
;
6524 for (i
=0; i
< MAX_SCSI_TAR
; i
++) {
6528 for (k
=0; k
< ID_STRING_LENGTH
; k
++)
6530 if (p_id_string
[k
] != FPT_scamInfo
[i
].id_string
[k
])
6536 FPT_scamInfo
[i
].state
= ID_ASSIGNED
;
6544 if (p_id_string
[0] & BIT(5))
6549 if (((p_id_string
[0] & 0x06) == 0x02) || ((p_id_string
[0] & 0x06) == 0x04))
6550 match
= p_id_string
[1] & (unsigned char) 0x1F;
6558 if (FPT_scamInfo
[match
].state
== ID_UNUSED
)
6560 for (k
=0; k
< ID_STRING_LENGTH
; k
++)
6562 FPT_scamInfo
[match
].id_string
[k
] = p_id_string
[k
];
6565 FPT_scamInfo
[match
].state
= ID_ASSIGNED
;
6567 if(FPT_BL_Card
[p_card
].pNvRamInfo
== NULL
)
6568 FPT_BL_Card
[p_card
].globalFlags
|= F_UPDATE_EEPROM
;
6578 if (p_id_string
[0] & BIT(5))
6581 match
= MAX_SCSI_TAR
-1;
6587 if (p_id_string
[0] & BIT(7))
6589 return(CLR_PRIORITY
);
6593 if (p_id_string
[0] & BIT(5))
6598 if (((p_id_string
[0] & 0x06) == 0x02) || ((p_id_string
[0] & 0x06) == 0x04))
6599 match
= p_id_string
[1] & (unsigned char) 0x1F;
6608 if (FPT_scamInfo
[match
].state
== ID_UNASSIGNED
)
6610 for (k
=0; k
< ID_STRING_LENGTH
; k
++)
6612 FPT_scamInfo
[match
].id_string
[k
] = p_id_string
[k
];
6615 FPT_scamInfo
[match
].id_string
[0] |= BIT(7);
6616 FPT_scamInfo
[match
].state
= ID_ASSIGNED
;
6617 if(FPT_BL_Card
[p_card
].pNvRamInfo
== NULL
)
6618 FPT_BL_Card
[p_card
].globalFlags
|= F_UPDATE_EEPROM
;
6628 if (p_id_string
[0] & BIT(5))
6631 match
= MAX_SCSI_TAR
-1;
6635 return(NO_ID_AVAIL
);
6639 /*---------------------------------------------------------------------
6641 * Function: FPT_scsavdi
6643 * Description: Save off the device SCAM ID strings.
6645 *---------------------------------------------------------------------*/
6647 static void FPT_scsavdi(unsigned char p_card
, unsigned long p_port
)
6649 unsigned char i
,k
,max_id
;
6650 unsigned short ee_data
,sum_data
;
6655 for (i
= 1; i
< EE_SCAMBASE
/2; i
++)
6657 sum_data
+= FPT_utilEERead(p_port
, i
);
6661 FPT_utilEEWriteOnOff(p_port
,1); /* Enable write access to the EEPROM */
6663 if (RD_HARPOON(p_port
+hp_page_ctrl
) & NARROW_SCSI_CARD
)
6669 for (i
=0; i
< max_id
; i
++)
6672 for (k
=0; k
< ID_STRING_LENGTH
; k
+=2)
6674 ee_data
= FPT_scamInfo
[i
].id_string
[k
+1];
6676 ee_data
|= FPT_scamInfo
[i
].id_string
[k
];
6677 sum_data
+= ee_data
;
6678 FPT_utilEEWrite(p_port
, ee_data
, (unsigned short)((EE_SCAMBASE
/2) +
6679 (unsigned short)(i
*((unsigned short)ID_STRING_LENGTH
/2)) + (unsigned short)(k
/2)));
6684 FPT_utilEEWrite(p_port
, sum_data
, EEPROM_CHECK_SUM
/2);
6685 FPT_utilEEWriteOnOff(p_port
,0); /* Turn off write access */
6688 /*---------------------------------------------------------------------
6690 * Function: FPT_XbowInit
6692 * Description: Setup the Xbow for normal operation.
6694 *---------------------------------------------------------------------*/
6696 static void FPT_XbowInit(unsigned long port
, unsigned char ScamFlg
)
6700 i
= RD_HARPOON(port
+hp_page_ctrl
);
6701 WR_HARPOON(port
+hp_page_ctrl
, (unsigned char) (i
| G_INT_DISABLE
));
6703 WR_HARPOON(port
+hp_scsireset
,0x00);
6704 WR_HARPOON(port
+hp_portctrl_1
,HOST_MODE8
);
6706 WR_HARPOON(port
+hp_scsireset
,(DMA_RESET
| HPSCSI_RESET
| PROG_RESET
| \
6709 WR_HARPOON(port
+hp_scsireset
,SCSI_INI
);
6711 WR_HARPOON(port
+hp_clkctrl_0
,CLKCTRL_DEFAULT
);
6713 WR_HARPOON(port
+hp_scsisig
,0x00); /* Clear any signals we might */
6714 WR_HARPOON(port
+hp_scsictrl_0
,ENA_SCAM_SEL
);
6716 WRW_HARPOON((port
+hp_intstat
), CLR_ALL_INT
);
6718 FPT_default_intena
= RESET
| RSEL
| PROG_HLT
| TIMEOUT
|
6719 BUS_FREE
| XFER_CNT_0
| AUTO_INT
;
6721 if ((ScamFlg
& SCAM_ENABLED
) && (ScamFlg
& SCAM_LEVEL2
))
6722 FPT_default_intena
|= SCAM_SEL
;
6724 WRW_HARPOON((port
+hp_intena
), FPT_default_intena
);
6726 WR_HARPOON(port
+hp_seltimeout
,TO_290ms
);
6728 /* Turn on SCSI_MODE8 for narrow cards to fix the
6729 strapping issue with the DUAL CHANNEL card */
6730 if (RD_HARPOON(port
+hp_page_ctrl
) & NARROW_SCSI_CARD
)
6731 WR_HARPOON(port
+hp_addstat
,SCSI_MODE8
);
6733 WR_HARPOON(port
+hp_page_ctrl
, i
);
6738 /*---------------------------------------------------------------------
6740 * Function: FPT_BusMasterInit
6742 * Description: Initialize the BusMaster for normal operations.
6744 *---------------------------------------------------------------------*/
6746 static void FPT_BusMasterInit(unsigned long p_port
)
6750 WR_HARPOON(p_port
+hp_sys_ctrl
, DRVR_RST
);
6751 WR_HARPOON(p_port
+hp_sys_ctrl
, 0x00);
6753 WR_HARPOON(p_port
+hp_host_blk_cnt
, XFER_BLK64
);
6756 WR_HARPOON(p_port
+hp_bm_ctrl
, (BMCTRL_DEFAULT
));
6758 WR_HARPOON(p_port
+hp_ee_ctrl
, (SCSI_TERM_ENA_H
));
6761 RD_HARPOON(p_port
+hp_int_status
); /*Clear interrupts. */
6762 WR_HARPOON(p_port
+hp_int_mask
, (INT_CMD_COMPL
| SCSI_INTERRUPT
));
6763 WR_HARPOON(p_port
+hp_page_ctrl
, (RD_HARPOON(p_port
+hp_page_ctrl
) &
6768 /*---------------------------------------------------------------------
6770 * Function: FPT_DiagEEPROM
6772 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6775 *---------------------------------------------------------------------*/
6777 static void FPT_DiagEEPROM(unsigned long p_port
)
6779 unsigned short index
,temp
,max_wd_cnt
;
6781 if (RD_HARPOON(p_port
+hp_page_ctrl
) & NARROW_SCSI_CARD
)
6782 max_wd_cnt
= EEPROM_WD_CNT
;
6784 max_wd_cnt
= EEPROM_WD_CNT
* 2;
6786 temp
= FPT_utilEERead(p_port
, FW_SIGNATURE
/2);
6788 if (temp
== 0x4641) {
6790 for (index
= 2; index
< max_wd_cnt
; index
++) {
6792 temp
+= FPT_utilEERead(p_port
, index
);
6796 if (temp
== FPT_utilEERead(p_port
, EEPROM_CHECK_SUM
/2)) {
6798 return; /*EEPROM is Okay so return now! */
6803 FPT_utilEEWriteOnOff(p_port
,(unsigned char)1);
6805 for (index
= 0; index
< max_wd_cnt
; index
++) {
6807 FPT_utilEEWrite(p_port
, 0x0000, index
);
6812 FPT_utilEEWrite(p_port
, 0x4641, FW_SIGNATURE
/2);
6814 FPT_utilEEWrite(p_port
, 0x3920, MODEL_NUMB_0
/2);
6816 FPT_utilEEWrite(p_port
, 0x3033, MODEL_NUMB_2
/2);
6818 FPT_utilEEWrite(p_port
, 0x2020, MODEL_NUMB_4
/2);
6820 FPT_utilEEWrite(p_port
, 0x70D3, SYSTEM_CONFIG
/2);
6822 FPT_utilEEWrite(p_port
, 0x0010, BIOS_CONFIG
/2);
6824 FPT_utilEEWrite(p_port
, 0x0003, SCAM_CONFIG
/2);
6826 FPT_utilEEWrite(p_port
, 0x0007, ADAPTER_SCSI_ID
/2);
6829 FPT_utilEEWrite(p_port
, 0x0000, IGNORE_B_SCAN
/2);
6831 FPT_utilEEWrite(p_port
, 0x0000, SEND_START_ENA
/2);
6833 FPT_utilEEWrite(p_port
, 0x0000, DEVICE_ENABLE
/2);
6836 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL01
/2);
6838 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL23
/2);
6840 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL45
/2);
6842 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL67
/2);
6844 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL89
/2);
6846 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBLab
/2);
6848 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBLcd
/2);
6850 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBLef
/2);
6854 FPT_utilEEWrite(p_port
, 0x6C46, 64/2); /*PRODUCT ID */
6856 FPT_utilEEWrite(p_port
, 0x7361, 66/2); /* FlashPoint LT */
6858 FPT_utilEEWrite(p_port
, 0x5068, 68/2);
6860 FPT_utilEEWrite(p_port
, 0x696F, 70/2);
6862 FPT_utilEEWrite(p_port
, 0x746E, 72/2);
6864 FPT_utilEEWrite(p_port
, 0x4C20, 74/2);
6866 FPT_utilEEWrite(p_port
, 0x2054, 76/2);
6868 FPT_utilEEWrite(p_port
, 0x2020, 78/2);
6871 index
= ((EE_SCAMBASE
/2)+(7*16));
6872 FPT_utilEEWrite(p_port
, (0x0700+TYPE_CODE0
), index
);
6873 temp
+= (0x0700+TYPE_CODE0
);
6875 FPT_utilEEWrite(p_port
, 0x5542, index
); /*Vendor ID code */
6876 temp
+= 0x5542; /* BUSLOGIC */
6878 FPT_utilEEWrite(p_port
, 0x4C53, index
);
6881 FPT_utilEEWrite(p_port
, 0x474F, index
);
6884 FPT_utilEEWrite(p_port
, 0x4349, index
);
6887 FPT_utilEEWrite(p_port
, 0x5442, index
); /*Vendor unique code */
6888 temp
+= 0x5442; /* BT- 930 */
6890 FPT_utilEEWrite(p_port
, 0x202D, index
);
6893 FPT_utilEEWrite(p_port
, 0x3339, index
);
6895 index
++; /*Serial # */
6896 FPT_utilEEWrite(p_port
, 0x2030, index
); /* 01234567 */
6899 FPT_utilEEWrite(p_port
, 0x5453, index
);
6902 FPT_utilEEWrite(p_port
, 0x5645, index
);
6905 FPT_utilEEWrite(p_port
, 0x2045, index
);
6908 FPT_utilEEWrite(p_port
, 0x202F, index
);
6911 FPT_utilEEWrite(p_port
, 0x4F4A, index
);
6914 FPT_utilEEWrite(p_port
, 0x204E, index
);
6917 FPT_utilEEWrite(p_port
, 0x3539, index
);
6922 FPT_utilEEWrite(p_port
, temp
, EEPROM_CHECK_SUM
/2);
6924 FPT_utilEEWriteOnOff(p_port
,(unsigned char)0);
6929 /*---------------------------------------------------------------------
6931 * Function: Queue Search Select
6933 * Description: Try to find a new command to execute.
6935 *---------------------------------------------------------------------*/
6937 static void FPT_queueSearchSelect(PSCCBcard pCurrCard
, unsigned char p_card
)
6939 unsigned char scan_ptr
, lun
;
6940 PSCCBMgr_tar_info currTar_Info
;
6941 struct sccb
* pOldSccb
;
6943 scan_ptr
= pCurrCard
->scanIndex
;
6946 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][scan_ptr
];
6947 if((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
6948 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
6950 if (currTar_Info
->TarSelQ_Cnt
!= 0)
6954 if (scan_ptr
== MAX_SCSI_TAR
)
6957 for(lun
=0; lun
< MAX_LUN
; lun
++)
6959 if(currTar_Info
->TarLUNBusy
[lun
] == 0)
6962 pCurrCard
->currentSCCB
= currTar_Info
->TarSelQ_Head
;
6965 while((pCurrCard
->currentSCCB
!= NULL
) &&
6966 (lun
!= pCurrCard
->currentSCCB
->Lun
))
6968 pOldSccb
= pCurrCard
->currentSCCB
;
6969 pCurrCard
->currentSCCB
= (struct sccb
*)(pCurrCard
->currentSCCB
)->
6972 if(pCurrCard
->currentSCCB
== NULL
)
6974 if(pOldSccb
!= NULL
)
6976 pOldSccb
->Sccb_forwardlink
= (struct sccb
*)(pCurrCard
->currentSCCB
)->
6978 pOldSccb
->Sccb_backlink
= (struct sccb
*)(pCurrCard
->currentSCCB
)->
6980 currTar_Info
->TarSelQ_Cnt
--;
6984 currTar_Info
->TarSelQ_Head
= (struct sccb
*)(pCurrCard
->currentSCCB
)->Sccb_forwardlink
;
6986 if (currTar_Info
->TarSelQ_Head
== NULL
)
6988 currTar_Info
->TarSelQ_Tail
= NULL
;
6989 currTar_Info
->TarSelQ_Cnt
= 0;
6993 currTar_Info
->TarSelQ_Cnt
--;
6994 currTar_Info
->TarSelQ_Head
->Sccb_backlink
= (struct sccb
*)NULL
;
6997 pCurrCard
->scanIndex
= scan_ptr
;
6999 pCurrCard
->globalFlags
|= F_NEW_SCCB_CMD
;
7009 if (scan_ptr
== MAX_SCSI_TAR
) {
7017 if ((currTar_Info
->TarSelQ_Cnt
!= 0) &&
7018 (currTar_Info
->TarLUNBusy
[0] == 0))
7021 pCurrCard
->currentSCCB
= currTar_Info
->TarSelQ_Head
;
7023 currTar_Info
->TarSelQ_Head
= (struct sccb
*)(pCurrCard
->currentSCCB
)->Sccb_forwardlink
;
7025 if (currTar_Info
->TarSelQ_Head
== NULL
)
7027 currTar_Info
->TarSelQ_Tail
= NULL
;
7028 currTar_Info
->TarSelQ_Cnt
= 0;
7032 currTar_Info
->TarSelQ_Cnt
--;
7033 currTar_Info
->TarSelQ_Head
->Sccb_backlink
= (struct sccb
*)NULL
;
7037 if (scan_ptr
== MAX_SCSI_TAR
)
7040 pCurrCard
->scanIndex
= scan_ptr
;
7042 pCurrCard
->globalFlags
|= F_NEW_SCCB_CMD
;
7050 if (scan_ptr
== MAX_SCSI_TAR
)
7056 } while (scan_ptr
!= pCurrCard
->scanIndex
);
7060 /*---------------------------------------------------------------------
7062 * Function: Queue Select Fail
7064 * Description: Add the current SCCB to the head of the Queue.
7066 *---------------------------------------------------------------------*/
7068 static void FPT_queueSelectFail(PSCCBcard pCurrCard
, unsigned char p_card
)
7070 unsigned char thisTarg
;
7071 PSCCBMgr_tar_info currTar_Info
;
7073 if (pCurrCard
->currentSCCB
!= NULL
)
7075 thisTarg
= (unsigned char)(((struct sccb
*)(pCurrCard
->currentSCCB
))->TargID
);
7076 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][thisTarg
];
7078 pCurrCard
->currentSCCB
->Sccb_backlink
= (struct sccb
*)NULL
;
7080 pCurrCard
->currentSCCB
->Sccb_forwardlink
= currTar_Info
->TarSelQ_Head
;
7082 if (currTar_Info
->TarSelQ_Cnt
== 0)
7084 currTar_Info
->TarSelQ_Tail
= pCurrCard
->currentSCCB
;
7089 currTar_Info
->TarSelQ_Head
->Sccb_backlink
= pCurrCard
->currentSCCB
;
7093 currTar_Info
->TarSelQ_Head
= pCurrCard
->currentSCCB
;
7095 pCurrCard
->currentSCCB
= NULL
;
7096 currTar_Info
->TarSelQ_Cnt
++;
7099 /*---------------------------------------------------------------------
7101 * Function: Queue Command Complete
7103 * Description: Call the callback function with the current SCCB.
7105 *---------------------------------------------------------------------*/
7107 static void FPT_queueCmdComplete(PSCCBcard pCurrCard
, struct sccb
* p_sccb
,
7108 unsigned char p_card
)
7111 unsigned char i
, SCSIcmd
;
7112 CALL_BK_FN callback
;
7113 PSCCBMgr_tar_info currTar_Info
;
7115 SCSIcmd
= p_sccb
->Cdb
[0];
7118 if (!(p_sccb
->Sccb_XferState
& F_ALL_XFERRED
)) {
7120 if ((p_sccb
->ControlByte
& (SCCB_DATA_XFER_OUT
| SCCB_DATA_XFER_IN
)) &&
7121 (p_sccb
->HostStatus
== SCCB_COMPLETE
) &&
7122 (p_sccb
->TargetStatus
!= SSCHECK
))
7124 if ((SCSIcmd
== SCSI_READ
) ||
7125 (SCSIcmd
== SCSI_WRITE
) ||
7126 (SCSIcmd
== SCSI_READ_EXTENDED
) ||
7127 (SCSIcmd
== SCSI_WRITE_EXTENDED
) ||
7128 (SCSIcmd
== SCSI_WRITE_AND_VERIFY
) ||
7129 (SCSIcmd
== SCSI_START_STOP_UNIT
) ||
7130 (pCurrCard
->globalFlags
& F_NO_FILTER
)
7132 p_sccb
->HostStatus
= SCCB_DATA_UNDER_RUN
;
7136 if(p_sccb
->SccbStatus
== SCCB_IN_PROCESS
)
7138 if (p_sccb
->HostStatus
|| p_sccb
->TargetStatus
)
7139 p_sccb
->SccbStatus
= SCCB_ERROR
;
7141 p_sccb
->SccbStatus
= SCCB_SUCCESS
;
7144 if (p_sccb
->Sccb_XferState
& F_AUTO_SENSE
) {
7146 p_sccb
->CdbLength
= p_sccb
->Save_CdbLen
;
7147 for (i
=0; i
< 6; i
++) {
7148 p_sccb
->Cdb
[i
] = p_sccb
->Save_Cdb
[i
];
7152 if ((p_sccb
->OperationCode
== RESIDUAL_SG_COMMAND
) ||
7153 (p_sccb
->OperationCode
== RESIDUAL_COMMAND
)) {
7155 FPT_utilUpdateResidual(p_sccb
);
7158 pCurrCard
->cmdCounter
--;
7159 if (!pCurrCard
->cmdCounter
) {
7161 if (pCurrCard
->globalFlags
& F_GREEN_PC
) {
7162 WR_HARPOON(pCurrCard
->ioPort
+hp_clkctrl_0
,(PWR_DWN
| CLKCTRL_DEFAULT
));
7163 WR_HARPOON(pCurrCard
->ioPort
+hp_sys_ctrl
, STOP_CLK
);
7166 WR_HARPOON(pCurrCard
->ioPort
+hp_semaphore
,
7167 (RD_HARPOON(pCurrCard
->ioPort
+hp_semaphore
) & ~SCCB_MGR_ACTIVE
));
7171 if(pCurrCard
->discQCount
!= 0)
7173 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
];
7174 if(((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
7175 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
)))
7177 pCurrCard
->discQCount
--;
7178 pCurrCard
->discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[p_sccb
->Lun
]] = NULL
;
7182 if(p_sccb
->Sccb_tag
)
7184 pCurrCard
->discQCount
--;
7185 pCurrCard
->discQ_Tbl
[p_sccb
->Sccb_tag
] = NULL
;
7188 pCurrCard
->discQCount
--;
7189 pCurrCard
->discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[0]] = NULL
;
7195 callback
= (CALL_BK_FN
)p_sccb
->SccbCallback
;
7197 pCurrCard
->globalFlags
|= F_NEW_SCCB_CMD
;
7198 pCurrCard
->currentSCCB
= NULL
;
7202 /*---------------------------------------------------------------------
7204 * Function: Queue Disconnect
7206 * Description: Add SCCB to our disconnect array.
7208 *---------------------------------------------------------------------*/
7209 static void FPT_queueDisconnect(struct sccb
* p_sccb
, unsigned char p_card
)
7211 PSCCBMgr_tar_info currTar_Info
;
7213 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
];
7215 if(((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
7216 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
)))
7218 FPT_BL_Card
[p_card
].discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[p_sccb
->Lun
]] = p_sccb
;
7222 if (p_sccb
->Sccb_tag
)
7224 FPT_BL_Card
[p_card
].discQ_Tbl
[p_sccb
->Sccb_tag
] = p_sccb
;
7225 FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
].TarLUNBusy
[0] = 0;
7226 FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
].TarTagQ_Cnt
++;
7229 FPT_BL_Card
[p_card
].discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[0]] = p_sccb
;
7232 FPT_BL_Card
[p_card
].currentSCCB
= NULL
;
7236 /*---------------------------------------------------------------------
7238 * Function: Queue Flush SCCB
7240 * Description: Flush all SCCB's back to the host driver for this target.
7242 *---------------------------------------------------------------------*/
7244 static void FPT_queueFlushSccb(unsigned char p_card
, unsigned char error_code
)
7246 unsigned char qtag
,thisTarg
;
7247 struct sccb
* currSCCB
;
7248 PSCCBMgr_tar_info currTar_Info
;
7250 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
7251 if(currSCCB
!= NULL
)
7253 thisTarg
= (unsigned char)currSCCB
->TargID
;
7254 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][thisTarg
];
7256 for (qtag
=0; qtag
<QUEUE_DEPTH
; qtag
++) {
7258 if (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] &&
7259 (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->TargID
== thisTarg
))
7262 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->HostStatus
= (unsigned char)error_code
;
7264 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
],FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
], p_card
);
7266 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] = NULL
;
7267 currTar_Info
->TarTagQ_Cnt
--;
7275 /*---------------------------------------------------------------------
7277 * Function: Queue Flush Target SCCB
7279 * Description: Flush all SCCB's back to the host driver for this target.
7281 *---------------------------------------------------------------------*/
7283 static void FPT_queueFlushTargSccb(unsigned char p_card
, unsigned char thisTarg
,
7284 unsigned char error_code
)
7287 PSCCBMgr_tar_info currTar_Info
;
7289 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][thisTarg
];
7291 for (qtag
=0; qtag
<QUEUE_DEPTH
; qtag
++) {
7293 if (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] &&
7294 (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->TargID
== thisTarg
))
7297 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->HostStatus
= (unsigned char)error_code
;
7299 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
],FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
], p_card
);
7301 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] = NULL
;
7302 currTar_Info
->TarTagQ_Cnt
--;
7313 static void FPT_queueAddSccb(struct sccb
* p_SCCB
, unsigned char p_card
)
7315 PSCCBMgr_tar_info currTar_Info
;
7316 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_SCCB
->TargID
];
7318 p_SCCB
->Sccb_forwardlink
= NULL
;
7320 p_SCCB
->Sccb_backlink
= currTar_Info
->TarSelQ_Tail
;
7322 if (currTar_Info
->TarSelQ_Cnt
== 0) {
7324 currTar_Info
->TarSelQ_Head
= p_SCCB
;
7329 currTar_Info
->TarSelQ_Tail
->Sccb_forwardlink
= p_SCCB
;
7333 currTar_Info
->TarSelQ_Tail
= p_SCCB
;
7334 currTar_Info
->TarSelQ_Cnt
++;
7338 /*---------------------------------------------------------------------
7340 * Function: Queue Find SCCB
7342 * Description: Search the target select Queue for this SCCB, and
7343 * remove it if found.
7345 *---------------------------------------------------------------------*/
7347 static unsigned char FPT_queueFindSccb(struct sccb
* p_SCCB
, unsigned char p_card
)
7349 struct sccb
* q_ptr
;
7350 PSCCBMgr_tar_info currTar_Info
;
7352 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_SCCB
->TargID
];
7354 q_ptr
= currTar_Info
->TarSelQ_Head
;
7356 while(q_ptr
!= NULL
) {
7358 if (q_ptr
== p_SCCB
) {
7361 if (currTar_Info
->TarSelQ_Head
== q_ptr
) {
7363 currTar_Info
->TarSelQ_Head
= q_ptr
->Sccb_forwardlink
;
7366 if (currTar_Info
->TarSelQ_Tail
== q_ptr
) {
7368 currTar_Info
->TarSelQ_Tail
= q_ptr
->Sccb_backlink
;
7371 if (q_ptr
->Sccb_forwardlink
!= NULL
) {
7372 q_ptr
->Sccb_forwardlink
->Sccb_backlink
= q_ptr
->Sccb_backlink
;
7375 if (q_ptr
->Sccb_backlink
!= NULL
) {
7376 q_ptr
->Sccb_backlink
->Sccb_forwardlink
= q_ptr
->Sccb_forwardlink
;
7379 currTar_Info
->TarSelQ_Cnt
--;
7385 q_ptr
= q_ptr
->Sccb_forwardlink
;
7395 /*---------------------------------------------------------------------
7397 * Function: Utility Update Residual Count
7399 * Description: Update the XferCnt to the remaining byte count.
7400 * If we transferred all the data then just write zero.
7401 * If Non-SG transfer then report Total Cnt - Actual Transfer
7402 * Cnt. For SG transfers add the count fields of all
7403 * remaining SG elements, as well as any partial remaining
7406 *---------------------------------------------------------------------*/
7408 static void FPT_utilUpdateResidual(struct sccb
* p_SCCB
)
7410 unsigned long partial_cnt
;
7411 unsigned int sg_index
;
7412 unsigned long *sg_ptr
;
7414 if (p_SCCB
->Sccb_XferState
& F_ALL_XFERRED
) {
7416 p_SCCB
->DataLength
= 0x0000;
7419 else if (p_SCCB
->Sccb_XferState
& F_SG_XFER
) {
7421 partial_cnt
= 0x0000;
7423 sg_index
= p_SCCB
->Sccb_sgseg
;
7425 sg_ptr
= (unsigned long *)p_SCCB
->DataPointer
;
7427 if (p_SCCB
->Sccb_SGoffset
) {
7429 partial_cnt
= p_SCCB
->Sccb_SGoffset
;
7433 while ( ((unsigned long)sg_index
* (unsigned long)SG_ELEMENT_SIZE
) <
7434 p_SCCB
->DataLength
) {
7436 partial_cnt
+= *(sg_ptr
+(sg_index
* 2));
7440 p_SCCB
->DataLength
= partial_cnt
;
7445 p_SCCB
->DataLength
-= p_SCCB
->Sccb_ATC
;
7450 /*---------------------------------------------------------------------
7452 * Function: Wait 1 Second
7454 * Description: Wait for 1 second.
7456 *---------------------------------------------------------------------*/
7458 static void FPT_Wait1Second(unsigned long p_port
)
7462 for(i
=0; i
< 4; i
++) {
7464 FPT_Wait(p_port
, TO_250ms
);
7466 if ((RD_HARPOON(p_port
+hp_scsictrl_0
) & SCSI_RST
))
7469 if((RDW_HARPOON((p_port
+hp_intstat
)) & SCAM_SEL
))
7475 /*---------------------------------------------------------------------
7477 * Function: FPT_Wait
7479 * Description: Wait the desired delay.
7481 *---------------------------------------------------------------------*/
7483 static void FPT_Wait(unsigned long p_port
, unsigned char p_delay
)
7485 unsigned char old_timer
;
7486 unsigned char green_flag
;
7488 old_timer
= RD_HARPOON(p_port
+hp_seltimeout
);
7490 green_flag
=RD_HARPOON(p_port
+hp_clkctrl_0
);
7491 WR_HARPOON(p_port
+hp_clkctrl_0
, CLKCTRL_DEFAULT
);
7493 WR_HARPOON(p_port
+hp_seltimeout
,p_delay
);
7494 WRW_HARPOON((p_port
+hp_intstat
), TIMEOUT
);
7495 WRW_HARPOON((p_port
+hp_intena
), (FPT_default_intena
& ~TIMEOUT
));
7498 WR_HARPOON(p_port
+hp_portctrl_0
,
7499 (RD_HARPOON(p_port
+hp_portctrl_0
) | START_TO
));
7501 while (!(RDW_HARPOON((p_port
+hp_intstat
)) & TIMEOUT
)) {
7503 if ((RD_HARPOON(p_port
+hp_scsictrl_0
) & SCSI_RST
))
7506 if ((RDW_HARPOON((p_port
+hp_intstat
)) & SCAM_SEL
))
7510 WR_HARPOON(p_port
+hp_portctrl_0
,
7511 (RD_HARPOON(p_port
+hp_portctrl_0
) & ~START_TO
));
7513 WRW_HARPOON((p_port
+hp_intstat
), TIMEOUT
);
7514 WRW_HARPOON((p_port
+hp_intena
), FPT_default_intena
);
7516 WR_HARPOON(p_port
+hp_clkctrl_0
,green_flag
);
7518 WR_HARPOON(p_port
+hp_seltimeout
,old_timer
);
7522 /*---------------------------------------------------------------------
7524 * Function: Enable/Disable Write to EEPROM
7526 * Description: The EEPROM must first be enabled for writes
7527 * A total of 9 clocks are needed.
7529 *---------------------------------------------------------------------*/
7531 static void FPT_utilEEWriteOnOff(unsigned long p_port
,unsigned char p_mode
)
7533 unsigned char ee_value
;
7535 ee_value
= (unsigned char)(RD_HARPOON(p_port
+hp_ee_ctrl
) & (EXT_ARB_ACK
| SCSI_TERM_ENA_H
));
7539 FPT_utilEESendCmdAddr(p_port
, EWEN
, EWEN_ADDR
);
7544 FPT_utilEESendCmdAddr(p_port
, EWDS
, EWDS_ADDR
);
7546 WR_HARPOON(p_port
+hp_ee_ctrl
, (ee_value
| SEE_MS
)); /*Turn off CS */
7547 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
); /*Turn off Master Select */
7551 /*---------------------------------------------------------------------
7553 * Function: Write EEPROM
7555 * Description: Write a word to the EEPROM at the specified
7558 *---------------------------------------------------------------------*/
7560 static void FPT_utilEEWrite(unsigned long p_port
, unsigned short ee_data
, unsigned short ee_addr
)
7563 unsigned char ee_value
;
7566 ee_value
= (unsigned char)((RD_HARPOON(p_port
+hp_ee_ctrl
) & (EXT_ARB_ACK
| SCSI_TERM_ENA_H
))|
7571 FPT_utilEESendCmdAddr(p_port
, EE_WRITE
, ee_addr
);
7574 ee_value
|= (SEE_MS
+ SEE_CS
);
7576 for(i
= 0x8000; i
!= 0; i
>>=1) {
7581 ee_value
&= ~SEE_DO
;
7583 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7584 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7585 ee_value
|= SEE_CLK
; /* Clock data! */
7586 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7587 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7588 ee_value
&= ~SEE_CLK
;
7589 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7590 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7592 ee_value
&= (EXT_ARB_ACK
| SCSI_TERM_ENA_H
);
7593 WR_HARPOON(p_port
+hp_ee_ctrl
, (ee_value
| SEE_MS
));
7595 FPT_Wait(p_port
, TO_10ms
);
7597 WR_HARPOON(p_port
+hp_ee_ctrl
, (ee_value
| SEE_MS
| SEE_CS
)); /* Set CS to EEPROM */
7598 WR_HARPOON(p_port
+hp_ee_ctrl
, (ee_value
| SEE_MS
)); /* Turn off CS */
7599 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
); /* Turn off Master Select */
7602 /*---------------------------------------------------------------------
7604 * Function: Read EEPROM
7606 * Description: Read a word from the EEPROM at the desired
7609 *---------------------------------------------------------------------*/
7611 static unsigned short FPT_utilEERead(unsigned long p_port
, unsigned short ee_addr
)
7613 unsigned short i
, ee_data1
, ee_data2
;
7616 ee_data1
= FPT_utilEEReadOrg(p_port
, ee_addr
);
7619 ee_data2
= FPT_utilEEReadOrg(p_port
, ee_addr
);
7621 if(ee_data1
== ee_data2
)
7624 ee_data1
= ee_data2
;
7632 /*---------------------------------------------------------------------
7634 * Function: Read EEPROM Original
7636 * Description: Read a word from the EEPROM at the desired
7639 *---------------------------------------------------------------------*/
7641 static unsigned short FPT_utilEEReadOrg(unsigned long p_port
, unsigned short ee_addr
)
7644 unsigned char ee_value
;
7645 unsigned short i
, ee_data
;
7647 ee_value
= (unsigned char)((RD_HARPOON(p_port
+hp_ee_ctrl
) & (EXT_ARB_ACK
| SCSI_TERM_ENA_H
))|
7651 FPT_utilEESendCmdAddr(p_port
, EE_READ
, ee_addr
);
7654 ee_value
|= (SEE_MS
+ SEE_CS
);
7657 for(i
= 1; i
<= 16; i
++) {
7659 ee_value
|= SEE_CLK
; /* Clock data! */
7660 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7661 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7662 ee_value
&= ~SEE_CLK
;
7663 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7664 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7668 if (RD_HARPOON(p_port
+hp_ee_ctrl
) & SEE_DI
)
7672 ee_value
&= ~(SEE_MS
+ SEE_CS
);
7673 WR_HARPOON(p_port
+hp_ee_ctrl
, (ee_value
| SEE_MS
)); /*Turn off CS */
7674 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
); /*Turn off Master Select */
7680 /*---------------------------------------------------------------------
7682 * Function: Send EE command and Address to the EEPROM
7684 * Description: Transfers the correct command and sends the address
7687 *---------------------------------------------------------------------*/
7689 static void FPT_utilEESendCmdAddr(unsigned long p_port
, unsigned char ee_cmd
, unsigned short ee_addr
)
7691 unsigned char ee_value
;
7692 unsigned char narrow_flg
;
7697 narrow_flg
= (unsigned char)(RD_HARPOON(p_port
+hp_page_ctrl
) & NARROW_SCSI_CARD
);
7701 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7703 ee_value
|= SEE_CS
; /* Set CS to EEPROM */
7704 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7707 for(i
= 0x04; i
!= 0; i
>>=1) {
7712 ee_value
&= ~SEE_DO
;
7714 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7715 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7716 ee_value
|= SEE_CLK
; /* Clock data! */
7717 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7718 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7719 ee_value
&= ~SEE_CLK
;
7720 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7721 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7737 ee_value
&= ~SEE_DO
;
7739 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7740 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7741 ee_value
|= SEE_CLK
; /* Clock data! */
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
;
7745 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7746 WR_HARPOON(p_port
+hp_ee_ctrl
, ee_value
);
7752 static unsigned short FPT_CalcCrc16(unsigned char buffer
[])
7754 unsigned short crc
=0;
7757 for (i
=0; i
< ID_STRING_LENGTH
; i
++)
7759 ch
= (unsigned short) buffer
[i
];
7760 for(j
=0; j
< 8; j
++)
7763 crc
= (crc
>> 1) ^ CRCMASK
;
7772 static unsigned char FPT_CalcLrc(unsigned char buffer
[])
7777 for(i
= 0; i
< ID_STRING_LENGTH
; i
++)
7785 The following inline definitions avoid type conflicts.
7788 static inline unsigned char
7789 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info
*FlashPointInfo
)
7791 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO
) FlashPointInfo
);
7795 static inline FlashPoint_CardHandle_T
7796 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info
*FlashPointInfo
)
7798 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO
) FlashPointInfo
);
7802 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle
)
7804 FlashPoint_ReleaseHostAdapter(CardHandle
);
7809 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle
, struct BusLogic_CCB
*CCB
)
7811 FlashPoint_StartCCB(CardHandle
, (struct sccb
*) CCB
);
7816 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle
, struct BusLogic_CCB
*CCB
)
7818 FlashPoint_AbortCCB(CardHandle
, (struct sccb
*) CCB
);
7822 static inline boolean
7823 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle
)
7825 return FlashPoint_InterruptPending(CardHandle
);
7830 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle
)
7832 return FlashPoint_HandleInterrupt(CardHandle
);
7836 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7837 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7838 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7839 #define FlashPoint_StartCCB FlashPoint__StartCCB
7840 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7841 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7842 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7845 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7849 Define prototypes for the FlashPoint SCCB Manager Functions.
7852 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info
*);
7853 extern FlashPoint_CardHandle_T
7854 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info
*);
7855 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T
, struct BusLogic_CCB
*);
7856 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T
, struct BusLogic_CCB
*);
7857 extern boolean
FlashPoint_InterruptPending(FlashPoint_CardHandle_T
);
7858 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T
);
7859 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T
);
7862 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */