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 struct sccb_mgr_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;
86 #define SCSI_PARITY_ENA 0x0001
87 #define LOW_BYTE_TERM 0x0010
88 #define HIGH_BYTE_TERM 0x0020
89 #define BUSTYPE_PCI 0x3
91 #define SUPPORT_16TAR_32LUN 0x0002
92 #define SOFT_RESET 0x0004
93 #define EXTENDED_TRANSLATION 0x0008
94 #define POST_ALL_UNDERRRUNS 0x0040
95 #define FLAG_SCAM_ENABLED 0x0080
96 #define FLAG_SCAM_LEVEL2 0x0100
101 #define HARPOON_FAMILY 0x02
105 /* SCCB struct used for both SCCB and UCB manager compiles!
106 * The UCB Manager treats the SCCB as it's 'native hardware structure'
112 unsigned char OperationCode;
113 unsigned char ControlByte;
114 unsigned char CdbLength;
115 unsigned char RequestSenseLength;
116 unsigned long DataLength;
117 unsigned long DataPointer;
118 unsigned char CcbRes[2];
119 unsigned char HostStatus;
120 unsigned char TargetStatus;
121 unsigned char TargID;
123 unsigned char Cdb[12];
124 unsigned char CcbRes1;
125 unsigned char Reserved1;
126 unsigned long Reserved2;
127 unsigned long SensePointer;
130 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
131 unsigned long SccbIOPort; /* Identifies board base port */
132 unsigned char SccbStatus;
133 unsigned char SCCBRes2;
134 unsigned short SccbOSFlags;
137 unsigned long Sccb_XferCnt; /* actual transfer count */
138 unsigned long Sccb_ATC;
139 unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */
140 unsigned long Sccb_res1;
141 unsigned short Sccb_MGRFlags;
142 unsigned short Sccb_sgseg;
143 unsigned char Sccb_scsimsg; /* identify msg for selection */
144 unsigned char Sccb_tag;
145 unsigned char Sccb_scsistat;
146 unsigned char Sccb_idmsg; /* image of last msg in */
147 struct sccb * Sccb_forwardlink;
148 struct sccb * Sccb_backlink;
149 unsigned long Sccb_savedATC;
150 unsigned char Save_Cdb[6];
151 unsigned char Save_CdbLen;
152 unsigned char Sccb_XferState;
153 unsigned long Sccb_SGoffset;
161 #define SCATTER_GATHER_COMMAND 0x02
162 #define RESIDUAL_COMMAND 0x03
163 #define RESIDUAL_SG_COMMAND 0x04
164 #define RESET_COMMAND 0x81
167 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
168 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
169 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
170 #define SCCB_DATA_XFER_IN 0x08 /* Read */
173 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
176 #define BUS_FREE_ST 0
178 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
179 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
180 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
181 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
183 #define DATA_OUT_ST 7
185 #define DISCONNECT_ST 9
189 #define F_HOST_XFER_DIR 0x01
190 #define F_ALL_XFERRED 0x02
191 #define F_SG_XFER 0x04
192 #define F_AUTO_SENSE 0x08
193 #define F_ODD_BALL_CNT 0x10
194 #define F_NO_DATA_YET 0x80
197 #define F_STATUSLOADED 0x01
198 #define F_DEV_SELECTED 0x04
201 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
202 #define SCCB_DATA_UNDER_RUN 0x0C
203 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
204 #define SCCB_DATA_OVER_RUN 0x12
205 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
207 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
208 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
209 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
215 #define SCCB_IN_PROCESS 0x00
216 #define SCCB_SUCCESS 0x01
217 #define SCCB_ABORT 0x02
218 #define SCCB_ERROR 0x04
222 #define ORION_FW_REV 3110
226 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
228 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
231 #define MAX_SCSI_TAR 16
233 #define LUN_MASK 0x1f
235 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
237 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
240 #define RD_HARPOON(ioport) inb((u32)ioport)
241 #define RDW_HARPOON(ioport) inw((u32)ioport)
242 #define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
243 #define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
244 #define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
245 #define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
248 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
249 #define SYNC_TRYING BIT(6)
250 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
252 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
253 #define WIDE_ENABLED BIT(4)
254 #define WIDE_NEGOCIATED BIT(5)
256 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
257 #define TAG_Q_TRYING BIT(2)
258 #define TAG_Q_REJECT BIT(3)
260 #define TAR_ALLOW_DISC BIT(0)
263 #define EE_SYNC_MASK (BIT(0)+BIT(1))
264 #define EE_SYNC_5MB BIT(0)
265 #define EE_SYNC_10MB BIT(1)
266 #define EE_SYNC_20MB (BIT(0)+BIT(1))
268 #define EE_WIDE_SCSI BIT(7)
273 struct sccb_mgr_tar_info {
275 struct sccb * TarSelQ_Head;
276 struct sccb * TarSelQ_Tail;
277 unsigned char TarLUN_CA; /*Contingent Allgiance */
278 unsigned char TarTagQ_Cnt;
279 unsigned char TarSelQ_Cnt;
280 unsigned char TarStatus;
281 unsigned char TarEEValue;
282 unsigned char TarSyncCtrl;
283 unsigned char TarReserved[2]; /* for alignment */
284 unsigned char LunDiscQ_Idx[MAX_LUN];
285 unsigned char TarLUNBusy[MAX_LUN];
288 typedef struct NVRAMInfo {
289 unsigned char niModel; /* Model No. of card */
290 unsigned char niCardNo; /* Card no. */
291 unsigned long niBaseAddr; /* Port Address of card */
292 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
293 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
294 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
295 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
296 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
297 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
300 typedef NVRAMINFO *PNVRamInfo;
308 typedef struct SCCBcard {
309 struct sccb * currentSCCB;
310 struct sccb_mgr_info * cardInfo;
312 unsigned long ioPort;
314 unsigned short cmdCounter;
315 unsigned char discQCount;
316 unsigned char tagQ_Lst;
317 unsigned char cardIndex;
318 unsigned char scanIndex;
319 unsigned char globalFlags;
321 PNVRamInfo pNvRamInfo;
322 struct sccb * discQ_Tbl[QUEUE_DEPTH];
326 typedef struct SCCBcard *PSCCBcard;
329 #define F_TAG_STARTED 0x01
330 #define F_CONLUN_IO 0x02
331 #define F_DO_RENEGO 0x04
332 #define F_NO_FILTER 0x08
333 #define F_GREEN_PC 0x10
334 #define F_HOST_XFER_ACT 0x20
335 #define F_NEW_SCCB_CMD 0x40
336 #define F_UPDATE_EEPROM 0x80
339 #define ID_STRING_LENGTH 32
340 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
343 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
345 #define ASSIGN_ID 0x00
346 #define SET_P_FLAG 0x01
347 #define CFG_CMPLT 0x03
348 #define DOM_MSTR 0x0F
349 #define SYNC_PTRN 0x1F
353 #define MISC_CODE 0x14
354 #define CLR_P_FLAG 0x18
358 #define INIT_SELTD 0x01
359 #define LEVEL2_TAR 0x02
362 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
363 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
364 CLR_PRIORITY,NO_ID_AVAIL };
366 typedef struct SCCBscam_info {
368 unsigned char id_string[ID_STRING_LENGTH];
369 enum scam_id_st state;
374 #define SCSI_REQUEST_SENSE 0x03
375 #define SCSI_READ 0x08
376 #define SCSI_WRITE 0x0A
377 #define SCSI_START_STOP_UNIT 0x1B
378 #define SCSI_READ_EXTENDED 0x28
379 #define SCSI_WRITE_EXTENDED 0x2A
380 #define SCSI_WRITE_AND_VERIFY 0x2E
386 #define SSQ_FULL 0x28
391 #define SMCMD_COMP 0x00
393 #define SMSAVE_DATA_PTR 0x02
394 #define SMREST_DATA_PTR 0x03
397 #define SMREJECT 0x07
399 #define SMPARITY 0x09
400 #define SMDEV_RESET 0x0C
401 #define SMABORT_TAG 0x0D
402 #define SMINIT_RECOVERY 0x0F
403 #define SMREL_RECOVERY 0x10
406 #define DISC_PRIV 0x40
413 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
422 #define SIX_BYTE_CMD 0x06
423 #define TWELVE_BYTE_CMD 0x0C
426 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
429 #define EEPROM_WD_CNT 256
431 #define EEPROM_CHECK_SUM 0
432 #define FW_SIGNATURE 2
433 #define MODEL_NUMB_0 4
434 #define MODEL_NUMB_2 6
435 #define MODEL_NUMB_4 8
436 #define SYSTEM_CONFIG 16
437 #define SCSI_CONFIG 17
438 #define BIOS_CONFIG 18
439 #define SCAM_CONFIG 20
440 #define ADAPTER_SCSI_ID 24
443 #define IGNORE_B_SCAN 32
444 #define SEND_START_ENA 34
445 #define DEVICE_ENABLE 36
447 #define SYNC_RATE_TBL 38
448 #define SYNC_RATE_TBL01 38
449 #define SYNC_RATE_TBL23 40
450 #define SYNC_RATE_TBL45 42
451 #define SYNC_RATE_TBL67 44
452 #define SYNC_RATE_TBL89 46
453 #define SYNC_RATE_TBLab 48
454 #define SYNC_RATE_TBLcd 50
455 #define SYNC_RATE_TBLef 52
459 #define EE_SCAMBASE 256
463 #define SCAM_ENABLED BIT(2)
464 #define SCAM_LEVEL2 BIT(3)
467 #define RENEGO_ENA BITW(10)
468 #define CONNIO_ENA BITW(11)
469 #define GREEN_PC_ENA BITW(12)
472 #define AUTO_RATE_00 00
473 #define AUTO_RATE_05 01
474 #define AUTO_RATE_10 02
475 #define AUTO_RATE_20 03
477 #define WIDE_NEGO_BIT BIT(7)
478 #define DISC_ENABLE_BIT BIT(6)
482 #define hp_vendor_id_0 0x00 /* LSB */
483 #define ORION_VEND_0 0x4B
485 #define hp_vendor_id_1 0x01 /* MSB */
486 #define ORION_VEND_1 0x10
488 #define hp_device_id_0 0x02 /* LSB */
489 #define ORION_DEV_0 0x30
491 #define hp_device_id_1 0x03 /* MSB */
492 #define ORION_DEV_1 0x81
494 /* Sub Vendor ID and Sub Device ID only available in
495 Harpoon Version 2 and higher */
497 #define hp_sub_device_id_0 0x06 /* LSB */
501 #define hp_semaphore 0x0C
502 #define SCCB_MGR_ACTIVE BIT(0)
503 #define TICKLE_ME BIT(1)
504 #define SCCB_MGR_PRESENT BIT(3)
505 #define BIOS_IN_USE BIT(4)
509 #define hp_sys_ctrl 0x0F
511 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
512 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
513 #define HALT_MACH BIT(3) /*Halt State Machine */
514 #define HARD_ABORT BIT(4) /*Hard Abort */
524 #define hp_host_blk_cnt 0x13
526 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
528 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
532 #define hp_int_mask 0x17
534 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
535 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
538 #define hp_xfer_cnt_lo 0x18
539 #define hp_xfer_cnt_hi 0x1A
540 #define hp_xfer_cmd 0x1B
542 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
543 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
546 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
548 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
550 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
552 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
553 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
555 #define hp_host_addr_lo 0x1C
556 #define hp_host_addr_hmi 0x1E
558 #define hp_ee_ctrl 0x22
560 #define EXT_ARB_ACK BIT(7)
561 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
562 #define SEE_MS BIT(5)
563 #define SEE_CS BIT(3)
564 #define SEE_CLK BIT(2)
565 #define SEE_DO BIT(1)
566 #define SEE_DI BIT(0)
569 #define EE_WRITE 0x05
571 #define EWEN_ADDR 0x03C0
573 #define EWDS_ADDR 0x0000
581 #define hp_bm_ctrl 0x26
583 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
584 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
585 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
586 #define FAST_SINGLE BIT(6) /*?? */
588 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
591 #define hp_sg_addr 0x28
592 #define hp_page_ctrl 0x29
594 #define SCATTER_EN BIT(0)
595 #define SGRAM_ARAM BIT(1)
596 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
597 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
602 #define hp_pci_stat_cfg 0x2D
604 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
613 #define hp_rev_num 0x33
616 #define hp_stack_data 0x34
617 #define hp_stack_addr 0x35
619 #define hp_ext_status 0x36
621 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
622 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
623 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
624 #define CMD_ABORTED BIT(4) /*Command aborted */
625 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
626 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
627 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
628 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
629 BM_PARITY_ERR | PIO_OVERRUN)
631 #define hp_int_status 0x37
633 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
634 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
635 #define INT_ASSERTED BIT(5) /* */
638 #define hp_fifo_cnt 0x38
643 #define hp_intena 0x40
645 #define RESET BITW(7)
646 #define PROG_HLT BITW(6)
647 #define PARITY BITW(5)
650 #define SCAM_SEL BITW(2)
652 #define TIMEOUT BITW(0)
653 #define BUS_FREE BITW(15)
654 #define XFER_CNT_0 BITW(14)
655 #define PHASE BITW(13)
656 #define IUNKWN BITW(12)
657 #define ICMD_COMP BITW(11)
658 #define ITICKLE BITW(10)
659 #define IDO_STRT BITW(9)
660 #define ITAR_DISC BITW(8)
661 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
662 #define CLR_ALL_INT 0xFFFF
663 #define CLR_ALL_INT_1 0xFF00
665 #define hp_intstat 0x42
667 #define hp_scsisig 0x44
669 #define SCSI_SEL BIT(7)
670 #define SCSI_BSY BIT(6)
671 #define SCSI_REQ BIT(5)
672 #define SCSI_ACK BIT(4)
673 #define SCSI_ATN BIT(3)
674 #define SCSI_CD BIT(2)
675 #define SCSI_MSG BIT(1)
676 #define SCSI_IOBIT BIT(0)
678 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
679 #define S_MSGO_PH (BIT(2)+BIT(1) )
680 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
681 #define S_DATAI_PH ( BIT(0))
682 #define S_DATAO_PH 0x00
683 #define S_ILL_PH ( BIT(1) )
685 #define hp_scsictrl_0 0x45
687 #define SEL_TAR BIT(6)
688 #define ENA_ATN BIT(4)
689 #define ENA_RESEL BIT(2)
690 #define SCSI_RST BIT(1)
691 #define ENA_SCAM_SEL BIT(0)
695 #define hp_portctrl_0 0x46
697 #define SCSI_PORT BIT(7)
698 #define SCSI_INBIT BIT(6)
699 #define DMA_PORT BIT(5)
700 #define DMA_RD BIT(4)
701 #define HOST_PORT BIT(3)
702 #define HOST_WRT BIT(2)
703 #define SCSI_BUS_EN BIT(1)
704 #define START_TO BIT(0)
706 #define hp_scsireset 0x47
708 #define SCSI_INI BIT(6)
709 #define SCAM_EN BIT(5)
710 #define DMA_RESET BIT(3)
711 #define HPSCSI_RESET BIT(2)
712 #define PROG_RESET BIT(1)
713 #define FIFO_CLR BIT(0)
715 #define hp_xfercnt_0 0x48
716 #define hp_xfercnt_2 0x4A
718 #define hp_fifodata_0 0x4C
719 #define hp_addstat 0x4E
721 #define SCAM_TIMER BIT(7)
722 #define SCSI_MODE8 BIT(3)
723 #define SCSI_PAR_ERR BIT(0)
725 #define hp_prgmcnt_0 0x4F
728 #define hp_selfid_0 0x50
729 #define hp_selfid_1 0x51
730 #define hp_arb_id 0x52
733 #define hp_select_id 0x53
736 #define hp_synctarg_base 0x54
737 #define hp_synctarg_12 0x54
738 #define hp_synctarg_13 0x55
739 #define hp_synctarg_14 0x56
740 #define hp_synctarg_15 0x57
742 #define hp_synctarg_8 0x58
743 #define hp_synctarg_9 0x59
744 #define hp_synctarg_10 0x5A
745 #define hp_synctarg_11 0x5B
747 #define hp_synctarg_4 0x5C
748 #define hp_synctarg_5 0x5D
749 #define hp_synctarg_6 0x5E
750 #define hp_synctarg_7 0x5F
752 #define hp_synctarg_0 0x60
753 #define hp_synctarg_1 0x61
754 #define hp_synctarg_2 0x62
755 #define hp_synctarg_3 0x63
757 #define NARROW_SCSI BIT(4)
758 #define DEFAULT_OFFSET 0x0F
760 #define hp_autostart_0 0x64
761 #define hp_autostart_1 0x65
762 #define hp_autostart_3 0x67
766 #define AUTO_IMMED BIT(5)
767 #define SELECT BIT(6)
768 #define END_DATA (BIT(7)+BIT(6))
770 #define hp_gp_reg_0 0x68
771 #define hp_gp_reg_1 0x69
772 #define hp_gp_reg_3 0x6B
774 #define hp_seltimeout 0x6C
777 #define TO_4ms 0x67 /* 3.9959ms */
779 #define TO_5ms 0x03 /* 4.9152ms */
780 #define TO_10ms 0x07 /* 11.xxxms */
781 #define TO_250ms 0x99 /* 250.68ms */
782 #define TO_290ms 0xB1 /* 289.99ms */
784 #define hp_clkctrl_0 0x6D
786 #define PWR_DWN BIT(6)
787 #define ACTdeassert BIT(4)
788 #define CLK_40MHZ (BIT(1) + BIT(0))
790 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
792 #define hp_fiforead 0x6E
793 #define hp_fifowrite 0x6F
795 #define hp_offsetctr 0x70
796 #define hp_xferstat 0x71
798 #define FIFO_EMPTY BIT(6)
800 #define hp_portctrl_1 0x72
802 #define CHK_SCSI_P BIT(3)
803 #define HOST_MODE8 BIT(0)
805 #define hp_xfer_pad 0x73
807 #define ID_UNLOCK BIT(3)
809 #define hp_scsidata_0 0x74
810 #define hp_scsidata_1 0x75
814 #define hp_aramBase 0x80
815 #define BIOS_DATA_OFFSET 0x60
816 #define BIOS_RELATIVE_CARD 0x64
821 #define AR3 (BITW(9) + BITW(8))
822 #define SDATA BITW(10)
825 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
827 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
831 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
833 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
836 #define ADATA_OUT 0x00
837 #define ADATA_IN BITW(8)
838 #define ACOMMAND BITW(10)
839 #define ASTATUS (BITW(10)+BITW(8))
840 #define AMSG_OUT (BITW(10)+BITW(9))
841 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
844 #define BRH_OP BITW(13) /* Branch */
848 #define EQUAL BITW(8)
849 #define NOT_EQ BITW(9)
851 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
854 #define FIFO_0 BITW(10)
857 #define MPM_OP BITW(15) /* Match phase and move data */
860 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
863 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
868 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
878 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
880 #define SSI_OP (BITW(15)+BITW(11))
883 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
884 #define SSI_IDO_STRT (IDO_STRT >> 8)
886 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
887 #define SSI_ITICKLE (ITICKLE >> 8)
889 #define SSI_IUNKWN (IUNKWN >> 8)
890 #define SSI_INO_CC (IUNKWN >> 8)
891 #define SSI_IRFAIL (IUNKWN >> 8)
894 #define NP 0x10 /*Next Phase */
895 #define NTCMD 0x02 /*Non- Tagged Command start */
896 #define CMDPZ 0x04 /*Command phase */
897 #define DINT 0x12 /*Data Out/In interrupt */
898 #define DI 0x13 /*Data Out */
899 #define DC 0x19 /*Disconnect Message */
900 #define ST 0x1D /*Status Phase */
901 #define UNKNWN 0x24 /*Unknown bus action */
902 #define CC 0x25 /*Command Completion failure */
903 #define TICK 0x26 /*New target reselected us. */
904 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
907 #define ID_MSG_STRT hp_aramBase + 0x00
908 #define NON_TAG_ID_MSG hp_aramBase + 0x06
909 #define CMD_STRT hp_aramBase + 0x08
910 #define SYNC_MSGS hp_aramBase + 0x08
916 #define TAG_STRT 0x00
917 #define DISCONNECT_START 0x10/2
918 #define END_DATA_START 0x14/2
919 #define CMD_ONLY_STRT CMDPZ/2
920 #define SELCHK_STRT SELCHK/2
930 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
931 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
933 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
935 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
937 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
938 WR_HARP32(port,hp_xfercnt_0,count),\
939 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
941 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
943 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
944 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
947 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
948 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
952 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
953 WR_HARPOON(port+hp_scsireset, 0x00))
955 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
956 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
958 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
959 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
961 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
962 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
964 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
965 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
970 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
971 static void FPT_ssel(unsigned long port, unsigned char p_card);
972 static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
973 static void FPT_shandem(unsigned long port, unsigned char p_card,struct sccb * pCurrSCCB);
974 static void FPT_stsyncn(unsigned long port, unsigned char p_card);
975 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
976 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
977 struct sccb_mgr_tar_info * currTar_Info);
978 static void FPT_sresb(unsigned long port, unsigned char p_card);
979 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
980 static void FPT_schkdd(unsigned long port, unsigned char p_card);
981 static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
982 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
983 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
985 static void FPT_SendMsg(unsigned long port, unsigned char message);
986 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
987 unsigned char error_code);
989 static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card);
990 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
992 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
993 static void FPT_stwidn(unsigned long port, unsigned char p_card);
994 static void FPT_siwidr(unsigned long port, unsigned char width);
997 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
998 static void FPT_queueDisconnect(struct sccb * p_SCCB, unsigned char p_card);
999 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_SCCB,
1000 unsigned char p_card);
1001 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1002 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1003 static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char card);
1004 static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card);
1005 static void FPT_utilUpdateResidual(struct sccb * p_SCCB);
1006 static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
1007 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
1010 static void FPT_Wait1Second(unsigned long p_port);
1011 static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1012 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1013 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1014 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1015 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1016 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
1020 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1021 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1022 static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1023 static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1024 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1025 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1026 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
1028 static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1029 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1030 static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
1035 static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1036 static void FPT_BusMasterInit(unsigned long p_port);
1037 static void FPT_DiagEEPROM(unsigned long p_port);
1042 static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
1043 static void FPT_busMstrSGDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1044 static void FPT_busMstrDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1045 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB);
1046 static void FPT_hostDataXferRestart(struct sccb * currSCCB);
1049 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
1050 PSCCBcard pCurrCard, unsigned short p_int);
1052 static void FPT_SccbMgrTableInitAll(void);
1053 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1054 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
1058 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
1060 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1061 static void FPT_scbusf(unsigned long p_port);
1062 static void FPT_scsel(unsigned long p_port);
1063 static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1064 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1065 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1066 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1067 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1068 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
1069 static unsigned char FPT_scvalq(unsigned char p_quintet);
1070 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1071 static void FPT_scwtsel(unsigned long p_port);
1072 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1073 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
1074 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
1077 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1078 static void FPT_autoLoadDefaultMap(unsigned long p_port);
1083 static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1084 static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1085 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1086 static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1089 static unsigned char FPT_mbCards = 0;
1090 static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1091 ' ', 'B', 'T', '-', '9', '3', '0', \
1092 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1093 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1095 static unsigned short FPT_default_intena = 0;
1098 static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
1101 /*---------------------------------------------------------------------
1103 * Function: FlashPoint_ProbeHostAdapter
1105 * Description: Setup and/or Search for cards and return info to caller.
1107 *---------------------------------------------------------------------*/
1109 static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info * pCardInfo)
1111 static unsigned char first_time = 1;
1113 unsigned char i,j,id,ScamFlg;
1114 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
1115 unsigned long ioport;
1116 PNVRamInfo pCurrNvRam;
1118 ioport = pCardInfo->si_baseaddr;
1121 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1122 return((int)FAILURE);
1124 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1125 return((int)FAILURE);
1127 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1128 return((int)FAILURE);
1130 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1131 return((int)FAILURE);
1134 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1136 /* For new Harpoon then check for sub_device ID LSB
1137 the bits(0-3) must be all ZERO for compatible with
1138 current version of SCCBMgr, else skip this Harpoon
1141 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1142 return((int)FAILURE);
1147 FPT_SccbMgrTableInitAll();
1152 if(FPT_RdStack(ioport, 0) != 0x00) {
1153 if(FPT_ChkIfChipInitialized(ioport) == 0)
1156 WR_HARPOON(ioport+hp_semaphore, 0x00);
1157 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1158 FPT_DiagEEPROM(ioport);
1162 if(FPT_mbCards < MAX_MB_CARDS) {
1163 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1165 pCurrNvRam->niBaseAddr = ioport;
1166 FPT_RNVRamData(pCurrNvRam);
1168 return((int) FAILURE);
1173 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1174 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1177 pCardInfo->si_id = pCurrNvRam->niAdapId;
1179 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1180 (unsigned char)0x0FF);
1182 pCardInfo->si_lun = 0x00;
1183 pCardInfo->si_fw_revision = ORION_FW_REV;
1190 for (id = 0; id < (16/2); id++) {
1193 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1194 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1195 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1197 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1199 for (i = 0; i < 2; temp >>=8,i++) {
1208 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1209 temp6 |= 0x8000; /* Fall through */
1210 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1211 temp5 |= 0x8000; /* Fall through */
1212 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1213 temp2 |= 0x8000; /* Fall through */
1214 case AUTO_RATE_00: /* Asynchronous */
1218 if (temp & DISC_ENABLE_BIT)
1221 if (temp & WIDE_NEGO_BIT)
1227 pCardInfo->si_per_targ_init_sync = temp2;
1228 pCardInfo->si_per_targ_no_disc = temp3;
1229 pCardInfo->si_per_targ_wide_nego = temp4;
1230 pCardInfo->si_per_targ_fast_nego = temp5;
1231 pCardInfo->si_per_targ_ultra_nego = temp6;
1234 i = pCurrNvRam->niSysConf;
1236 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1239 ScamFlg = pCurrNvRam->niScamConf;
1241 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1243 pCardInfo->si_flags = 0x0000;
1246 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1249 pCardInfo->si_flags |= SOFT_RESET;
1252 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1254 if (ScamFlg & SCAM_ENABLED)
1255 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1257 if (ScamFlg & SCAM_LEVEL2)
1258 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1260 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1262 j |= SCSI_TERM_ENA_L;
1264 WR_HARPOON(ioport+hp_bm_ctrl, j );
1266 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1268 j |= SCSI_TERM_ENA_H;
1270 WR_HARPOON(ioport+hp_ee_ctrl, j );
1272 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1274 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1276 pCardInfo->si_card_family = HARPOON_FAMILY;
1277 pCardInfo->si_bustype = BUSTYPE_PCI;
1280 pCardInfo->si_card_model[0] = '9';
1281 switch(pCurrNvRam->niModel & 0x0f){
1283 pCardInfo->si_card_model[1] = '3';
1284 pCardInfo->si_card_model[2] = '0';
1287 pCardInfo->si_card_model[1] = '5';
1288 pCardInfo->si_card_model[2] = '0';
1291 pCardInfo->si_card_model[1] = '3';
1292 pCardInfo->si_card_model[2] = '2';
1295 pCardInfo->si_card_model[1] = '5';
1296 pCardInfo->si_card_model[2] = '2';
1300 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1301 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1302 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1304 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1305 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1308 if (pCardInfo->si_card_model[1] == '3')
1310 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1311 pCardInfo->si_flags |= LOW_BYTE_TERM;
1313 else if (pCardInfo->si_card_model[2] == '0')
1315 temp = RD_HARPOON(ioport+hp_xfer_pad);
1316 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1317 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1318 pCardInfo->si_flags |= LOW_BYTE_TERM;
1319 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1320 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1321 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1322 WR_HARPOON(ioport+hp_xfer_pad, temp);
1326 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1327 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1328 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1329 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1331 for (i = 0; i < 8; i++)
1334 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1336 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1337 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1339 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1340 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1341 if (!(temp3 & BIT(7)))
1342 pCardInfo->si_flags |= LOW_BYTE_TERM;
1343 if (!(temp3 & BIT(6)))
1344 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1348 ARAM_ACCESS(ioport);
1350 for ( i = 0; i < 4; i++ ) {
1352 pCardInfo->si_XlatInfo[i] =
1353 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1356 /* return with -1 if no sort, else return with
1357 logical card number sorted by BIOS (zero-based) */
1359 pCardInfo->si_relative_cardnum =
1360 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1362 SGRAM_ACCESS(ioport);
1364 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1365 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1366 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1367 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1368 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1369 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1370 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1371 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1373 pCardInfo->si_present = 0x01;
1379 /*---------------------------------------------------------------------
1381 * Function: FlashPoint_HardwareResetHostAdapter
1383 * Description: Setup adapter for normal operation (hard reset).
1385 *---------------------------------------------------------------------*/
1387 static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info * pCardInfo)
1389 PSCCBcard CurrCard = NULL;
1390 PNVRamInfo pCurrNvRam;
1391 unsigned char i,j,thisCard, ScamFlg;
1392 unsigned short temp,sync_bit_map,id;
1393 unsigned long ioport;
1395 ioport = pCardInfo->si_baseaddr;
1397 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1399 if (thisCard == MAX_CARDS) {
1404 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1406 CurrCard = &FPT_BL_Card[thisCard];
1407 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1411 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1413 FPT_BL_Card[thisCard].ioPort = ioport;
1414 CurrCard = &FPT_BL_Card[thisCard];
1417 for(i = 0; i < FPT_mbCards; i++){
1418 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1419 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1421 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1422 CurrCard->cardIndex = thisCard;
1423 CurrCard->cardInfo = pCardInfo;
1429 pCurrNvRam = CurrCard->pNvRamInfo;
1432 ScamFlg = pCurrNvRam->niScamConf;
1435 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1439 FPT_BusMasterInit(ioport);
1440 FPT_XbowInit(ioport, ScamFlg);
1442 FPT_autoLoadDefaultMap(ioport);
1445 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1447 WR_HARPOON(ioport+hp_selfid_0, id);
1448 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1449 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1450 CurrCard->ourId = pCardInfo->si_id;
1452 i = (unsigned char) pCardInfo->si_flags;
1453 if (i & SCSI_PARITY_ENA)
1454 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1456 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1457 if (i & LOW_BYTE_TERM)
1458 j |= SCSI_TERM_ENA_L;
1459 WR_HARPOON(ioport+hp_bm_ctrl, j);
1461 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1462 if (i & HIGH_BYTE_TERM)
1463 j |= SCSI_TERM_ENA_H;
1464 WR_HARPOON(ioport+hp_ee_ctrl, j );
1467 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1469 FPT_sresb(ioport,thisCard);
1471 FPT_scini(thisCard, pCardInfo->si_id, 0);
1476 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1477 CurrCard->globalFlags |= F_NO_FILTER;
1480 if(pCurrNvRam->niSysConf & 0x10)
1481 CurrCard->globalFlags |= F_GREEN_PC;
1484 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1485 CurrCard->globalFlags |= F_GREEN_PC;
1488 /* Set global flag to indicate Re-Negotiation to be done on all
1491 if(pCurrNvRam->niScsiConf & 0x04)
1492 CurrCard->globalFlags |= F_DO_RENEGO;
1495 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1496 CurrCard->globalFlags |= F_DO_RENEGO;
1500 if(pCurrNvRam->niScsiConf & 0x08)
1501 CurrCard->globalFlags |= F_CONLUN_IO;
1504 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1505 CurrCard->globalFlags |= F_CONLUN_IO;
1509 temp = pCardInfo->si_per_targ_no_disc;
1511 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1514 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1517 sync_bit_map = 0x0001;
1519 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1522 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1523 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1524 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1526 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1528 for (i = 0; i < 2; temp >>=8,i++) {
1530 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1532 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
1536 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1537 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1538 (unsigned char)(temp & ~EE_SYNC_MASK);
1541 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1544 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1546 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1550 else { /* NARROW SCSI */
1551 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1562 WR_HARPOON((ioport+hp_semaphore),
1563 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1565 return((unsigned long)CurrCard);
1568 static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
1571 unsigned long portBase;
1572 unsigned long regOffset;
1573 unsigned long scamData;
1574 unsigned long *pScamTbl;
1575 PNVRamInfo pCurrNvRam;
1577 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1580 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1581 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1582 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1583 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1584 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1586 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1587 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
1589 portBase = pCurrNvRam->niBaseAddr;
1591 for(i = 0; i < MAX_SCSI_TAR; i++){
1592 regOffset = hp_aramBase + 64 + i*4;
1593 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
1594 scamData = *pScamTbl;
1595 WR_HARP32(portBase, regOffset, scamData);
1599 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1604 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1607 unsigned long portBase;
1608 unsigned long regOffset;
1609 unsigned long scamData;
1610 unsigned long *pScamTbl;
1612 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1613 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1614 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1615 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1616 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1618 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1619 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
1621 portBase = pNvRamInfo->niBaseAddr;
1623 for(i = 0; i < MAX_SCSI_TAR; i++){
1624 regOffset = hp_aramBase + 64 + i*4;
1625 RD_HARP32(portBase, regOffset, scamData);
1626 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
1627 *pScamTbl = scamData;
1632 static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
1634 WR_HARPOON(portBase + hp_stack_addr, index);
1635 return(RD_HARPOON(portBase + hp_stack_data));
1638 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
1640 WR_HARPOON(portBase + hp_stack_addr, index);
1641 WR_HARPOON(portBase + hp_stack_data, data);
1645 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
1647 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1649 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1652 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1653 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1658 /*---------------------------------------------------------------------
1660 * Function: FlashPoint_StartCCB
1662 * Description: Start a command pointed to by p_Sccb. When the
1663 * command is completed it will be returned via the
1664 * callback function.
1666 *---------------------------------------------------------------------*/
1667 static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
1669 unsigned long ioport;
1670 unsigned char thisCard, lun;
1671 struct sccb * pSaveSccb;
1672 CALL_BK_FN callback;
1674 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1675 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1677 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1680 p_Sccb->HostStatus = SCCB_COMPLETE;
1681 p_Sccb->SccbStatus = SCCB_ERROR;
1682 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1689 FPT_sinits(p_Sccb,thisCard);
1692 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1694 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1695 | SCCB_MGR_ACTIVE));
1697 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1699 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1700 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1704 ((PSCCBcard)pCurrCard)->cmdCounter++;
1706 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1708 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1710 if(p_Sccb->OperationCode == RESET_COMMAND)
1712 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1713 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1714 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1715 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1719 FPT_queueAddSccb(p_Sccb,thisCard);
1723 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1725 if(p_Sccb->OperationCode == RESET_COMMAND)
1727 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1728 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1729 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1730 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1734 FPT_queueAddSccb(p_Sccb,thisCard);
1740 MDISABLE_INT(ioport);
1742 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
1743 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1747 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
1748 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1749 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1752 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1753 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1758 if(p_Sccb->OperationCode == RESET_COMMAND)
1760 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1761 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1762 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1763 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1767 FPT_queueAddSccb(p_Sccb,thisCard);
1772 MENABLE_INT(ioport);
1778 /*---------------------------------------------------------------------
1780 * Function: FlashPoint_AbortCCB
1782 * Description: Abort the command pointed to by p_Sccb. When the
1783 * command is completed it will be returned via the
1784 * callback function.
1786 *---------------------------------------------------------------------*/
1787 static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
1789 unsigned long ioport;
1791 unsigned char thisCard;
1792 CALL_BK_FN callback;
1794 struct sccb * pSaveSCCB;
1795 struct sccb_mgr_tar_info * currTar_Info;
1798 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1800 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1802 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1805 if (FPT_queueFindSccb(p_Sccb,thisCard))
1808 ((PSCCBcard)pCurrCard)->cmdCounter--;
1810 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1811 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1812 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1814 p_Sccb->SccbStatus = SCCB_ABORT;
1815 callback = p_Sccb->SccbCallback;
1823 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1825 p_Sccb->SccbStatus = SCCB_ABORT;
1833 TID = p_Sccb->TargID;
1836 if(p_Sccb->Sccb_tag)
1838 MDISABLE_INT(ioport);
1839 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1841 p_Sccb->SccbStatus = SCCB_ABORT;
1842 p_Sccb->Sccb_scsistat = ABORT_ST;
1843 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1845 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1847 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1848 FPT_ssel(ioport, thisCard);
1852 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1853 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1854 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1855 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1858 MENABLE_INT(ioport);
1863 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1865 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1868 p_Sccb->SccbStatus = SCCB_ABORT;
1879 /*---------------------------------------------------------------------
1881 * Function: FlashPoint_InterruptPending
1883 * Description: Do a quick check to determine if there is a pending
1884 * interrupt for this card and disable the IRQ Pin if so.
1886 *---------------------------------------------------------------------*/
1887 static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
1889 unsigned long ioport;
1891 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1893 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1905 /*---------------------------------------------------------------------
1907 * Function: FlashPoint_HandleInterrupt
1909 * Description: This is our entry point when an interrupt is generated
1910 * by the card and the upper level driver passes it on to
1913 *---------------------------------------------------------------------*/
1914 static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
1916 struct sccb * currSCCB;
1917 unsigned char thisCard,result,bm_status, bm_int_st;
1918 unsigned short hp_int;
1919 unsigned char i, target;
1920 unsigned long ioport;
1922 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1923 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1925 MDISABLE_INT(ioport);
1927 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1928 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
1932 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1934 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1938 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1940 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1941 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1942 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1947 MENABLE_INT(ioport);
1953 else if (hp_int & ICMD_COMP) {
1955 if ( !(hp_int & BUS_FREE) ) {
1956 /* Wait for the BusFree before starting a new command. We
1957 must also check for being reselected since the BusFree
1958 may not show up if another device reselects us in 1.5us or
1959 less. SRR Wednesday, 3/8/1995.
1961 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1964 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1966 FPT_phaseChkFifo(ioport, thisCard);
1968 /* WRW_HARPOON((ioport+hp_intstat),
1969 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1972 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1974 FPT_autoCmdCmplt(ioport,thisCard);
1979 else if (hp_int & ITAR_DISC)
1982 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1984 FPT_phaseChkFifo(ioport, thisCard);
1988 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1990 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
1991 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1993 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1996 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1997 FPT_queueDisconnect(currSCCB,thisCard);
1999 /* Wait for the BusFree before starting a new command. We
2000 must also check for being reselected since the BusFree
2001 may not show up if another device reselects us in 1.5us or
2002 less. SRR Wednesday, 3/8/1995.
2004 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2005 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2006 RD_HARPOON((ioport+hp_scsisig)) ==
2007 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2010 The additional loop exit condition above detects a timing problem
2011 with the revision D/E harpoon chips. The caller should reset the
2012 host adapter to recover when 0xFE is returned.
2014 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2016 MENABLE_INT(ioport);
2020 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2023 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2028 else if (hp_int & RSEL) {
2030 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2032 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2034 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2036 FPT_phaseChkFifo(ioport, thisCard);
2039 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2041 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2042 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2043 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2046 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2047 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2048 FPT_queueDisconnect(currSCCB,thisCard);
2051 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2052 FPT_phaseDecode(ioport,thisCard);
2057 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2060 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2061 FPT_phaseDecode(ioport,thisCard);
2066 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2068 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2069 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
2071 FPT_phaseDecode(ioport,thisCard);
2075 /* Harpoon problem some SCSI target device respond to selection
2076 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2077 to latch the correct Target ID into reg. x53.
2078 The work around require to correct this reg. But when write to this
2079 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2080 need to read this reg first then restore it later. After update to 0x53 */
2082 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2083 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2084 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2085 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2086 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
2087 WR_HARPOON(ioport+hp_fifowrite, i);
2088 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2092 else if (hp_int & XFER_CNT_0) {
2094 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2096 FPT_schkdd(ioport,thisCard);
2101 else if (hp_int & BUS_FREE) {
2103 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2105 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2107 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
2110 FPT_phaseBusFree(ioport,thisCard);
2114 else if (hp_int & ITICKLE) {
2116 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2117 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2122 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2125 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2128 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2130 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
2133 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2134 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2135 FPT_ssel(ioport,thisCard);
2144 MENABLE_INT(ioport);
2149 /*---------------------------------------------------------------------
2151 * Function: Sccb_bad_isr
2153 * Description: Some type of interrupt has occurred which is slightly
2154 * out of the ordinary. We will now decode it fully, in
2155 * this routine. This is broken up in an attempt to save
2158 *---------------------------------------------------------------------*/
2159 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
2160 PSCCBcard pCurrCard, unsigned short p_int)
2162 unsigned char temp, ScamFlg;
2163 struct sccb_mgr_tar_info * currTar_Info;
2164 PNVRamInfo pCurrNvRam;
2167 if (RD_HARPOON(p_port+hp_ext_status) &
2168 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2171 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2174 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2177 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2180 WR_HARPOON(p_port+hp_pci_stat_cfg,
2181 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2183 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2187 if (pCurrCard->currentSCCB != NULL)
2190 if (!pCurrCard->currentSCCB->HostStatus)
2191 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2193 FPT_sxfrp(p_port,p_card);
2195 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
2196 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2197 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
2198 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2200 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2202 FPT_phaseDecode(p_port,p_card);
2208 else if (p_int & RESET)
2211 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2212 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2213 if (pCurrCard->currentSCCB != NULL) {
2215 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2217 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2221 DISABLE_AUTO(p_port);
2223 FPT_sresb(p_port,p_card);
2225 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2227 pCurrNvRam = pCurrCard->pNvRamInfo;
2229 ScamFlg = pCurrNvRam->niScamConf;
2232 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
2235 FPT_XbowInit(p_port, ScamFlg);
2237 FPT_scini(p_card, pCurrCard->ourId, 0);
2243 else if (p_int & FIFO) {
2245 WRW_HARPOON((p_port+hp_intstat), FIFO);
2247 if (pCurrCard->currentSCCB != NULL)
2248 FPT_sxfrp(p_port,p_card);
2251 else if (p_int & TIMEOUT)
2254 DISABLE_AUTO(p_port);
2256 WRW_HARPOON((p_port+hp_intstat),
2257 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2259 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2262 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2263 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2264 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2265 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
2267 currTar_Info->TarLUNBusy[0] = 0;
2270 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2272 currTar_Info->TarSyncCtrl = 0;
2273 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2276 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2278 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2281 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
2283 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2287 else if (p_int & SCAM_SEL)
2290 FPT_scarb(p_port,LEVEL2_TAR);
2292 FPT_scasid(p_card, p_port);
2296 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2303 /*---------------------------------------------------------------------
2305 * Function: SccbMgrTableInit
2307 * Description: Initialize all Sccb manager data structures.
2309 *---------------------------------------------------------------------*/
2311 static void FPT_SccbMgrTableInitAll()
2313 unsigned char thisCard;
2315 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2317 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
2319 FPT_BL_Card[thisCard].ioPort = 0x00;
2320 FPT_BL_Card[thisCard].cardInfo = NULL;
2321 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2322 FPT_BL_Card[thisCard].ourId = 0x00;
2323 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2328 /*---------------------------------------------------------------------
2330 * Function: SccbMgrTableInit
2332 * Description: Initialize all Sccb manager data structures.
2334 *---------------------------------------------------------------------*/
2336 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
2338 unsigned char scsiID, qtag;
2340 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2342 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2345 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2347 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2348 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2349 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2352 pCurrCard->scanIndex = 0x00;
2353 pCurrCard->currentSCCB = NULL;
2354 pCurrCard->globalFlags = 0x00;
2355 pCurrCard->cmdCounter = 0x00;
2356 pCurrCard->tagQ_Lst = 0x01;
2357 pCurrCard->discQCount = 0;
2363 /*---------------------------------------------------------------------
2365 * Function: SccbMgrTableInit
2367 * Description: Initialize all Sccb manager data structures.
2369 *---------------------------------------------------------------------*/
2371 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
2374 unsigned char lun, qtag;
2375 struct sccb_mgr_tar_info * currTar_Info;
2377 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2379 currTar_Info->TarSelQ_Cnt = 0;
2380 currTar_Info->TarSyncCtrl = 0;
2382 currTar_Info->TarSelQ_Head = NULL;
2383 currTar_Info->TarSelQ_Tail = NULL;
2384 currTar_Info->TarTagQ_Cnt = 0;
2385 currTar_Info->TarLUN_CA = 0;
2388 for (lun = 0; lun < MAX_LUN; lun++)
2390 currTar_Info->TarLUNBusy[lun] = 0;
2391 currTar_Info->LunDiscQ_Idx[lun] = 0;
2394 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2396 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
2398 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
2400 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2401 FPT_BL_Card[p_card].discQCount--;
2408 /*---------------------------------------------------------------------
2412 * Description: Read in a message byte from the SCSI bus, and check
2413 * for a parity error.
2415 *---------------------------------------------------------------------*/
2417 static unsigned char FPT_sfm(unsigned long port, struct sccb * pCurrSCCB)
2419 unsigned char message;
2420 unsigned short TimeOutLoop;
2423 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2424 (TimeOutLoop++ < 20000) ){}
2427 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2429 message = RD_HARPOON(port+hp_scsidata_0);
2431 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2434 if (TimeOutLoop > 20000)
2435 message = 0x00; /* force message byte = 0 if Time Out on Req */
2437 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2438 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2440 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2441 WR_HARPOON(port+hp_xferstat, 0);
2442 WR_HARPOON(port+hp_fiforead, 0);
2443 WR_HARPOON(port+hp_fifowrite, 0);
2444 if (pCurrSCCB != NULL)
2446 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2451 ACCEPT_MSG_ATN(port);
2453 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2454 (TimeOutLoop++ < 20000) ){}
2455 if (TimeOutLoop > 20000)
2457 WRW_HARPOON((port+hp_intstat), PARITY);
2460 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2462 WRW_HARPOON((port+hp_intstat), PARITY);
2465 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2467 RD_HARPOON(port+hp_scsidata_0);
2469 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2474 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2475 WR_HARPOON(port+hp_xferstat, 0);
2476 WR_HARPOON(port+hp_fiforead, 0);
2477 WR_HARPOON(port+hp_fifowrite, 0);
2482 /*---------------------------------------------------------------------
2484 * Function: FPT_ssel
2486 * Description: Load up automation and select target device.
2488 *---------------------------------------------------------------------*/
2490 static void FPT_ssel(unsigned long port, unsigned char p_card)
2493 unsigned char auto_loaded, i, target, *theCCB;
2495 unsigned long cdb_reg;
2497 struct sccb * currSCCB;
2498 struct sccb_mgr_tar_info * currTar_Info;
2499 unsigned char lastTag, lun;
2501 CurrCard = &FPT_BL_Card[p_card];
2502 currSCCB = CurrCard->currentSCCB;
2503 target = currSCCB->TargID;
2504 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2505 lastTag = CurrCard->tagQ_Lst;
2510 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2511 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2513 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2514 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2516 lun = currSCCB->Lun;
2521 if (CurrCard->globalFlags & F_TAG_STARTED)
2523 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2525 if ((currTar_Info->TarLUN_CA == 0)
2526 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2530 if (currTar_Info->TarTagQ_Cnt !=0)
2532 currTar_Info->TarLUNBusy[lun] = 1;
2533 FPT_queueSelectFail(CurrCard,p_card);
2539 currTar_Info->TarLUNBusy[lun] = 1;
2542 } /*End non-tagged */
2545 currTar_Info->TarLUNBusy[lun] = 1;
2548 } /*!Use cmd Q Tagged */
2551 if (currTar_Info->TarLUN_CA == 1)
2553 FPT_queueSelectFail(CurrCard,p_card);
2558 currTar_Info->TarLUNBusy[lun] = 1;
2560 } /*else use cmd Q tagged */
2562 } /*if glob tagged started */
2565 currTar_Info->TarLUNBusy[lun] = 1;
2570 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2571 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2572 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2574 if(CurrCard->discQCount >= QUEUE_DEPTH)
2576 currTar_Info->TarLUNBusy[lun] = 1;
2577 FPT_queueSelectFail(CurrCard,p_card);
2581 for (i = 1; i < QUEUE_DEPTH; i++)
2583 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2584 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2586 CurrCard->tagQ_Lst = lastTag;
2587 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2588 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2589 CurrCard->discQCount++;
2593 if(i == QUEUE_DEPTH)
2595 currTar_Info->TarLUNBusy[lun] = 1;
2596 FPT_queueSelectFail(CurrCard,p_card);
2606 WR_HARPOON(port+hp_select_id, target);
2607 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2609 if (currSCCB->OperationCode == RESET_COMMAND) {
2610 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2611 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2613 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2615 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2617 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2619 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2621 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2623 currTar_Info->TarSyncCtrl = 0;
2624 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2627 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2629 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2632 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2633 FPT_SccbMgrTableInitTarget(p_card, target);
2637 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2639 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2640 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2642 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2644 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2645 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2646 >> 6) | (unsigned char)0x20)));
2647 WRW_HARPOON((port+SYNC_MSGS+2),
2648 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2649 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2651 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2656 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2657 auto_loaded = FPT_siwidn(port,p_card);
2658 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2661 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2662 == SYNC_SUPPORTED)) {
2663 auto_loaded = FPT_sisyncn(port,p_card, 0);
2664 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2671 if (currSCCB->ControlByte & F_USE_CMD_Q)
2674 CurrCard->globalFlags |= F_TAG_STARTED;
2676 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2679 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2681 /* Fix up the start instruction with a jump to
2682 Non-Tag-CMD handling */
2683 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2685 WRW_HARPOON((port+NON_TAG_ID_MSG),
2686 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2688 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2690 /* Setup our STATE so we know what happend when
2691 the wheels fall off. */
2692 currSCCB->Sccb_scsistat = SELECT_ST;
2694 currTar_Info->TarLUNBusy[lun] = 1;
2699 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2701 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2702 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2703 >> 6) | (unsigned char)0x20)));
2705 for (i = 1; i < QUEUE_DEPTH; i++)
2707 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2708 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2710 WRW_HARPOON((port+ID_MSG_STRT+6),
2711 (MPM_OP+AMSG_OUT+lastTag));
2712 CurrCard->tagQ_Lst = lastTag;
2713 currSCCB->Sccb_tag = lastTag;
2714 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2715 CurrCard->discQCount++;
2721 if ( i == QUEUE_DEPTH )
2723 currTar_Info->TarLUNBusy[lun] = 1;
2724 FPT_queueSelectFail(CurrCard,p_card);
2729 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2731 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2738 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2740 WRW_HARPOON((port+NON_TAG_ID_MSG),
2741 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2743 currSCCB->Sccb_scsistat = SELECT_ST;
2745 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2749 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2751 cdb_reg = port + CMD_STRT;
2753 for (i=0; i < currSCCB->CdbLength; i++)
2755 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2760 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2761 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2765 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2766 WR_HARPOON(port+hp_xferstat, 0x00);
2768 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2770 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2773 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2775 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2780 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2781 auto_loaded |= AUTO_IMMED; */
2782 auto_loaded = AUTO_IMMED;
2786 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2793 /*---------------------------------------------------------------------
2795 * Function: FPT_sres
2797 * Description: Hookup the correct CCB and handle the incoming messages.
2799 *---------------------------------------------------------------------*/
2801 static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
2804 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2807 struct sccb_mgr_tar_info * currTar_Info;
2808 struct sccb * currSCCB;
2813 if(pCurrCard->currentSCCB != NULL)
2815 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2819 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2822 currSCCB = pCurrCard->currentSCCB;
2823 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2825 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2826 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2828 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2830 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2831 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2833 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2834 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2836 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2837 if(currSCCB->Sccb_scsistat != ABORT_ST)
2839 pCurrCard->discQCount--;
2840 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2846 currTar_Info->TarLUNBusy[0] = 0;
2847 if(currSCCB->Sccb_tag)
2849 if(currSCCB->Sccb_scsistat != ABORT_ST)
2851 pCurrCard->discQCount--;
2852 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2856 if(currSCCB->Sccb_scsistat != ABORT_ST)
2858 pCurrCard->discQCount--;
2859 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2864 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
2867 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2870 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
2871 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2878 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2882 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2884 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2887 WRW_HARPOON((port+hp_intstat), PHASE);
2892 WRW_HARPOON((port+hp_intstat), PHASE);
2893 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2896 message = FPT_sfm(port,pCurrCard->currentSCCB);
2900 if (message <= (0x80 | LUN_MASK))
2902 lun = message & (unsigned char)LUN_MASK;
2904 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2906 if (currTar_Info->TarTagQ_Cnt != 0)
2909 if (!(currTar_Info->TarLUN_CA))
2911 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2914 message = FPT_sfm(port,pCurrCard->currentSCCB);
2925 tag = FPT_sfm(port,pCurrCard->currentSCCB);
2933 } /*End Q cnt != 0 */
2935 } /*End Tag cmds supported! */
2937 } /*End valid ID message. */
2942 ACCEPT_MSG_ATN(port);
2945 } /* End good id message. */
2955 ACCEPT_MSG_ATN(port);
2957 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2958 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2959 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2967 if(msgRetryCount == 1)
2969 FPT_SendMsg(port, SMPARITY);
2973 FPT_SendMsg(port, SMDEV_RESET);
2975 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
2977 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
2980 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
2984 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
2987 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
2991 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
2992 FPT_SccbMgrTableInitTarget(p_card,our_target);
2996 }while(message == 0);
3000 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3001 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3003 currTar_Info->TarLUNBusy[lun] = 1;
3004 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3005 if(pCurrCard->currentSCCB != NULL)
3011 ACCEPT_MSG_ATN(port);
3016 currTar_Info->TarLUNBusy[0] = 1;
3021 if (pCurrCard->discQ_Tbl[tag] != NULL)
3023 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3024 currTar_Info->TarTagQ_Cnt--;
3029 ACCEPT_MSG_ATN(port);
3033 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3034 if(pCurrCard->currentSCCB != NULL)
3040 ACCEPT_MSG_ATN(port);
3045 if(pCurrCard->currentSCCB != NULL)
3047 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3049 /* During Abort Tag command, the target could have got re-selected
3050 and completed the command. Check the select Q and remove the CCB
3051 if it is in the Select Q */
3052 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
3057 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3058 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3059 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3062 static void FPT_SendMsg(unsigned long port, unsigned char message)
3064 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3066 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3069 WRW_HARPOON((port+hp_intstat), PHASE);
3074 WRW_HARPOON((port+hp_intstat), PHASE);
3075 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3077 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3080 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3082 WR_HARPOON(port+hp_scsidata_0,message);
3084 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3088 WR_HARPOON(port+hp_portctrl_0, 0x00);
3090 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3091 (message == SMABORT_TAG) )
3093 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3095 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3097 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3103 /*---------------------------------------------------------------------
3105 * Function: FPT_sdecm
3107 * Description: Determine the proper responce to the message from the
3110 *---------------------------------------------------------------------*/
3111 static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
3113 struct sccb * currSCCB;
3115 struct sccb_mgr_tar_info * currTar_Info;
3117 CurrCard = &FPT_BL_Card[p_card];
3118 currSCCB = CurrCard->currentSCCB;
3120 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3122 if (message == SMREST_DATA_PTR)
3124 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3126 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3128 FPT_hostDataXferRestart(currSCCB);
3132 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3135 else if (message == SMCMD_COMP)
3139 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3141 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3142 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
3149 else if ((message == SMNO_OP) || (message >= SMIDENT)
3150 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3154 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3157 else if (message == SMREJECT)
3160 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3161 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3162 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3163 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3166 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3171 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3172 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3174 if(currSCCB->Lun == 0x00)
3176 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3179 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3181 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3184 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3188 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3189 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3191 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3195 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3197 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3198 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3201 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3202 CurrCard->discQCount--;
3203 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3204 currSCCB->Sccb_tag = 0x00;
3209 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3213 if(currSCCB->Lun == 0x00)
3215 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3216 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3223 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3224 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3225 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
3227 currTar_Info->TarLUNBusy[0] = 1;
3230 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
3232 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3241 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3242 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3244 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3246 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3251 else if (message == SMEXT)
3255 FPT_shandem(port,p_card,currSCCB);
3258 else if (message == SMIGNORWR)
3261 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3263 message = FPT_sfm(port,currSCCB);
3265 if(currSCCB->Sccb_scsimsg != SMPARITY)
3267 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3274 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3275 currSCCB->Sccb_scsimsg = SMREJECT;
3277 ACCEPT_MSG_ATN(port);
3278 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3283 /*---------------------------------------------------------------------
3285 * Function: FPT_shandem
3287 * Description: Decide what to do with the extended message.
3289 *---------------------------------------------------------------------*/
3290 static void FPT_shandem(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
3292 unsigned char length,message;
3294 length = FPT_sfm(port,pCurrSCCB);
3299 message = FPT_sfm(port,pCurrSCCB);
3303 if (message == SMSYNC)
3310 FPT_stsyncn(port,p_card);
3315 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3316 ACCEPT_MSG_ATN(port);
3319 else if (message == SMWDTR)
3326 FPT_stwidn(port,p_card);
3331 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3332 ACCEPT_MSG_ATN(port);
3334 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3340 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3341 ACCEPT_MSG_ATN(port);
3343 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3348 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3350 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3354 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3355 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3360 /*---------------------------------------------------------------------
3362 * Function: FPT_sisyncn
3364 * Description: Read in a message byte from the SCSI bus, and check
3365 * for a parity error.
3367 *---------------------------------------------------------------------*/
3369 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
3371 struct sccb * currSCCB;
3372 struct sccb_mgr_tar_info * currTar_Info;
3374 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3375 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3377 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3380 WRW_HARPOON((port+ID_MSG_STRT),
3381 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3383 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3385 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3386 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3387 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3390 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3392 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3394 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3396 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3398 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3400 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3403 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3406 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3407 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3408 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3413 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3414 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3415 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
3419 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3428 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3429 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3436 /*---------------------------------------------------------------------
3438 * Function: FPT_stsyncn
3440 * Description: The has sent us a Sync Nego message so handle it as
3443 *---------------------------------------------------------------------*/
3444 static void FPT_stsyncn(unsigned long port, unsigned char p_card)
3446 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
3447 struct sccb * currSCCB;
3448 struct sccb_mgr_tar_info * currTar_Info;
3450 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3451 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3453 sync_msg = FPT_sfm(port,currSCCB);
3455 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3457 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3464 offset = FPT_sfm(port,currSCCB);
3466 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3468 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3472 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3474 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3476 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3478 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3480 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3482 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3485 our_sync_msg = 0; /* Message = Async */
3487 if (sync_msg < our_sync_msg) {
3488 sync_msg = our_sync_msg; /*if faster, then set to max. */
3491 if (offset == ASYNC)
3494 if (offset > MAX_OFFSET)
3495 offset = MAX_OFFSET;
3501 sync_reg = 0x20; /* Use 10MB/s */
3505 sync_reg = 0x40; /* Use 6.6MB/s */
3509 sync_reg = 0x60; /* Use 5MB/s */
3513 sync_reg = 0x80; /* Use 4MB/s */
3517 sync_reg = 0xA0; /* Use 3.33MB/s */
3521 sync_reg = 0xC0; /* Use 2.85MB/s */
3525 sync_reg = 0xE0; /* Use 2.5MB/s */
3527 if (sync_msg > 100) {
3529 sync_reg = 0x00; /* Use ASYNC */
3534 if (currTar_Info->TarStatus & WIDE_ENABLED)
3540 sync_reg |= (offset | NARROW_SCSI);
3542 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
3545 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3550 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3551 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3553 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3559 ACCEPT_MSG_ATN(port);
3561 FPT_sisyncr(port,sync_msg,offset);
3563 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3564 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3569 /*---------------------------------------------------------------------
3571 * Function: FPT_sisyncr
3573 * Description: Answer the targets sync message.
3575 *---------------------------------------------------------------------*/
3576 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
3579 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3580 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3581 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3582 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3583 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3584 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3585 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3588 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3589 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3591 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3593 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3598 /*---------------------------------------------------------------------
3600 * Function: FPT_siwidn
3602 * Description: Read in a message byte from the SCSI bus, and check
3603 * for a parity error.
3605 *---------------------------------------------------------------------*/
3607 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
3609 struct sccb * currSCCB;
3610 struct sccb_mgr_tar_info * currTar_Info;
3612 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3613 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3615 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3618 WRW_HARPOON((port+ID_MSG_STRT),
3619 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3621 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3623 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3624 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3625 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3626 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3627 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3628 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3630 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3633 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3634 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
3641 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3642 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3644 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3651 /*---------------------------------------------------------------------
3653 * Function: FPT_stwidn
3655 * Description: The has sent us a Wide Nego message so handle it as
3658 *---------------------------------------------------------------------*/
3659 static void FPT_stwidn(unsigned long port, unsigned char p_card)
3661 unsigned char width;
3662 struct sccb * currSCCB;
3663 struct sccb_mgr_tar_info * currTar_Info;
3665 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3666 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3668 width = FPT_sfm(port,currSCCB);
3670 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3672 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3677 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3681 currTar_Info->TarStatus |= WIDE_ENABLED;
3685 width = NARROW_SCSI;
3686 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3690 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
3693 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3698 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3700 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3702 ACCEPT_MSG_ATN(port);
3704 FPT_sisyncn(port,p_card, 1);
3705 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3711 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3718 ACCEPT_MSG_ATN(port);
3720 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3725 FPT_siwidr(port,width);
3727 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3732 /*---------------------------------------------------------------------
3734 * Function: FPT_siwidr
3736 * Description: Answer the targets Wide nego message.
3738 *---------------------------------------------------------------------*/
3739 static void FPT_siwidr(unsigned long port, unsigned char width)
3742 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3743 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3744 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3745 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3746 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3747 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3750 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3751 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3753 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3755 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3760 /*---------------------------------------------------------------------
3762 * Function: FPT_sssyncv
3764 * Description: Write the desired value to the Sync Register for the
3767 *---------------------------------------------------------------------*/
3768 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
3769 struct sccb_mgr_tar_info * currTar_Info)
3771 unsigned char index;
3778 index = 12; /* hp_synctarg_0 */
3781 index = 13; /* hp_synctarg_1 */
3784 index = 14; /* hp_synctarg_2 */
3787 index = 15; /* hp_synctarg_3 */
3790 index = 8; /* hp_synctarg_4 */
3793 index = 9; /* hp_synctarg_5 */
3796 index = 10; /* hp_synctarg_6 */
3799 index = 11; /* hp_synctarg_7 */
3802 index = 4; /* hp_synctarg_8 */
3805 index = 5; /* hp_synctarg_9 */
3808 index = 6; /* hp_synctarg_10 */
3811 index = 7; /* hp_synctarg_11 */
3814 index = 0; /* hp_synctarg_12 */
3817 index = 1; /* hp_synctarg_13 */
3820 index = 2; /* hp_synctarg_14 */
3823 index = 3; /* hp_synctarg_15 */
3827 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3829 currTar_Info->TarSyncCtrl = p_sync_value;
3833 /*---------------------------------------------------------------------
3835 * Function: FPT_sresb
3837 * Description: Reset the desired card's SCSI bus.
3839 *---------------------------------------------------------------------*/
3840 static void FPT_sresb(unsigned long port, unsigned char p_card)
3842 unsigned char scsiID, i;
3844 struct sccb_mgr_tar_info * currTar_Info;
3846 WR_HARPOON(port+hp_page_ctrl,
3847 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3848 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3850 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3852 scsiID = RD_HARPOON(port+hp_seltimeout);
3853 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3854 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3856 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3858 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3860 WR_HARPOON(port+hp_seltimeout,scsiID);
3862 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3864 FPT_Wait(port, TO_5ms);
3866 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3868 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3870 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3872 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3874 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3876 currTar_Info->TarSyncCtrl = 0;
3877 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3880 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3882 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3885 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
3887 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3890 FPT_BL_Card[p_card].scanIndex = 0x00;
3891 FPT_BL_Card[p_card].currentSCCB = NULL;
3892 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3894 FPT_BL_Card[p_card].cmdCounter = 0x00;
3895 FPT_BL_Card[p_card].discQCount = 0x00;
3896 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3898 for(i = 0; i < QUEUE_DEPTH; i++)
3899 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3901 WR_HARPOON(port+hp_page_ctrl,
3902 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3906 /*---------------------------------------------------------------------
3908 * Function: FPT_ssenss
3910 * Description: Setup for the Auto Sense command.
3912 *---------------------------------------------------------------------*/
3913 static void FPT_ssenss(PSCCBcard pCurrCard)
3916 struct sccb * currSCCB;
3918 currSCCB = pCurrCard->currentSCCB;
3921 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3923 for (i = 0; i < 6; i++) {
3925 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3928 currSCCB->CdbLength = SIX_BYTE_CMD;
3929 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3930 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3931 currSCCB->Cdb[2] = 0x00;
3932 currSCCB->Cdb[3] = 0x00;
3933 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3934 currSCCB->Cdb[5] = 0x00;
3936 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3938 currSCCB->Sccb_ATC = 0x00;
3940 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3942 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3944 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3946 currSCCB->ControlByte = 0x00;
3948 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3953 /*---------------------------------------------------------------------
3955 * Function: FPT_sxfrp
3957 * Description: Transfer data into the bit bucket until the device
3958 * decides to switch phase.
3960 *---------------------------------------------------------------------*/
3962 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
3964 unsigned char curr_phz;
3967 DISABLE_AUTO(p_port);
3969 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3971 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
3975 /* If the Automation handled the end of the transfer then do not
3976 match the phase or we will get out of sync with the ISR. */
3978 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3981 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3983 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3985 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3988 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3990 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
3991 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
3993 if (curr_phz & (unsigned char)SCSI_IOBIT)
3995 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3997 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
3999 RD_HARPOON(p_port+hp_fifodata_0);
4004 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4005 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4007 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4010 } /* End of While loop for padding data I/O phase */
4012 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4014 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4018 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4019 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4021 RD_HARPOON(p_port+hp_fifodata_0);
4024 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4026 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4027 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4029 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4030 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4035 /*---------------------------------------------------------------------
4037 * Function: FPT_schkdd
4039 * Description: Make sure data has been flushed from both FIFOs and abort
4040 * the operations if necessary.
4042 *---------------------------------------------------------------------*/
4044 static void FPT_schkdd(unsigned long port, unsigned char p_card)
4046 unsigned short TimeOutLoop;
4047 unsigned char sPhase;
4049 struct sccb * currSCCB;
4051 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4054 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4055 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4061 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4064 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4066 currSCCB->Sccb_XferCnt = 1;
4068 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4069 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
4070 WR_HARPOON(port+hp_xferstat, 0x00);
4076 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4078 currSCCB->Sccb_XferCnt = 0;
4081 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4082 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4084 currSCCB->HostStatus = SCCB_PARITY_ERR;
4085 WRW_HARPOON((port+hp_intstat), PARITY);
4089 FPT_hostDataXferAbort(port,p_card,currSCCB);
4092 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4096 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4098 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4101 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
4104 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4107 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4111 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4112 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4113 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
4114 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4115 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4118 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4120 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4122 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4123 FPT_phaseDataIn(port,p_card);
4127 FPT_phaseDataOut(port,p_card);
4132 FPT_sxfrp(port,p_card);
4133 if (!(RDW_HARPOON((port+hp_intstat)) &
4134 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4136 WRW_HARPOON((port+hp_intstat), AUTO_INT);
4137 FPT_phaseDecode(port,p_card);
4144 WR_HARPOON(port+hp_portctrl_0, 0x00);
4149 /*---------------------------------------------------------------------
4151 * Function: FPT_sinits
4153 * Description: Setup SCCB manager fields in this SCCB.
4155 *---------------------------------------------------------------------*/
4157 static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card)
4159 struct sccb_mgr_tar_info * currTar_Info;
4161 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4165 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
4167 p_sccb->Sccb_XferState = 0x00;
4168 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4170 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4171 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4173 p_sccb->Sccb_SGoffset = 0;
4174 p_sccb->Sccb_XferState = F_SG_XFER;
4175 p_sccb->Sccb_XferCnt = 0x00;
4178 if (p_sccb->DataLength == 0x00)
4180 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4182 if (p_sccb->ControlByte & F_USE_CMD_Q)
4184 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4185 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4188 currTar_Info->TarStatus |= TAG_Q_TRYING;
4191 /* For !single SCSI device in system & device allow Disconnect
4192 or command is tag_q type then send Cmd with Disconnect Enable
4193 else send Cmd with Disconnect Disable */
4196 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4197 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4198 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4200 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4201 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4202 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4207 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
4210 p_sccb->HostStatus = 0x00;
4211 p_sccb->TargetStatus = 0x00;
4212 p_sccb->Sccb_tag = 0x00;
4213 p_sccb->Sccb_MGRFlags = 0x00;
4214 p_sccb->Sccb_sgseg = 0x00;
4215 p_sccb->Sccb_ATC = 0x00;
4216 p_sccb->Sccb_savedATC = 0x00;
4218 p_sccb->SccbVirtDataPtr = 0x00;
4219 p_sccb->Sccb_forwardlink = NULL;
4220 p_sccb->Sccb_backlink = NULL;
4222 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4223 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4224 p_sccb->Sccb_scsimsg = SMNO_OP;
4229 /*---------------------------------------------------------------------
4231 * Function: Phase Decode
4233 * Description: Determine the phase and call the appropriate function.
4235 *---------------------------------------------------------------------*/
4237 static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
4239 unsigned char phase_ref;
4240 void (*phase) (unsigned long, unsigned char);
4243 DISABLE_AUTO(p_port);
4245 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4247 phase = FPT_s_PhaseTbl[phase_ref];
4249 (*phase)(p_port, p_card); /* Call the correct phase func */
4254 /*---------------------------------------------------------------------
4256 * Function: Data Out Phase
4258 * Description: Start up both the BusMaster and Xbow.
4260 *---------------------------------------------------------------------*/
4262 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
4265 struct sccb * currSCCB;
4267 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4268 if (currSCCB == NULL)
4270 return; /* Exit if No SCCB record */
4273 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4274 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4276 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4278 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4280 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4282 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4284 if (currSCCB->Sccb_XferCnt == 0) {
4287 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4288 (currSCCB->HostStatus == SCCB_COMPLETE))
4289 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4291 FPT_sxfrp(port,p_card);
4292 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4293 FPT_phaseDecode(port,p_card);
4298 /*---------------------------------------------------------------------
4300 * Function: Data In Phase
4302 * Description: Startup the BusMaster and the XBOW.
4304 *---------------------------------------------------------------------*/
4306 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
4309 struct sccb * currSCCB;
4311 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4313 if (currSCCB == NULL)
4315 return; /* Exit if No SCCB record */
4319 currSCCB->Sccb_scsistat = DATA_IN_ST;
4320 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4321 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4323 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4325 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4327 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4329 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4331 if (currSCCB->Sccb_XferCnt == 0) {
4334 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4335 (currSCCB->HostStatus == SCCB_COMPLETE))
4336 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4338 FPT_sxfrp(port,p_card);
4339 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4340 FPT_phaseDecode(port,p_card);
4345 /*---------------------------------------------------------------------
4347 * Function: Command Phase
4349 * Description: Load the CDB into the automation and start it up.
4351 *---------------------------------------------------------------------*/
4353 static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
4355 struct sccb * currSCCB;
4356 unsigned long cdb_reg;
4359 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4361 if (currSCCB->OperationCode == RESET_COMMAND) {
4363 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4364 currSCCB->CdbLength = SIX_BYTE_CMD;
4367 WR_HARPOON(p_port+hp_scsisig, 0x00);
4369 ARAM_ACCESS(p_port);
4372 cdb_reg = p_port + CMD_STRT;
4374 for (i=0; i < currSCCB->CdbLength; i++) {
4376 if (currSCCB->OperationCode == RESET_COMMAND)
4378 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4381 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4385 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4386 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4388 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4390 currSCCB->Sccb_scsistat = COMMAND_ST;
4392 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4393 SGRAM_ACCESS(p_port);
4397 /*---------------------------------------------------------------------
4399 * Function: Status phase
4401 * Description: Bring in the status and command complete message bytes
4403 *---------------------------------------------------------------------*/
4405 static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
4407 /* Start-up the automation to finish off this command and let the
4408 isr handle the interrupt for command complete when it comes in.
4409 We could wait here for the interrupt to be generated?
4412 WR_HARPOON(port+hp_scsisig, 0x00);
4414 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4418 /*---------------------------------------------------------------------
4420 * Function: Phase Message Out
4422 * Description: Send out our message (if we have one) and handle whatever
4425 *---------------------------------------------------------------------*/
4427 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
4429 unsigned char message,scsiID;
4430 struct sccb * currSCCB;
4431 struct sccb_mgr_tar_info * currTar_Info;
4433 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4435 if (currSCCB != NULL) {
4437 message = currSCCB->Sccb_scsimsg;
4438 scsiID = currSCCB->TargID;
4440 if (message == SMDEV_RESET)
4444 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4445 currTar_Info->TarSyncCtrl = 0;
4446 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
4448 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
4451 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
4455 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
4458 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
4462 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4463 FPT_SccbMgrTableInitTarget(p_card,scsiID);
4465 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4467 currSCCB->HostStatus = SCCB_COMPLETE;
4468 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
4470 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4471 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4476 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4480 if(message == SMNO_OP)
4482 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4484 FPT_ssel(port,p_card);
4492 if (message == SMABORT)
4494 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4503 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4506 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4508 WR_HARPOON(port+hp_scsidata_0,message);
4510 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4514 WR_HARPOON(port+hp_portctrl_0, 0x00);
4516 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4517 (message == SMABORT_TAG) )
4520 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4522 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4524 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4526 if (currSCCB != NULL)
4529 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4530 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4531 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4533 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4535 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
4540 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4547 FPT_sxfrp(port,p_card);
4554 if(message == SMPARITY)
4556 currSCCB->Sccb_scsimsg = SMNO_OP;
4557 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4561 FPT_sxfrp(port,p_card);
4567 /*---------------------------------------------------------------------
4569 * Function: Message In phase
4571 * Description: Bring in the message and determine what to do with it.
4573 *---------------------------------------------------------------------*/
4575 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
4577 unsigned char message;
4578 struct sccb * currSCCB;
4580 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4582 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
4585 FPT_phaseChkFifo(port, p_card);
4588 message = RD_HARPOON(port+hp_scsidata_0);
4589 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4592 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4599 message = FPT_sfm(port,currSCCB);
4604 FPT_sdecm(message,port,p_card);
4609 if(currSCCB->Sccb_scsimsg != SMPARITY)
4611 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4618 /*---------------------------------------------------------------------
4620 * Function: Illegal phase
4622 * Description: Target switched to some illegal phase, so all we can do
4623 * is report an error back to the host (if that is possible)
4624 * and send an ABORT message to the misbehaving target.
4626 *---------------------------------------------------------------------*/
4628 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
4630 struct sccb * currSCCB;
4632 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4634 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4635 if (currSCCB != NULL) {
4637 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4638 currSCCB->Sccb_scsistat = ABORT_ST;
4639 currSCCB->Sccb_scsimsg = SMABORT;
4642 ACCEPT_MSG_ATN(port);
4647 /*---------------------------------------------------------------------
4649 * Function: Phase Check FIFO
4651 * Description: Make sure data has been flushed from both FIFOs and abort
4652 * the operations if necessary.
4654 *---------------------------------------------------------------------*/
4656 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
4658 unsigned long xfercnt;
4659 struct sccb * currSCCB;
4661 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4663 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4666 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4667 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4670 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4672 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4674 currSCCB->Sccb_XferCnt = 0;
4676 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4677 (currSCCB->HostStatus == SCCB_COMPLETE))
4679 currSCCB->HostStatus = SCCB_PARITY_ERR;
4680 WRW_HARPOON((port+hp_intstat), PARITY);
4683 FPT_hostDataXferAbort(port,p_card,currSCCB);
4685 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4687 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4688 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4691 } /*End Data In specific code. */
4695 GET_XFER_CNT(port,xfercnt);
4698 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4701 WR_HARPOON(port+hp_portctrl_0, 0x00);
4703 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4705 currSCCB->Sccb_XferCnt = xfercnt;
4707 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4708 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4710 currSCCB->HostStatus = SCCB_PARITY_ERR;
4711 WRW_HARPOON((port+hp_intstat), PARITY);
4715 FPT_hostDataXferAbort(port,p_card,currSCCB);
4718 WR_HARPOON(port+hp_fifowrite, 0x00);
4719 WR_HARPOON(port+hp_fiforead, 0x00);
4720 WR_HARPOON(port+hp_xferstat, 0x00);
4722 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4726 /*---------------------------------------------------------------------
4728 * Function: Phase Bus Free
4730 * Description: We just went bus free so figure out if it was
4731 * because of command complete or from a disconnect.
4733 *---------------------------------------------------------------------*/
4734 static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
4736 struct sccb * currSCCB;
4738 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4740 if (currSCCB != NULL)
4746 if (currSCCB->OperationCode == RESET_COMMAND)
4749 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4750 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4751 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4753 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4755 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4757 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
4761 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4763 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4764 (unsigned char)SYNC_SUPPORTED;
4765 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4768 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4770 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4771 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4772 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4774 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
4777 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4779 /* Make sure this is not a phony BUS_FREE. If we were
4780 reselected or if BUSY is NOT on then this is a
4781 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4783 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4784 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4786 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4787 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
4799 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4801 if (!currSCCB->HostStatus)
4803 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4806 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4807 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4808 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4810 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4812 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4817 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4819 } /*end if !=null */
4825 /*---------------------------------------------------------------------
4827 * Function: Auto Load Default Map
4829 * Description: Load the Automation RAM with the defualt map values.
4831 *---------------------------------------------------------------------*/
4832 static void FPT_autoLoadDefaultMap(unsigned long p_port)
4834 unsigned long map_addr;
4836 ARAM_ACCESS(p_port);
4837 map_addr = p_port + hp_aramBase;
4839 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4841 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4843 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4845 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4847 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4849 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4851 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4853 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4855 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4857 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4859 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4861 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4863 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4865 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4867 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4869 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4871 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4873 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4874 map_addr +=2; /*This means AYNC DATA IN */
4875 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4877 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4879 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4881 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4883 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4885 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4887 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4889 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4891 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4893 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4895 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4897 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4899 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4901 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4903 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4905 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4907 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4909 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4912 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4914 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4916 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4918 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4919 map_addr +=2; /* DIDN'T GET ONE */
4920 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4922 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4924 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4928 SGRAM_ACCESS(p_port);
4931 /*---------------------------------------------------------------------
4933 * Function: Auto Command Complete
4935 * Description: Post command back to host and find another command
4938 *---------------------------------------------------------------------*/
4940 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
4942 struct sccb * currSCCB;
4943 unsigned char status_byte;
4945 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4947 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4949 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4951 if (status_byte != SSGOOD) {
4953 if (status_byte == SSQ_FULL) {
4956 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4957 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4959 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4960 if(FPT_BL_Card[p_card].discQCount != 0)
4961 FPT_BL_Card[p_card].discQCount--;
4962 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
4966 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
4967 if(currSCCB->Sccb_tag)
4969 if(FPT_BL_Card[p_card].discQCount != 0)
4970 FPT_BL_Card[p_card].discQCount--;
4971 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4974 if(FPT_BL_Card[p_card].discQCount != 0)
4975 FPT_BL_Card[p_card].discQCount--;
4976 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
4980 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4982 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
4987 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4989 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4990 (unsigned char)SYNC_SUPPORTED;
4992 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4993 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4995 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4996 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4998 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4999 if(FPT_BL_Card[p_card].discQCount != 0)
5000 FPT_BL_Card[p_card].discQCount--;
5001 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5005 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5006 if(currSCCB->Sccb_tag)
5008 if(FPT_BL_Card[p_card].discQCount != 0)
5009 FPT_BL_Card[p_card].discQCount--;
5010 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5013 if(FPT_BL_Card[p_card].discQCount != 0)
5014 FPT_BL_Card[p_card].discQCount--;
5015 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5022 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5025 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5026 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
5027 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5029 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5030 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5032 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5033 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5035 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5036 if(FPT_BL_Card[p_card].discQCount != 0)
5037 FPT_BL_Card[p_card].discQCount--;
5038 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5042 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5043 if(currSCCB->Sccb_tag)
5045 if(FPT_BL_Card[p_card].discQCount != 0)
5046 FPT_BL_Card[p_card].discQCount--;
5047 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5050 if(FPT_BL_Card[p_card].discQCount != 0)
5051 FPT_BL_Card[p_card].discQCount--;
5052 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5059 if (status_byte == SSCHECK)
5061 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
5063 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
5065 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
5067 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
5069 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
5074 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5076 currSCCB->SccbStatus = SCCB_ERROR;
5077 currSCCB->TargetStatus = status_byte;
5079 if (status_byte == SSCHECK) {
5081 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5085 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5087 if (currSCCB->RequestSenseLength == 0)
5088 currSCCB->RequestSenseLength = 14;
5090 FPT_ssenss(&FPT_BL_Card[p_card]);
5091 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5093 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5094 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5096 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5097 if(FPT_BL_Card[p_card].discQCount != 0)
5098 FPT_BL_Card[p_card].discQCount--;
5099 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5103 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5104 if(currSCCB->Sccb_tag)
5106 if(FPT_BL_Card[p_card].discQCount != 0)
5107 FPT_BL_Card[p_card].discQCount--;
5108 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5111 if(FPT_BL_Card[p_card].discQCount != 0)
5112 FPT_BL_Card[p_card].discQCount--;
5113 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5123 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5124 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5125 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
5127 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5130 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
5133 #define SHORT_WAIT 0x0000000F
5134 #define LONG_WAIT 0x0000FFFFL
5137 /*---------------------------------------------------------------------
5139 * Function: Data Transfer Processor
5141 * Description: This routine performs two tasks.
5142 * (1) Start data transfer by calling HOST_DATA_XFER_START
5143 * function. Once data transfer is started, (2) Depends
5144 * on the type of data transfer mode Scatter/Gather mode
5145 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5146 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5147 * data transfer done. In Scatter/Gather mode, this routine
5148 * checks bus master command complete and dual rank busy
5149 * bit to keep chaining SC transfer command. Similarly,
5150 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5151 * (F_HOST_XFER_ACT bit) for data transfer done.
5153 *---------------------------------------------------------------------*/
5155 static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
5157 struct sccb * currSCCB;
5159 currSCCB = pCurrCard->currentSCCB;
5161 if (currSCCB->Sccb_XferState & F_SG_XFER)
5163 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5166 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
5167 currSCCB->Sccb_SGoffset = 0x00;
5169 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5171 FPT_busMstrSGDataXferStart(port, currSCCB);
5176 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5178 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5180 FPT_busMstrDataXferStart(port, currSCCB);
5186 /*---------------------------------------------------------------------
5188 * Function: BusMaster Scatter Gather Data Transfer Start
5192 *---------------------------------------------------------------------*/
5193 static void FPT_busMstrSGDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
5195 unsigned long count,addr,tmpSGCnt;
5196 unsigned int sg_index;
5197 unsigned char sg_count, i;
5198 unsigned long reg_offset;
5201 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5203 count = ((unsigned long) HOST_RD_CMD)<<24;
5207 count = ((unsigned long) HOST_WRT_CMD)<<24;
5212 sg_index = pcurrSCCB->Sccb_sgseg;
5213 reg_offset = hp_aramBase;
5216 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5219 WR_HARPOON(p_port+hp_page_ctrl, i);
5221 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
5222 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5224 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
5227 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
5230 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
5231 ((sg_index * 2) + 1));
5234 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5236 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5237 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5239 tmpSGCnt = count & 0x00FFFFFFL;
5242 WR_HARP32(p_port,reg_offset,addr);
5245 WR_HARP32(p_port,reg_offset,count);
5248 count &= 0xFF000000L;
5254 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5256 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5258 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5260 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5263 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5264 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5270 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5271 (tmpSGCnt & 0x000000001))
5274 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5279 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5281 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5282 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5286 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
5291 /*---------------------------------------------------------------------
5293 * Function: BusMaster Data Transfer Start
5297 *---------------------------------------------------------------------*/
5298 static void FPT_busMstrDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
5300 unsigned long addr,count;
5302 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5304 count = pcurrSCCB->Sccb_XferCnt;
5306 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5310 addr = pcurrSCCB->SensePointer;
5311 count = pcurrSCCB->RequestSenseLength;
5315 HP_SETUP_ADDR_CNT(p_port,addr,count);
5318 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5320 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5321 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5323 WR_HARPOON(p_port+hp_xfer_cmd,
5324 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5329 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5330 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5332 WR_HARPOON(p_port+hp_xfer_cmd,
5333 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5339 /*---------------------------------------------------------------------
5341 * Function: BusMaster Timeout Handler
5343 * Description: This function is called after a bus master command busy time
5344 * out is detected. This routines issue halt state machine
5345 * with a software time out for command busy. If command busy
5346 * is still asserted at the end of the time out, it issues
5347 * hard abort with another software time out. It hard abort
5348 * command busy is also time out, it'll just give up.
5350 *---------------------------------------------------------------------*/
5351 static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
5353 unsigned long timeout;
5355 timeout = LONG_WAIT;
5357 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5359 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5363 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5364 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5366 timeout = LONG_WAIT;
5367 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5370 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5372 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5382 /*---------------------------------------------------------------------
5384 * Function: Host Data Transfer Abort
5386 * Description: Abort any in progress transfer.
5388 *---------------------------------------------------------------------*/
5389 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
5392 unsigned long timeout;
5393 unsigned long remain_cnt;
5394 unsigned int sg_ptr;
5396 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5398 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5401 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5403 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5404 timeout = LONG_WAIT;
5406 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5408 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5410 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5412 if (FPT_busMstrTimeOut(port)) {
5414 if (pCurrSCCB->HostStatus == 0x00)
5416 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5420 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5422 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5424 if (pCurrSCCB->HostStatus == 0x00)
5427 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5433 else if (pCurrSCCB->Sccb_XferCnt) {
5435 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5438 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5441 WR_HARPOON(port+hp_sg_addr,0x00);
5443 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5445 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5447 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5450 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5452 while (remain_cnt < 0x01000000L) {
5456 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
5457 DataPointer) + (sg_ptr * 2)))) {
5459 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
5460 DataPointer) + (sg_ptr * 2)));
5471 if (remain_cnt < 0x01000000L) {
5474 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5476 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5479 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5480 && (remain_cnt == 0))
5482 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5488 if (pCurrSCCB->HostStatus == 0x00) {
5490 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5496 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5499 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5501 FPT_busMstrTimeOut(port);
5506 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5508 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5510 if (pCurrSCCB->HostStatus == 0x00) {
5512 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5523 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5525 timeout = SHORT_WAIT;
5527 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5528 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5532 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5534 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5537 timeout = LONG_WAIT;
5539 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5542 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5546 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5548 if (pCurrSCCB->HostStatus == 0x00) {
5550 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5553 FPT_busMstrTimeOut(port);
5557 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5559 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5561 if (pCurrSCCB->HostStatus == 0x00) {
5563 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5574 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5576 timeout = LONG_WAIT;
5578 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5580 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5582 if (pCurrSCCB->HostStatus == 0x00) {
5584 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5587 FPT_busMstrTimeOut(port);
5592 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5594 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5596 if (pCurrSCCB->HostStatus == 0x00) {
5598 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5604 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5606 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5609 WR_HARPOON(port+hp_sg_addr,0x00);
5611 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5613 pCurrSCCB->Sccb_SGoffset = 0x00;
5616 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5617 pCurrSCCB->DataLength) {
5619 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5621 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5628 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5630 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5634 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5639 /*---------------------------------------------------------------------
5641 * Function: Host Data Transfer Restart
5643 * Description: Reset the available count due to a restore data
5646 *---------------------------------------------------------------------*/
5647 static void FPT_hostDataXferRestart(struct sccb * currSCCB)
5649 unsigned long data_count;
5650 unsigned int sg_index;
5651 unsigned long *sg_ptr;
5653 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5655 currSCCB->Sccb_XferCnt = 0;
5657 sg_index = 0xffff; /*Index by long words into sg list. */
5658 data_count = 0; /*Running count of SG xfer counts. */
5660 sg_ptr = (unsigned long *)currSCCB->DataPointer;
5662 while (data_count < currSCCB->Sccb_ATC) {
5665 data_count += *(sg_ptr+(sg_index * 2));
5668 if (data_count == currSCCB->Sccb_ATC) {
5670 currSCCB->Sccb_SGoffset = 0;
5675 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5678 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5682 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5688 /*---------------------------------------------------------------------
5690 * Function: FPT_scini
5692 * Description: Setup all data structures necessary for SCAM selection.
5694 *---------------------------------------------------------------------*/
5696 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
5699 unsigned char loser,assigned_id;
5700 unsigned long p_port;
5702 unsigned char i,k,ScamFlg ;
5704 PNVRamInfo pCurrNvRam;
5706 currCard = &FPT_BL_Card[p_card];
5707 p_port = currCard->ioPort;
5708 pCurrNvRam = currCard->pNvRamInfo;
5712 ScamFlg = pCurrNvRam->niScamConf;
5713 i = pCurrNvRam->niSysConf;
5716 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5717 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
5719 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5722 FPT_inisci(p_card,p_port, p_our_id);
5724 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5725 too slow to return to SCAM selection */
5728 FPT_Wait1Second(p_port);
5730 FPT_Wait(p_port, TO_250ms); */
5732 FPT_Wait1Second(p_port);
5734 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5736 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5741 FPT_scxferc(p_port,SYNC_PTRN);
5742 FPT_scxferc(p_port,DOM_MSTR);
5743 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
5744 } while ( loser == 0xFF );
5748 if ((p_power_up) && (!loser))
5750 FPT_sresb(p_port,p_card);
5751 FPT_Wait(p_port, TO_250ms);
5753 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5758 FPT_scxferc(p_port, SYNC_PTRN);
5759 FPT_scxferc(p_port, DOM_MSTR);
5760 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
5762 } while ( loser == 0xFF );
5777 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5780 if (ScamFlg & SCAM_ENABLED)
5783 for (i=0; i < MAX_SCSI_TAR; i++)
5785 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5786 (FPT_scamInfo[i].state == ID_UNUSED))
5788 if (FPT_scsell(p_port,i))
5790 FPT_scamInfo[i].state = LEGACY;
5791 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5792 (FPT_scamInfo[i].id_string[1] != 0xFA))
5795 FPT_scamInfo[i].id_string[0] = 0xFF;
5796 FPT_scamInfo[i].id_string[1] = 0xFA;
5797 if(pCurrNvRam == NULL)
5798 currCard->globalFlags |= F_UPDATE_EEPROM;
5804 FPT_sresb(p_port,p_card);
5805 FPT_Wait1Second(p_port);
5806 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5808 FPT_scasid(p_card, p_port);
5813 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5815 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5817 FPT_scwtsel(p_port);
5820 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
5822 i = FPT_scxferc(p_port,0x00);
5825 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
5827 i = FPT_scxferc(p_port,0x00);
5830 k = FPT_scxferc(p_port,0x00);
5835 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
5836 FPT_inisci(p_card, p_port, p_our_id);
5837 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5838 FPT_scamInfo[currCard->ourId].id_string[0]
5846 else if (i == SET_P_FLAG)
5848 if (!(FPT_scsendi(p_port,
5849 &FPT_scamInfo[p_our_id].id_string[0])))
5850 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
5852 }while (!assigned_id);
5854 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
5857 if (ScamFlg & SCAM_ENABLED)
5860 if (currCard->globalFlags & F_UPDATE_EEPROM)
5862 FPT_scsavdi(p_card, p_port);
5863 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5869 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5871 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5872 (FPT_scamInfo[i].state == LEGACY))
5877 currCard->globalFlags |= F_SINGLE_DEVICE;
5879 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5884 /*---------------------------------------------------------------------
5886 * Function: FPT_scarb
5888 * Description: Gain control of the bus and wait SCAM select time (250ms)
5890 *---------------------------------------------------------------------*/
5892 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
5894 if (p_sel_type == INIT_SELTD)
5897 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5900 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
5903 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
5906 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5908 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5910 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5916 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5918 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5920 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5921 ~(SCSI_BSY | SCSI_SEL)));
5927 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5929 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5930 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5931 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
5932 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5934 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5936 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5939 FPT_Wait(p_port,TO_250ms);
5945 /*---------------------------------------------------------------------
5947 * Function: FPT_scbusf
5949 * Description: Release the SCSI bus and disable SCAM selection.
5951 *---------------------------------------------------------------------*/
5953 static void FPT_scbusf(unsigned long p_port)
5955 WR_HARPOON(p_port+hp_page_ctrl,
5956 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5959 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5961 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5964 WR_HARPOON(p_port+hp_scsisig, 0x00);
5967 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5970 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5973 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5975 WR_HARPOON(p_port+hp_page_ctrl,
5976 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5981 /*---------------------------------------------------------------------
5983 * Function: FPT_scasid
5985 * Description: Assign an ID to all the SCAM devices.
5987 *---------------------------------------------------------------------*/
5989 static void FPT_scasid(unsigned char p_card, unsigned long p_port)
5991 unsigned char temp_id_string[ID_STRING_LENGTH];
5993 unsigned char i,k,scam_id;
5994 unsigned char crcBytes[3];
5995 PNVRamInfo pCurrNvRam;
5996 unsigned short * pCrcBytes;
5998 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6005 for (k=0; k < ID_STRING_LENGTH; k++)
6007 temp_id_string[k] = (unsigned char) 0x00;
6010 FPT_scxferc(p_port,SYNC_PTRN);
6011 FPT_scxferc(p_port,ASSIGN_ID);
6013 if (!(FPT_sciso(p_port,&temp_id_string[0])))
6016 pCrcBytes = (unsigned short *)&crcBytes[0];
6017 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6018 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
6019 temp_id_string[1] = crcBytes[2];
6020 temp_id_string[2] = crcBytes[0];
6021 temp_id_string[3] = crcBytes[1];
6022 for(k = 4; k < ID_STRING_LENGTH; k++)
6023 temp_id_string[k] = (unsigned char) 0x00;
6025 i = FPT_scmachid(p_card,temp_id_string);
6027 if (i == CLR_PRIORITY)
6029 FPT_scxferc(p_port,MISC_CODE);
6030 FPT_scxferc(p_port,CLR_P_FLAG);
6031 i = 0; /*Not the last ID yet. */
6034 else if (i != NO_ID_AVAIL)
6037 FPT_scxferc(p_port,ID_0_7);
6039 FPT_scxferc(p_port,ID_8_F);
6041 scam_id = (i & (unsigned char) 0x07);
6044 for (k=1; k < 0x08; k <<= 1)
6046 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6048 FPT_scxferc(p_port,scam_id);
6050 i = 0; /*Not the last ID yet. */
6061 FPT_scxferc(p_port,SYNC_PTRN);
6062 FPT_scxferc(p_port,CFG_CMPLT);
6069 /*---------------------------------------------------------------------
6071 * Function: FPT_scsel
6073 * Description: Select all the SCAM devices.
6075 *---------------------------------------------------------------------*/
6077 static void FPT_scsel(unsigned long p_port)
6080 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6081 FPT_scwiros(p_port, SCSI_MSG);
6083 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6086 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6087 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6088 (unsigned char)(BIT(7)+BIT(6))));
6091 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6092 FPT_scwiros(p_port, SCSI_SEL);
6094 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6095 ~(unsigned char)BIT(6)));
6096 FPT_scwirod(p_port, BIT(6));
6098 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6103 /*---------------------------------------------------------------------
6105 * Function: FPT_scxferc
6107 * Description: Handshake the p_data (DB4-0) across the bus.
6109 *---------------------------------------------------------------------*/
6111 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
6113 unsigned char curr_data, ret_data;
6115 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6117 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6119 curr_data &= ~BIT(7);
6121 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6123 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
6124 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6126 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
6128 curr_data |= BIT(6);
6130 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6132 curr_data &= ~BIT(5);
6134 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6136 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
6138 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6139 curr_data |= BIT(7);
6141 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6143 curr_data &= ~BIT(6);
6145 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6147 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
6153 /*---------------------------------------------------------------------
6155 * Function: FPT_scsendi
6157 * Description: Transfer our Identification string to determine if we
6158 * will be the dominant master.
6160 *---------------------------------------------------------------------*/
6162 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
6164 unsigned char ret_data,byte_cnt,bit_cnt,defer;
6168 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6170 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6173 ret_data = FPT_scxferc(p_port,00);
6175 else if (p_id_string[byte_cnt] & bit_cnt)
6177 ret_data = FPT_scxferc(p_port,02);
6181 ret_data = FPT_scxferc(p_port,01);
6186 if ((ret_data & 0x1C) == 0x10)
6187 return(0x00); /*End of isolation stage, we won! */
6189 if (ret_data & 0x1C)
6192 if ((defer) && (!(ret_data & 0x1F)))
6193 return(0x01); /*End of isolation stage, we lost. */
6200 return(0x01); /*We lost */
6202 return(0); /*We WON! Yeeessss! */
6207 /*---------------------------------------------------------------------
6209 * Function: FPT_sciso
6211 * Description: Transfer the Identification string.
6213 *---------------------------------------------------------------------*/
6215 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
6217 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
6221 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6223 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6225 ret_data = FPT_scxferc(p_port,0);
6227 if (ret_data & 0xFC)
6233 if (ret_data & BIT(1)) {
6238 if ((ret_data & 0x1F) == 0)
6241 if(bit_cnt != 0 || bit_cnt != 8)
6245 FPT_scxferc(p_port, SYNC_PTRN);
6246 FPT_scxferc(p_port, ASSIGN_ID);
6258 p_id_string[byte_cnt] = the_data;
6267 /*---------------------------------------------------------------------
6269 * Function: FPT_scwirod
6271 * Description: Sample the SCSI data bus making sure the signal has been
6272 * deasserted for the correct number of consecutive samples.
6274 *---------------------------------------------------------------------*/
6276 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
6281 while ( i < MAX_SCSI_TAR ) {
6283 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6296 /*---------------------------------------------------------------------
6298 * Function: FPT_scwiros
6300 * Description: Sample the SCSI Signal lines making sure the signal has been
6301 * deasserted for the correct number of consecutive samples.
6303 *---------------------------------------------------------------------*/
6305 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
6310 while ( i < MAX_SCSI_TAR ) {
6312 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6324 /*---------------------------------------------------------------------
6326 * Function: FPT_scvalq
6328 * Description: Make sure we received a valid data byte.
6330 *---------------------------------------------------------------------*/
6332 static unsigned char FPT_scvalq(unsigned char p_quintet)
6334 unsigned char count;
6336 for (count=1; count < 0x08; count<<=1) {
6337 if (!(p_quintet & count))
6341 if (p_quintet & 0x18)
6349 /*---------------------------------------------------------------------
6351 * Function: FPT_scsell
6353 * Description: Select the specified device ID using a selection timeout
6354 * less than 4ms. If somebody responds then it is a legacy
6355 * drive and this ID must be marked as such.
6357 *---------------------------------------------------------------------*/
6359 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
6363 WR_HARPOON(p_port+hp_page_ctrl,
6364 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6366 ARAM_ACCESS(p_port);
6368 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6369 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6372 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6373 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6375 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6377 WRW_HARPOON((p_port+hp_intstat),
6378 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6380 WR_HARPOON(p_port+hp_select_id, targ_id);
6382 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6383 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6384 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6387 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6388 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6390 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6391 FPT_Wait(p_port, TO_250ms);
6393 DISABLE_AUTO(p_port);
6395 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6396 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6398 SGRAM_ACCESS(p_port);
6400 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6402 WRW_HARPOON((p_port+hp_intstat),
6403 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6405 WR_HARPOON(p_port+hp_page_ctrl,
6406 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6408 return(0); /*No legacy device */
6413 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6414 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6416 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6421 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6423 WR_HARPOON(p_port+hp_page_ctrl,
6424 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6426 return(1); /*Found one of them oldies! */
6430 /*---------------------------------------------------------------------
6432 * Function: FPT_scwtsel
6434 * Description: Wait to be selected by another SCAM initiator.
6436 *---------------------------------------------------------------------*/
6438 static void FPT_scwtsel(unsigned long p_port)
6440 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6444 /*---------------------------------------------------------------------
6446 * Function: FPT_inisci
6448 * Description: Setup the data Structure with the info from the EEPROM.
6450 *---------------------------------------------------------------------*/
6452 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
6454 unsigned char i,k,max_id;
6455 unsigned short ee_data;
6456 PNVRamInfo pCurrNvRam;
6458 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6460 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6467 for(i = 0; i < max_id; i++){
6469 for(k = 0; k < 4; k++)
6470 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
6471 for(k = 4; k < ID_STRING_LENGTH; k++)
6472 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
6474 if(FPT_scamInfo[i].id_string[0] == 0x00)
6475 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6477 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6481 for (i=0; i < max_id; i++)
6483 for (k=0; k < ID_STRING_LENGTH; k+=2)
6485 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6486 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6487 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
6489 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
6492 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6493 (FPT_scamInfo[i].id_string[0] == 0xFF))
6495 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6498 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6502 for(k = 0; k < ID_STRING_LENGTH; k++)
6503 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6507 /*---------------------------------------------------------------------
6509 * Function: FPT_scmachid
6511 * Description: Match the Device ID string with our values stored in
6514 *---------------------------------------------------------------------*/
6516 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
6519 unsigned char i,k,match;
6522 for (i=0; i < MAX_SCSI_TAR; i++) {
6526 for (k=0; k < ID_STRING_LENGTH; k++)
6528 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6534 FPT_scamInfo[i].state = ID_ASSIGNED;
6542 if (p_id_string[0] & BIT(5))
6547 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6548 match = p_id_string[1] & (unsigned char) 0x1F;
6556 if (FPT_scamInfo[match].state == ID_UNUSED)
6558 for (k=0; k < ID_STRING_LENGTH; k++)
6560 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6563 FPT_scamInfo[match].state = ID_ASSIGNED;
6565 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6566 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6576 if (p_id_string[0] & BIT(5))
6579 match = MAX_SCSI_TAR-1;
6585 if (p_id_string[0] & BIT(7))
6587 return(CLR_PRIORITY);
6591 if (p_id_string[0] & BIT(5))
6596 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6597 match = p_id_string[1] & (unsigned char) 0x1F;
6606 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
6608 for (k=0; k < ID_STRING_LENGTH; k++)
6610 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6613 FPT_scamInfo[match].id_string[0] |= BIT(7);
6614 FPT_scamInfo[match].state = ID_ASSIGNED;
6615 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6616 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6626 if (p_id_string[0] & BIT(5))
6629 match = MAX_SCSI_TAR-1;
6633 return(NO_ID_AVAIL);
6637 /*---------------------------------------------------------------------
6639 * Function: FPT_scsavdi
6641 * Description: Save off the device SCAM ID strings.
6643 *---------------------------------------------------------------------*/
6645 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
6647 unsigned char i,k,max_id;
6648 unsigned short ee_data,sum_data;
6653 for (i = 1; i < EE_SCAMBASE/2; i++)
6655 sum_data += FPT_utilEERead(p_port, i);
6659 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
6661 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6667 for (i=0; i < max_id; i++)
6670 for (k=0; k < ID_STRING_LENGTH; k+=2)
6672 ee_data = FPT_scamInfo[i].id_string[k+1];
6674 ee_data |= FPT_scamInfo[i].id_string[k];
6675 sum_data += ee_data;
6676 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6677 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6682 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6683 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
6686 /*---------------------------------------------------------------------
6688 * Function: FPT_XbowInit
6690 * Description: Setup the Xbow for normal operation.
6692 *---------------------------------------------------------------------*/
6694 static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
6698 i = RD_HARPOON(port+hp_page_ctrl);
6699 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
6701 WR_HARPOON(port+hp_scsireset,0x00);
6702 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6704 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6707 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6709 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6711 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6712 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6714 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6716 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6717 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6719 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6720 FPT_default_intena |= SCAM_SEL;
6722 WRW_HARPOON((port+hp_intena), FPT_default_intena);
6724 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6726 /* Turn on SCSI_MODE8 for narrow cards to fix the
6727 strapping issue with the DUAL CHANNEL card */
6728 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6729 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6731 WR_HARPOON(port+hp_page_ctrl, i);
6736 /*---------------------------------------------------------------------
6738 * Function: FPT_BusMasterInit
6740 * Description: Initialize the BusMaster for normal operations.
6742 *---------------------------------------------------------------------*/
6744 static void FPT_BusMasterInit(unsigned long p_port)
6748 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6749 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6751 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6754 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6756 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6759 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6760 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6761 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6766 /*---------------------------------------------------------------------
6768 * Function: FPT_DiagEEPROM
6770 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6773 *---------------------------------------------------------------------*/
6775 static void FPT_DiagEEPROM(unsigned long p_port)
6777 unsigned short index,temp,max_wd_cnt;
6779 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6780 max_wd_cnt = EEPROM_WD_CNT;
6782 max_wd_cnt = EEPROM_WD_CNT * 2;
6784 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
6786 if (temp == 0x4641) {
6788 for (index = 2; index < max_wd_cnt; index++) {
6790 temp += FPT_utilEERead(p_port, index);
6794 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
6796 return; /*EEPROM is Okay so return now! */
6801 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
6803 for (index = 0; index < max_wd_cnt; index++) {
6805 FPT_utilEEWrite(p_port, 0x0000, index);
6810 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
6812 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
6814 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
6816 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
6818 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
6820 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
6822 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
6824 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
6827 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
6829 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
6831 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
6834 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
6836 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
6838 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
6840 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
6842 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
6844 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
6846 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
6848 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
6852 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
6854 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
6856 FPT_utilEEWrite(p_port, 0x5068, 68/2);
6858 FPT_utilEEWrite(p_port, 0x696F, 70/2);
6860 FPT_utilEEWrite(p_port, 0x746E, 72/2);
6862 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
6864 FPT_utilEEWrite(p_port, 0x2054, 76/2);
6866 FPT_utilEEWrite(p_port, 0x2020, 78/2);
6869 index = ((EE_SCAMBASE/2)+(7*16));
6870 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
6871 temp += (0x0700+TYPE_CODE0);
6873 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6874 temp += 0x5542; /* BUSLOGIC */
6876 FPT_utilEEWrite(p_port, 0x4C53, index);
6879 FPT_utilEEWrite(p_port, 0x474F, index);
6882 FPT_utilEEWrite(p_port, 0x4349, index);
6885 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6886 temp += 0x5442; /* BT- 930 */
6888 FPT_utilEEWrite(p_port, 0x202D, index);
6891 FPT_utilEEWrite(p_port, 0x3339, index);
6893 index++; /*Serial # */
6894 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6897 FPT_utilEEWrite(p_port, 0x5453, index);
6900 FPT_utilEEWrite(p_port, 0x5645, index);
6903 FPT_utilEEWrite(p_port, 0x2045, index);
6906 FPT_utilEEWrite(p_port, 0x202F, index);
6909 FPT_utilEEWrite(p_port, 0x4F4A, index);
6912 FPT_utilEEWrite(p_port, 0x204E, index);
6915 FPT_utilEEWrite(p_port, 0x3539, index);
6920 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
6922 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
6927 /*---------------------------------------------------------------------
6929 * Function: Queue Search Select
6931 * Description: Try to find a new command to execute.
6933 *---------------------------------------------------------------------*/
6935 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
6937 unsigned char scan_ptr, lun;
6938 struct sccb_mgr_tar_info * currTar_Info;
6939 struct sccb * pOldSccb;
6941 scan_ptr = pCurrCard->scanIndex;
6944 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6945 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6946 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6948 if (currTar_Info->TarSelQ_Cnt != 0)
6952 if (scan_ptr == MAX_SCSI_TAR)
6955 for(lun=0; lun < MAX_LUN; lun++)
6957 if(currTar_Info->TarLUNBusy[lun] == 0)
6960 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6963 while((pCurrCard->currentSCCB != NULL) &&
6964 (lun != pCurrCard->currentSCCB->Lun))
6966 pOldSccb = pCurrCard->currentSCCB;
6967 pCurrCard->currentSCCB = (struct sccb *)(pCurrCard->currentSCCB)->
6970 if(pCurrCard->currentSCCB == NULL)
6972 if(pOldSccb != NULL)
6974 pOldSccb->Sccb_forwardlink = (struct sccb *)(pCurrCard->currentSCCB)->
6976 pOldSccb->Sccb_backlink = (struct sccb *)(pCurrCard->currentSCCB)->
6978 currTar_Info->TarSelQ_Cnt--;
6982 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6984 if (currTar_Info->TarSelQ_Head == NULL)
6986 currTar_Info->TarSelQ_Tail = NULL;
6987 currTar_Info->TarSelQ_Cnt = 0;
6991 currTar_Info->TarSelQ_Cnt--;
6992 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
6995 pCurrCard->scanIndex = scan_ptr;
6997 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7007 if (scan_ptr == MAX_SCSI_TAR) {
7015 if ((currTar_Info->TarSelQ_Cnt != 0) &&
7016 (currTar_Info->TarLUNBusy[0] == 0))
7019 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7021 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7023 if (currTar_Info->TarSelQ_Head == NULL)
7025 currTar_Info->TarSelQ_Tail = NULL;
7026 currTar_Info->TarSelQ_Cnt = 0;
7030 currTar_Info->TarSelQ_Cnt--;
7031 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
7035 if (scan_ptr == MAX_SCSI_TAR)
7038 pCurrCard->scanIndex = scan_ptr;
7040 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7048 if (scan_ptr == MAX_SCSI_TAR)
7054 } while (scan_ptr != pCurrCard->scanIndex);
7058 /*---------------------------------------------------------------------
7060 * Function: Queue Select Fail
7062 * Description: Add the current SCCB to the head of the Queue.
7064 *---------------------------------------------------------------------*/
7066 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
7068 unsigned char thisTarg;
7069 struct sccb_mgr_tar_info * currTar_Info;
7071 if (pCurrCard->currentSCCB != NULL)
7073 thisTarg = (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->TargID);
7074 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7076 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
7078 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7080 if (currTar_Info->TarSelQ_Cnt == 0)
7082 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7087 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7091 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7093 pCurrCard->currentSCCB = NULL;
7094 currTar_Info->TarSelQ_Cnt++;
7097 /*---------------------------------------------------------------------
7099 * Function: Queue Command Complete
7101 * Description: Call the callback function with the current SCCB.
7103 *---------------------------------------------------------------------*/
7105 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_sccb,
7106 unsigned char p_card)
7109 unsigned char i, SCSIcmd;
7110 CALL_BK_FN callback;
7111 struct sccb_mgr_tar_info * currTar_Info;
7113 SCSIcmd = p_sccb->Cdb[0];
7116 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7118 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7119 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7120 (p_sccb->TargetStatus != SSCHECK))
7122 if ((SCSIcmd == SCSI_READ) ||
7123 (SCSIcmd == SCSI_WRITE) ||
7124 (SCSIcmd == SCSI_READ_EXTENDED) ||
7125 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7126 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7127 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7128 (pCurrCard->globalFlags & F_NO_FILTER)
7130 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7134 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7136 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7137 p_sccb->SccbStatus = SCCB_ERROR;
7139 p_sccb->SccbStatus = SCCB_SUCCESS;
7142 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7144 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7145 for (i=0; i < 6; i++) {
7146 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7150 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7151 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7153 FPT_utilUpdateResidual(p_sccb);
7156 pCurrCard->cmdCounter--;
7157 if (!pCurrCard->cmdCounter) {
7159 if (pCurrCard->globalFlags & F_GREEN_PC) {
7160 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7161 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7164 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7165 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7169 if(pCurrCard->discQCount != 0)
7171 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7172 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7173 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7175 pCurrCard->discQCount--;
7176 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7180 if(p_sccb->Sccb_tag)
7182 pCurrCard->discQCount--;
7183 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7186 pCurrCard->discQCount--;
7187 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7193 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7195 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7196 pCurrCard->currentSCCB = NULL;
7200 /*---------------------------------------------------------------------
7202 * Function: Queue Disconnect
7204 * Description: Add SCCB to our disconnect array.
7206 *---------------------------------------------------------------------*/
7207 static void FPT_queueDisconnect(struct sccb * p_sccb, unsigned char p_card)
7209 struct sccb_mgr_tar_info * currTar_Info;
7211 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7213 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7214 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7216 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
7220 if (p_sccb->Sccb_tag)
7222 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7223 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7224 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7227 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
7230 FPT_BL_Card[p_card].currentSCCB = NULL;
7234 /*---------------------------------------------------------------------
7236 * Function: Queue Flush SCCB
7238 * Description: Flush all SCCB's back to the host driver for this target.
7240 *---------------------------------------------------------------------*/
7242 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
7244 unsigned char qtag,thisTarg;
7245 struct sccb * currSCCB;
7246 struct sccb_mgr_tar_info * currTar_Info;
7248 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7249 if(currSCCB != NULL)
7251 thisTarg = (unsigned char)currSCCB->TargID;
7252 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7254 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7256 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7257 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7260 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7262 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7264 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7265 currTar_Info->TarTagQ_Cnt--;
7273 /*---------------------------------------------------------------------
7275 * Function: Queue Flush Target SCCB
7277 * Description: Flush all SCCB's back to the host driver for this target.
7279 *---------------------------------------------------------------------*/
7281 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7282 unsigned char error_code)
7285 struct sccb_mgr_tar_info * currTar_Info;
7287 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7289 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7291 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7292 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7295 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7297 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7299 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7300 currTar_Info->TarTagQ_Cnt--;
7311 static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char p_card)
7313 struct sccb_mgr_tar_info * currTar_Info;
7314 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7316 p_SCCB->Sccb_forwardlink = NULL;
7318 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7320 if (currTar_Info->TarSelQ_Cnt == 0) {
7322 currTar_Info->TarSelQ_Head = p_SCCB;
7327 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7331 currTar_Info->TarSelQ_Tail = p_SCCB;
7332 currTar_Info->TarSelQ_Cnt++;
7336 /*---------------------------------------------------------------------
7338 * Function: Queue Find SCCB
7340 * Description: Search the target select Queue for this SCCB, and
7341 * remove it if found.
7343 *---------------------------------------------------------------------*/
7345 static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card)
7347 struct sccb * q_ptr;
7348 struct sccb_mgr_tar_info * currTar_Info;
7350 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7352 q_ptr = currTar_Info->TarSelQ_Head;
7354 while(q_ptr != NULL) {
7356 if (q_ptr == p_SCCB) {
7359 if (currTar_Info->TarSelQ_Head == q_ptr) {
7361 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7364 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7366 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7369 if (q_ptr->Sccb_forwardlink != NULL) {
7370 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7373 if (q_ptr->Sccb_backlink != NULL) {
7374 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7377 currTar_Info->TarSelQ_Cnt--;
7383 q_ptr = q_ptr->Sccb_forwardlink;
7393 /*---------------------------------------------------------------------
7395 * Function: Utility Update Residual Count
7397 * Description: Update the XferCnt to the remaining byte count.
7398 * If we transferred all the data then just write zero.
7399 * If Non-SG transfer then report Total Cnt - Actual Transfer
7400 * Cnt. For SG transfers add the count fields of all
7401 * remaining SG elements, as well as any partial remaining
7404 *---------------------------------------------------------------------*/
7406 static void FPT_utilUpdateResidual(struct sccb * p_SCCB)
7408 unsigned long partial_cnt;
7409 unsigned int sg_index;
7410 unsigned long *sg_ptr;
7412 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7414 p_SCCB->DataLength = 0x0000;
7417 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7419 partial_cnt = 0x0000;
7421 sg_index = p_SCCB->Sccb_sgseg;
7423 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
7425 if (p_SCCB->Sccb_SGoffset) {
7427 partial_cnt = p_SCCB->Sccb_SGoffset;
7431 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
7432 p_SCCB->DataLength ) {
7434 partial_cnt += *(sg_ptr+(sg_index * 2));
7438 p_SCCB->DataLength = partial_cnt;
7443 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7448 /*---------------------------------------------------------------------
7450 * Function: Wait 1 Second
7452 * Description: Wait for 1 second.
7454 *---------------------------------------------------------------------*/
7456 static void FPT_Wait1Second(unsigned long p_port)
7460 for(i=0; i < 4; i++) {
7462 FPT_Wait(p_port, TO_250ms);
7464 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7467 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7473 /*---------------------------------------------------------------------
7475 * Function: FPT_Wait
7477 * Description: Wait the desired delay.
7479 *---------------------------------------------------------------------*/
7481 static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
7483 unsigned char old_timer;
7484 unsigned char green_flag;
7486 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7488 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7489 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7491 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7492 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7493 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
7496 WR_HARPOON(p_port+hp_portctrl_0,
7497 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7499 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7501 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7504 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7508 WR_HARPOON(p_port+hp_portctrl_0,
7509 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7511 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7512 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
7514 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7516 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7520 /*---------------------------------------------------------------------
7522 * Function: Enable/Disable Write to EEPROM
7524 * Description: The EEPROM must first be enabled for writes
7525 * A total of 9 clocks are needed.
7527 *---------------------------------------------------------------------*/
7529 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
7531 unsigned char ee_value;
7533 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7537 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7542 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7544 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7545 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7549 /*---------------------------------------------------------------------
7551 * Function: Write EEPROM
7553 * Description: Write a word to the EEPROM at the specified
7556 *---------------------------------------------------------------------*/
7558 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
7561 unsigned char ee_value;
7564 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7569 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7572 ee_value |= (SEE_MS + SEE_CS);
7574 for(i = 0x8000; i != 0; i>>=1) {
7579 ee_value &= ~SEE_DO;
7581 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7582 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7583 ee_value |= SEE_CLK; /* Clock data! */
7584 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7585 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7586 ee_value &= ~SEE_CLK;
7587 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7588 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7590 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7591 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7593 FPT_Wait(p_port, TO_10ms);
7595 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7596 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7597 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7600 /*---------------------------------------------------------------------
7602 * Function: Read EEPROM
7604 * Description: Read a word from the EEPROM at the desired
7607 *---------------------------------------------------------------------*/
7609 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
7611 unsigned short i, ee_data1, ee_data2;
7614 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7617 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7619 if(ee_data1 == ee_data2)
7622 ee_data1 = ee_data2;
7630 /*---------------------------------------------------------------------
7632 * Function: Read EEPROM Original
7634 * Description: Read a word from the EEPROM at the desired
7637 *---------------------------------------------------------------------*/
7639 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
7642 unsigned char ee_value;
7643 unsigned short i, ee_data;
7645 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7649 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7652 ee_value |= (SEE_MS + SEE_CS);
7655 for(i = 1; i <= 16; i++) {
7657 ee_value |= SEE_CLK; /* Clock data! */
7658 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7659 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7660 ee_value &= ~SEE_CLK;
7661 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7662 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7666 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7670 ee_value &= ~(SEE_MS + SEE_CS);
7671 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7672 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7678 /*---------------------------------------------------------------------
7680 * Function: Send EE command and Address to the EEPROM
7682 * Description: Transfers the correct command and sends the address
7685 *---------------------------------------------------------------------*/
7687 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
7689 unsigned char ee_value;
7690 unsigned char narrow_flg;
7695 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7699 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7701 ee_value |= SEE_CS; /* Set CS to EEPROM */
7702 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7705 for(i = 0x04; i != 0; i>>=1) {
7710 ee_value &= ~SEE_DO;
7712 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7713 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7714 ee_value |= SEE_CLK; /* Clock data! */
7715 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7716 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7717 ee_value &= ~SEE_CLK;
7718 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7719 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7735 ee_value &= ~SEE_DO;
7737 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7738 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7739 ee_value |= SEE_CLK; /* Clock data! */
7740 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7741 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7742 ee_value &= ~SEE_CLK;
7743 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7744 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7750 static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7752 unsigned short crc=0;
7755 for (i=0; i < ID_STRING_LENGTH; i++)
7757 ch = (unsigned short) buffer[i];
7758 for(j=0; j < 8; j++)
7761 crc = (crc >> 1) ^ CRCMASK;
7770 static unsigned char FPT_CalcLrc(unsigned char buffer[])
7775 for(i = 0; i < ID_STRING_LENGTH; i++)
7783 The following inline definitions avoid type conflicts.
7786 static inline unsigned char
7787 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7789 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
7793 static inline FlashPoint_CardHandle_T
7794 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7796 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
7800 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7802 FlashPoint_ReleaseHostAdapter(CardHandle);
7807 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7809 FlashPoint_StartCCB(CardHandle, (struct sccb *) CCB);
7814 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7816 FlashPoint_AbortCCB(CardHandle, (struct sccb *) CCB);
7820 static inline boolean
7821 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7823 return FlashPoint_InterruptPending(CardHandle);
7828 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7830 return FlashPoint_HandleInterrupt(CardHandle);
7834 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7835 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7836 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7837 #define FlashPoint_StartCCB FlashPoint__StartCCB
7838 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7839 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7840 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7843 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7847 Define prototypes for the FlashPoint SCCB Manager Functions.
7850 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7851 extern FlashPoint_CardHandle_T
7852 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7853 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7854 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7855 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7856 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7857 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7860 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */