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)
271 typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
274 typedef struct SCCBMgr_tar_info {
276 struct sccb * TarSelQ_Head;
277 struct sccb * TarSelQ_Tail;
278 unsigned char TarLUN_CA; /*Contingent Allgiance */
279 unsigned char TarTagQ_Cnt;
280 unsigned char TarSelQ_Cnt;
281 unsigned char TarStatus;
282 unsigned char TarEEValue;
283 unsigned char TarSyncCtrl;
284 unsigned char TarReserved[2]; /* for alignment */
285 unsigned char LunDiscQ_Idx[MAX_LUN];
286 unsigned char TarLUNBusy[MAX_LUN];
289 typedef struct NVRAMInfo {
290 unsigned char niModel; /* Model No. of card */
291 unsigned char niCardNo; /* Card no. */
292 unsigned long niBaseAddr; /* Port Address of card */
293 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
294 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
295 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
296 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
297 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
298 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
301 typedef NVRAMINFO *PNVRamInfo;
309 typedef struct SCCBcard {
310 struct sccb * currentSCCB;
311 struct sccb_mgr_info * cardInfo;
313 unsigned long ioPort;
315 unsigned short cmdCounter;
316 unsigned char discQCount;
317 unsigned char tagQ_Lst;
318 unsigned char cardIndex;
319 unsigned char scanIndex;
320 unsigned char globalFlags;
322 PNVRamInfo pNvRamInfo;
323 struct sccb * discQ_Tbl[QUEUE_DEPTH];
327 typedef struct SCCBcard *PSCCBcard;
330 #define F_TAG_STARTED 0x01
331 #define F_CONLUN_IO 0x02
332 #define F_DO_RENEGO 0x04
333 #define F_NO_FILTER 0x08
334 #define F_GREEN_PC 0x10
335 #define F_HOST_XFER_ACT 0x20
336 #define F_NEW_SCCB_CMD 0x40
337 #define F_UPDATE_EEPROM 0x80
340 #define ID_STRING_LENGTH 32
341 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
344 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
346 #define ASSIGN_ID 0x00
347 #define SET_P_FLAG 0x01
348 #define CFG_CMPLT 0x03
349 #define DOM_MSTR 0x0F
350 #define SYNC_PTRN 0x1F
354 #define MISC_CODE 0x14
355 #define CLR_P_FLAG 0x18
359 #define INIT_SELTD 0x01
360 #define LEVEL2_TAR 0x02
363 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
364 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
365 CLR_PRIORITY,NO_ID_AVAIL };
367 typedef struct SCCBscam_info {
369 unsigned char id_string[ID_STRING_LENGTH];
370 enum scam_id_st state;
375 #define SCSI_REQUEST_SENSE 0x03
376 #define SCSI_READ 0x08
377 #define SCSI_WRITE 0x0A
378 #define SCSI_START_STOP_UNIT 0x1B
379 #define SCSI_READ_EXTENDED 0x28
380 #define SCSI_WRITE_EXTENDED 0x2A
381 #define SCSI_WRITE_AND_VERIFY 0x2E
387 #define SSQ_FULL 0x28
392 #define SMCMD_COMP 0x00
394 #define SMSAVE_DATA_PTR 0x02
395 #define SMREST_DATA_PTR 0x03
398 #define SMREJECT 0x07
400 #define SMPARITY 0x09
401 #define SMDEV_RESET 0x0C
402 #define SMABORT_TAG 0x0D
403 #define SMINIT_RECOVERY 0x0F
404 #define SMREL_RECOVERY 0x10
407 #define DISC_PRIV 0x40
414 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
423 #define SIX_BYTE_CMD 0x06
424 #define TWELVE_BYTE_CMD 0x0C
427 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
430 #define EEPROM_WD_CNT 256
432 #define EEPROM_CHECK_SUM 0
433 #define FW_SIGNATURE 2
434 #define MODEL_NUMB_0 4
435 #define MODEL_NUMB_2 6
436 #define MODEL_NUMB_4 8
437 #define SYSTEM_CONFIG 16
438 #define SCSI_CONFIG 17
439 #define BIOS_CONFIG 18
440 #define SCAM_CONFIG 20
441 #define ADAPTER_SCSI_ID 24
444 #define IGNORE_B_SCAN 32
445 #define SEND_START_ENA 34
446 #define DEVICE_ENABLE 36
448 #define SYNC_RATE_TBL 38
449 #define SYNC_RATE_TBL01 38
450 #define SYNC_RATE_TBL23 40
451 #define SYNC_RATE_TBL45 42
452 #define SYNC_RATE_TBL67 44
453 #define SYNC_RATE_TBL89 46
454 #define SYNC_RATE_TBLab 48
455 #define SYNC_RATE_TBLcd 50
456 #define SYNC_RATE_TBLef 52
460 #define EE_SCAMBASE 256
464 #define SCAM_ENABLED BIT(2)
465 #define SCAM_LEVEL2 BIT(3)
468 #define RENEGO_ENA BITW(10)
469 #define CONNIO_ENA BITW(11)
470 #define GREEN_PC_ENA BITW(12)
473 #define AUTO_RATE_00 00
474 #define AUTO_RATE_05 01
475 #define AUTO_RATE_10 02
476 #define AUTO_RATE_20 03
478 #define WIDE_NEGO_BIT BIT(7)
479 #define DISC_ENABLE_BIT BIT(6)
483 #define hp_vendor_id_0 0x00 /* LSB */
484 #define ORION_VEND_0 0x4B
486 #define hp_vendor_id_1 0x01 /* MSB */
487 #define ORION_VEND_1 0x10
489 #define hp_device_id_0 0x02 /* LSB */
490 #define ORION_DEV_0 0x30
492 #define hp_device_id_1 0x03 /* MSB */
493 #define ORION_DEV_1 0x81
495 /* Sub Vendor ID and Sub Device ID only available in
496 Harpoon Version 2 and higher */
498 #define hp_sub_device_id_0 0x06 /* LSB */
502 #define hp_semaphore 0x0C
503 #define SCCB_MGR_ACTIVE BIT(0)
504 #define TICKLE_ME BIT(1)
505 #define SCCB_MGR_PRESENT BIT(3)
506 #define BIOS_IN_USE BIT(4)
510 #define hp_sys_ctrl 0x0F
512 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
513 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
514 #define HALT_MACH BIT(3) /*Halt State Machine */
515 #define HARD_ABORT BIT(4) /*Hard Abort */
525 #define hp_host_blk_cnt 0x13
527 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
529 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
533 #define hp_int_mask 0x17
535 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
536 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
539 #define hp_xfer_cnt_lo 0x18
540 #define hp_xfer_cnt_hi 0x1A
541 #define hp_xfer_cmd 0x1B
543 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
544 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
547 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
549 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
551 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
553 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
554 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
556 #define hp_host_addr_lo 0x1C
557 #define hp_host_addr_hmi 0x1E
559 #define hp_ee_ctrl 0x22
561 #define EXT_ARB_ACK BIT(7)
562 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
563 #define SEE_MS BIT(5)
564 #define SEE_CS BIT(3)
565 #define SEE_CLK BIT(2)
566 #define SEE_DO BIT(1)
567 #define SEE_DI BIT(0)
570 #define EE_WRITE 0x05
572 #define EWEN_ADDR 0x03C0
574 #define EWDS_ADDR 0x0000
582 #define hp_bm_ctrl 0x26
584 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
585 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
586 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
587 #define FAST_SINGLE BIT(6) /*?? */
589 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
592 #define hp_sg_addr 0x28
593 #define hp_page_ctrl 0x29
595 #define SCATTER_EN BIT(0)
596 #define SGRAM_ARAM BIT(1)
597 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
598 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
603 #define hp_pci_stat_cfg 0x2D
605 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
614 #define hp_rev_num 0x33
617 #define hp_stack_data 0x34
618 #define hp_stack_addr 0x35
620 #define hp_ext_status 0x36
622 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
623 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
624 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
625 #define CMD_ABORTED BIT(4) /*Command aborted */
626 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
627 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
628 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
629 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
630 BM_PARITY_ERR | PIO_OVERRUN)
632 #define hp_int_status 0x37
634 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
635 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
636 #define INT_ASSERTED BIT(5) /* */
639 #define hp_fifo_cnt 0x38
644 #define hp_intena 0x40
646 #define RESET BITW(7)
647 #define PROG_HLT BITW(6)
648 #define PARITY BITW(5)
651 #define SCAM_SEL BITW(2)
653 #define TIMEOUT BITW(0)
654 #define BUS_FREE BITW(15)
655 #define XFER_CNT_0 BITW(14)
656 #define PHASE BITW(13)
657 #define IUNKWN BITW(12)
658 #define ICMD_COMP BITW(11)
659 #define ITICKLE BITW(10)
660 #define IDO_STRT BITW(9)
661 #define ITAR_DISC BITW(8)
662 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
663 #define CLR_ALL_INT 0xFFFF
664 #define CLR_ALL_INT_1 0xFF00
666 #define hp_intstat 0x42
668 #define hp_scsisig 0x44
670 #define SCSI_SEL BIT(7)
671 #define SCSI_BSY BIT(6)
672 #define SCSI_REQ BIT(5)
673 #define SCSI_ACK BIT(4)
674 #define SCSI_ATN BIT(3)
675 #define SCSI_CD BIT(2)
676 #define SCSI_MSG BIT(1)
677 #define SCSI_IOBIT BIT(0)
679 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
680 #define S_MSGO_PH (BIT(2)+BIT(1) )
681 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
682 #define S_DATAI_PH ( BIT(0))
683 #define S_DATAO_PH 0x00
684 #define S_ILL_PH ( BIT(1) )
686 #define hp_scsictrl_0 0x45
688 #define SEL_TAR BIT(6)
689 #define ENA_ATN BIT(4)
690 #define ENA_RESEL BIT(2)
691 #define SCSI_RST BIT(1)
692 #define ENA_SCAM_SEL BIT(0)
696 #define hp_portctrl_0 0x46
698 #define SCSI_PORT BIT(7)
699 #define SCSI_INBIT BIT(6)
700 #define DMA_PORT BIT(5)
701 #define DMA_RD BIT(4)
702 #define HOST_PORT BIT(3)
703 #define HOST_WRT BIT(2)
704 #define SCSI_BUS_EN BIT(1)
705 #define START_TO BIT(0)
707 #define hp_scsireset 0x47
709 #define SCSI_INI BIT(6)
710 #define SCAM_EN BIT(5)
711 #define DMA_RESET BIT(3)
712 #define HPSCSI_RESET BIT(2)
713 #define PROG_RESET BIT(1)
714 #define FIFO_CLR BIT(0)
716 #define hp_xfercnt_0 0x48
717 #define hp_xfercnt_2 0x4A
719 #define hp_fifodata_0 0x4C
720 #define hp_addstat 0x4E
722 #define SCAM_TIMER BIT(7)
723 #define SCSI_MODE8 BIT(3)
724 #define SCSI_PAR_ERR BIT(0)
726 #define hp_prgmcnt_0 0x4F
729 #define hp_selfid_0 0x50
730 #define hp_selfid_1 0x51
731 #define hp_arb_id 0x52
734 #define hp_select_id 0x53
737 #define hp_synctarg_base 0x54
738 #define hp_synctarg_12 0x54
739 #define hp_synctarg_13 0x55
740 #define hp_synctarg_14 0x56
741 #define hp_synctarg_15 0x57
743 #define hp_synctarg_8 0x58
744 #define hp_synctarg_9 0x59
745 #define hp_synctarg_10 0x5A
746 #define hp_synctarg_11 0x5B
748 #define hp_synctarg_4 0x5C
749 #define hp_synctarg_5 0x5D
750 #define hp_synctarg_6 0x5E
751 #define hp_synctarg_7 0x5F
753 #define hp_synctarg_0 0x60
754 #define hp_synctarg_1 0x61
755 #define hp_synctarg_2 0x62
756 #define hp_synctarg_3 0x63
758 #define NARROW_SCSI BIT(4)
759 #define DEFAULT_OFFSET 0x0F
761 #define hp_autostart_0 0x64
762 #define hp_autostart_1 0x65
763 #define hp_autostart_3 0x67
767 #define AUTO_IMMED BIT(5)
768 #define SELECT BIT(6)
769 #define END_DATA (BIT(7)+BIT(6))
771 #define hp_gp_reg_0 0x68
772 #define hp_gp_reg_1 0x69
773 #define hp_gp_reg_3 0x6B
775 #define hp_seltimeout 0x6C
778 #define TO_4ms 0x67 /* 3.9959ms */
780 #define TO_5ms 0x03 /* 4.9152ms */
781 #define TO_10ms 0x07 /* 11.xxxms */
782 #define TO_250ms 0x99 /* 250.68ms */
783 #define TO_290ms 0xB1 /* 289.99ms */
785 #define hp_clkctrl_0 0x6D
787 #define PWR_DWN BIT(6)
788 #define ACTdeassert BIT(4)
789 #define CLK_40MHZ (BIT(1) + BIT(0))
791 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
793 #define hp_fiforead 0x6E
794 #define hp_fifowrite 0x6F
796 #define hp_offsetctr 0x70
797 #define hp_xferstat 0x71
799 #define FIFO_EMPTY BIT(6)
801 #define hp_portctrl_1 0x72
803 #define CHK_SCSI_P BIT(3)
804 #define HOST_MODE8 BIT(0)
806 #define hp_xfer_pad 0x73
808 #define ID_UNLOCK BIT(3)
810 #define hp_scsidata_0 0x74
811 #define hp_scsidata_1 0x75
815 #define hp_aramBase 0x80
816 #define BIOS_DATA_OFFSET 0x60
817 #define BIOS_RELATIVE_CARD 0x64
822 #define AR3 (BITW(9) + BITW(8))
823 #define SDATA BITW(10)
826 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
828 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
832 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
834 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
837 #define ADATA_OUT 0x00
838 #define ADATA_IN BITW(8)
839 #define ACOMMAND BITW(10)
840 #define ASTATUS (BITW(10)+BITW(8))
841 #define AMSG_OUT (BITW(10)+BITW(9))
842 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
845 #define BRH_OP BITW(13) /* Branch */
849 #define EQUAL BITW(8)
850 #define NOT_EQ BITW(9)
852 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
855 #define FIFO_0 BITW(10)
858 #define MPM_OP BITW(15) /* Match phase and move data */
861 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
864 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
869 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
879 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
881 #define SSI_OP (BITW(15)+BITW(11))
884 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
885 #define SSI_IDO_STRT (IDO_STRT >> 8)
887 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
888 #define SSI_ITICKLE (ITICKLE >> 8)
890 #define SSI_IUNKWN (IUNKWN >> 8)
891 #define SSI_INO_CC (IUNKWN >> 8)
892 #define SSI_IRFAIL (IUNKWN >> 8)
895 #define NP 0x10 /*Next Phase */
896 #define NTCMD 0x02 /*Non- Tagged Command start */
897 #define CMDPZ 0x04 /*Command phase */
898 #define DINT 0x12 /*Data Out/In interrupt */
899 #define DI 0x13 /*Data Out */
900 #define DC 0x19 /*Disconnect Message */
901 #define ST 0x1D /*Status Phase */
902 #define UNKNWN 0x24 /*Unknown bus action */
903 #define CC 0x25 /*Command Completion failure */
904 #define TICK 0x26 /*New target reselected us. */
905 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
908 #define ID_MSG_STRT hp_aramBase + 0x00
909 #define NON_TAG_ID_MSG hp_aramBase + 0x06
910 #define CMD_STRT hp_aramBase + 0x08
911 #define SYNC_MSGS hp_aramBase + 0x08
917 #define TAG_STRT 0x00
918 #define DISCONNECT_START 0x10/2
919 #define END_DATA_START 0x14/2
920 #define CMD_ONLY_STRT CMDPZ/2
921 #define SELCHK_STRT SELCHK/2
931 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
932 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
934 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
936 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
938 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
939 WR_HARP32(port,hp_xfercnt_0,count),\
940 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
942 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
944 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
945 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
948 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
949 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
953 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
954 WR_HARPOON(port+hp_scsireset, 0x00))
956 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
957 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
959 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
960 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
962 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
963 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
965 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
966 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
971 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
972 static void FPT_ssel(unsigned long port, unsigned char p_card);
973 static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
974 static void FPT_shandem(unsigned long port, unsigned char p_card,struct sccb * pCurrSCCB);
975 static void FPT_stsyncn(unsigned long port, unsigned char p_card);
976 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
977 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
978 PSCCBMgr_tar_info currTar_Info);
979 static void FPT_sresb(unsigned long port, unsigned char p_card);
980 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
981 static void FPT_schkdd(unsigned long port, unsigned char p_card);
982 static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
983 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
984 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
986 static void FPT_SendMsg(unsigned long port, unsigned char message);
987 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
988 unsigned char error_code);
990 static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card);
991 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
993 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
994 static void FPT_stwidn(unsigned long port, unsigned char p_card);
995 static void FPT_siwidr(unsigned long port, unsigned char width);
998 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
999 static void FPT_queueDisconnect(struct sccb * p_SCCB, unsigned char p_card);
1000 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_SCCB,
1001 unsigned char p_card);
1002 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1003 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1004 static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char card);
1005 static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card);
1006 static void FPT_utilUpdateResidual(struct sccb * p_SCCB);
1007 static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
1008 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
1011 static void FPT_Wait1Second(unsigned long p_port);
1012 static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1013 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1014 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1015 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1016 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1017 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
1021 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1022 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1023 static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1024 static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1025 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1026 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1027 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
1029 static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1030 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1031 static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
1036 static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1037 static void FPT_BusMasterInit(unsigned long p_port);
1038 static void FPT_DiagEEPROM(unsigned long p_port);
1043 static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
1044 static void FPT_busMstrSGDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1045 static void FPT_busMstrDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1046 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB);
1047 static void FPT_hostDataXferRestart(struct sccb * currSCCB);
1050 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
1051 PSCCBcard pCurrCard, unsigned short p_int);
1053 static void FPT_SccbMgrTableInitAll(void);
1054 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1055 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
1059 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
1061 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1062 static void FPT_scbusf(unsigned long p_port);
1063 static void FPT_scsel(unsigned long p_port);
1064 static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1065 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1066 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1067 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1068 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1069 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
1070 static unsigned char FPT_scvalq(unsigned char p_quintet);
1071 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1072 static void FPT_scwtsel(unsigned long p_port);
1073 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1074 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
1075 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
1078 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1079 static void FPT_autoLoadDefaultMap(unsigned long p_port);
1084 static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1085 static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1086 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1087 static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1090 static unsigned char FPT_mbCards = 0;
1091 static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1092 ' ', 'B', 'T', '-', '9', '3', '0', \
1093 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1094 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1096 static unsigned short FPT_default_intena = 0;
1099 static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
1102 /*---------------------------------------------------------------------
1104 * Function: FlashPoint_ProbeHostAdapter
1106 * Description: Setup and/or Search for cards and return info to caller.
1108 *---------------------------------------------------------------------*/
1110 static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info * pCardInfo)
1112 static unsigned char first_time = 1;
1114 unsigned char i,j,id,ScamFlg;
1115 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
1116 unsigned long ioport;
1117 PNVRamInfo pCurrNvRam;
1119 ioport = pCardInfo->si_baseaddr;
1122 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1123 return((int)FAILURE);
1125 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1126 return((int)FAILURE);
1128 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1129 return((int)FAILURE);
1131 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1132 return((int)FAILURE);
1135 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1137 /* For new Harpoon then check for sub_device ID LSB
1138 the bits(0-3) must be all ZERO for compatible with
1139 current version of SCCBMgr, else skip this Harpoon
1142 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1143 return((int)FAILURE);
1148 FPT_SccbMgrTableInitAll();
1153 if(FPT_RdStack(ioport, 0) != 0x00) {
1154 if(FPT_ChkIfChipInitialized(ioport) == 0)
1157 WR_HARPOON(ioport+hp_semaphore, 0x00);
1158 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1159 FPT_DiagEEPROM(ioport);
1163 if(FPT_mbCards < MAX_MB_CARDS) {
1164 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1166 pCurrNvRam->niBaseAddr = ioport;
1167 FPT_RNVRamData(pCurrNvRam);
1169 return((int) FAILURE);
1174 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1175 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1178 pCardInfo->si_id = pCurrNvRam->niAdapId;
1180 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1181 (unsigned char)0x0FF);
1183 pCardInfo->si_lun = 0x00;
1184 pCardInfo->si_fw_revision = ORION_FW_REV;
1191 for (id = 0; id < (16/2); id++) {
1194 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1195 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1196 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1198 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1200 for (i = 0; i < 2; temp >>=8,i++) {
1209 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1210 temp6 |= 0x8000; /* Fall through */
1211 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1212 temp5 |= 0x8000; /* Fall through */
1213 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1214 temp2 |= 0x8000; /* Fall through */
1215 case AUTO_RATE_00: /* Asynchronous */
1219 if (temp & DISC_ENABLE_BIT)
1222 if (temp & WIDE_NEGO_BIT)
1228 pCardInfo->si_per_targ_init_sync = temp2;
1229 pCardInfo->si_per_targ_no_disc = temp3;
1230 pCardInfo->si_per_targ_wide_nego = temp4;
1231 pCardInfo->si_per_targ_fast_nego = temp5;
1232 pCardInfo->si_per_targ_ultra_nego = temp6;
1235 i = pCurrNvRam->niSysConf;
1237 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1240 ScamFlg = pCurrNvRam->niScamConf;
1242 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1244 pCardInfo->si_flags = 0x0000;
1247 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1250 pCardInfo->si_flags |= SOFT_RESET;
1253 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1255 if (ScamFlg & SCAM_ENABLED)
1256 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1258 if (ScamFlg & SCAM_LEVEL2)
1259 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1261 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1263 j |= SCSI_TERM_ENA_L;
1265 WR_HARPOON(ioport+hp_bm_ctrl, j );
1267 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1269 j |= SCSI_TERM_ENA_H;
1271 WR_HARPOON(ioport+hp_ee_ctrl, j );
1273 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1275 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1277 pCardInfo->si_card_family = HARPOON_FAMILY;
1278 pCardInfo->si_bustype = BUSTYPE_PCI;
1281 pCardInfo->si_card_model[0] = '9';
1282 switch(pCurrNvRam->niModel & 0x0f){
1284 pCardInfo->si_card_model[1] = '3';
1285 pCardInfo->si_card_model[2] = '0';
1288 pCardInfo->si_card_model[1] = '5';
1289 pCardInfo->si_card_model[2] = '0';
1292 pCardInfo->si_card_model[1] = '3';
1293 pCardInfo->si_card_model[2] = '2';
1296 pCardInfo->si_card_model[1] = '5';
1297 pCardInfo->si_card_model[2] = '2';
1301 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1302 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1303 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1305 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1306 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1309 if (pCardInfo->si_card_model[1] == '3')
1311 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1312 pCardInfo->si_flags |= LOW_BYTE_TERM;
1314 else if (pCardInfo->si_card_model[2] == '0')
1316 temp = RD_HARPOON(ioport+hp_xfer_pad);
1317 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1318 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1319 pCardInfo->si_flags |= LOW_BYTE_TERM;
1320 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1321 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1322 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1323 WR_HARPOON(ioport+hp_xfer_pad, temp);
1327 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1328 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1329 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1330 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1332 for (i = 0; i < 8; i++)
1335 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1337 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1338 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1340 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1341 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1342 if (!(temp3 & BIT(7)))
1343 pCardInfo->si_flags |= LOW_BYTE_TERM;
1344 if (!(temp3 & BIT(6)))
1345 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1349 ARAM_ACCESS(ioport);
1351 for ( i = 0; i < 4; i++ ) {
1353 pCardInfo->si_XlatInfo[i] =
1354 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1357 /* return with -1 if no sort, else return with
1358 logical card number sorted by BIOS (zero-based) */
1360 pCardInfo->si_relative_cardnum =
1361 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1363 SGRAM_ACCESS(ioport);
1365 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1366 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1367 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1368 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1369 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1370 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1371 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1372 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1374 pCardInfo->si_present = 0x01;
1380 /*---------------------------------------------------------------------
1382 * Function: FlashPoint_HardwareResetHostAdapter
1384 * Description: Setup adapter for normal operation (hard reset).
1386 *---------------------------------------------------------------------*/
1388 static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info * pCardInfo)
1390 PSCCBcard CurrCard = NULL;
1391 PNVRamInfo pCurrNvRam;
1392 unsigned char i,j,thisCard, ScamFlg;
1393 unsigned short temp,sync_bit_map,id;
1394 unsigned long ioport;
1396 ioport = pCardInfo->si_baseaddr;
1398 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1400 if (thisCard == MAX_CARDS) {
1405 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1407 CurrCard = &FPT_BL_Card[thisCard];
1408 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1412 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1414 FPT_BL_Card[thisCard].ioPort = ioport;
1415 CurrCard = &FPT_BL_Card[thisCard];
1418 for(i = 0; i < FPT_mbCards; i++){
1419 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1420 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1422 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1423 CurrCard->cardIndex = thisCard;
1424 CurrCard->cardInfo = pCardInfo;
1430 pCurrNvRam = CurrCard->pNvRamInfo;
1433 ScamFlg = pCurrNvRam->niScamConf;
1436 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1440 FPT_BusMasterInit(ioport);
1441 FPT_XbowInit(ioport, ScamFlg);
1443 FPT_autoLoadDefaultMap(ioport);
1446 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1448 WR_HARPOON(ioport+hp_selfid_0, id);
1449 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1450 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1451 CurrCard->ourId = pCardInfo->si_id;
1453 i = (unsigned char) pCardInfo->si_flags;
1454 if (i & SCSI_PARITY_ENA)
1455 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1457 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1458 if (i & LOW_BYTE_TERM)
1459 j |= SCSI_TERM_ENA_L;
1460 WR_HARPOON(ioport+hp_bm_ctrl, j);
1462 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1463 if (i & HIGH_BYTE_TERM)
1464 j |= SCSI_TERM_ENA_H;
1465 WR_HARPOON(ioport+hp_ee_ctrl, j );
1468 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1470 FPT_sresb(ioport,thisCard);
1472 FPT_scini(thisCard, pCardInfo->si_id, 0);
1477 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1478 CurrCard->globalFlags |= F_NO_FILTER;
1481 if(pCurrNvRam->niSysConf & 0x10)
1482 CurrCard->globalFlags |= F_GREEN_PC;
1485 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1486 CurrCard->globalFlags |= F_GREEN_PC;
1489 /* Set global flag to indicate Re-Negotiation to be done on all
1492 if(pCurrNvRam->niScsiConf & 0x04)
1493 CurrCard->globalFlags |= F_DO_RENEGO;
1496 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1497 CurrCard->globalFlags |= F_DO_RENEGO;
1501 if(pCurrNvRam->niScsiConf & 0x08)
1502 CurrCard->globalFlags |= F_CONLUN_IO;
1505 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1506 CurrCard->globalFlags |= F_CONLUN_IO;
1510 temp = pCardInfo->si_per_targ_no_disc;
1512 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1515 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1518 sync_bit_map = 0x0001;
1520 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1523 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1524 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1525 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1527 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1529 for (i = 0; i < 2; temp >>=8,i++) {
1531 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1533 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
1537 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1538 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1539 (unsigned char)(temp & ~EE_SYNC_MASK);
1542 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1545 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1547 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1551 else { /* NARROW SCSI */
1552 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1563 WR_HARPOON((ioport+hp_semaphore),
1564 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1566 return((unsigned long)CurrCard);
1569 static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
1572 unsigned long portBase;
1573 unsigned long regOffset;
1574 unsigned long scamData;
1575 unsigned long *pScamTbl;
1576 PNVRamInfo pCurrNvRam;
1578 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1581 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1582 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1583 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1584 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1585 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1587 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1588 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
1590 portBase = pCurrNvRam->niBaseAddr;
1592 for(i = 0; i < MAX_SCSI_TAR; i++){
1593 regOffset = hp_aramBase + 64 + i*4;
1594 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
1595 scamData = *pScamTbl;
1596 WR_HARP32(portBase, regOffset, scamData);
1600 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1605 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1608 unsigned long portBase;
1609 unsigned long regOffset;
1610 unsigned long scamData;
1611 unsigned long *pScamTbl;
1613 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1614 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1615 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1616 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1617 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1619 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1620 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
1622 portBase = pNvRamInfo->niBaseAddr;
1624 for(i = 0; i < MAX_SCSI_TAR; i++){
1625 regOffset = hp_aramBase + 64 + i*4;
1626 RD_HARP32(portBase, regOffset, scamData);
1627 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
1628 *pScamTbl = scamData;
1633 static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
1635 WR_HARPOON(portBase + hp_stack_addr, index);
1636 return(RD_HARPOON(portBase + hp_stack_data));
1639 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
1641 WR_HARPOON(portBase + hp_stack_addr, index);
1642 WR_HARPOON(portBase + hp_stack_data, data);
1646 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
1648 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1650 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1653 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1654 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1659 /*---------------------------------------------------------------------
1661 * Function: FlashPoint_StartCCB
1663 * Description: Start a command pointed to by p_Sccb. When the
1664 * command is completed it will be returned via the
1665 * callback function.
1667 *---------------------------------------------------------------------*/
1668 static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
1670 unsigned long ioport;
1671 unsigned char thisCard, lun;
1672 struct sccb * pSaveSccb;
1673 CALL_BK_FN callback;
1675 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1676 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1678 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1681 p_Sccb->HostStatus = SCCB_COMPLETE;
1682 p_Sccb->SccbStatus = SCCB_ERROR;
1683 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1690 FPT_sinits(p_Sccb,thisCard);
1693 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1695 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1696 | SCCB_MGR_ACTIVE));
1698 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1700 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1701 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1705 ((PSCCBcard)pCurrCard)->cmdCounter++;
1707 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1709 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1711 if(p_Sccb->OperationCode == RESET_COMMAND)
1713 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1714 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1715 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1716 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1720 FPT_queueAddSccb(p_Sccb,thisCard);
1724 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1726 if(p_Sccb->OperationCode == RESET_COMMAND)
1728 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1729 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1730 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1731 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1735 FPT_queueAddSccb(p_Sccb,thisCard);
1741 MDISABLE_INT(ioport);
1743 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
1744 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1748 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
1749 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1750 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1753 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1754 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1759 if(p_Sccb->OperationCode == RESET_COMMAND)
1761 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1762 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1763 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1764 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1768 FPT_queueAddSccb(p_Sccb,thisCard);
1773 MENABLE_INT(ioport);
1779 /*---------------------------------------------------------------------
1781 * Function: FlashPoint_AbortCCB
1783 * Description: Abort the command pointed to by p_Sccb. When the
1784 * command is completed it will be returned via the
1785 * callback function.
1787 *---------------------------------------------------------------------*/
1788 static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
1790 unsigned long ioport;
1792 unsigned char thisCard;
1793 CALL_BK_FN callback;
1795 struct sccb * pSaveSCCB;
1796 PSCCBMgr_tar_info currTar_Info;
1799 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1801 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1803 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1806 if (FPT_queueFindSccb(p_Sccb,thisCard))
1809 ((PSCCBcard)pCurrCard)->cmdCounter--;
1811 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1812 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1813 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1815 p_Sccb->SccbStatus = SCCB_ABORT;
1816 callback = p_Sccb->SccbCallback;
1824 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1826 p_Sccb->SccbStatus = SCCB_ABORT;
1834 TID = p_Sccb->TargID;
1837 if(p_Sccb->Sccb_tag)
1839 MDISABLE_INT(ioport);
1840 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1842 p_Sccb->SccbStatus = SCCB_ABORT;
1843 p_Sccb->Sccb_scsistat = ABORT_ST;
1844 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1846 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1848 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1849 FPT_ssel(ioport, thisCard);
1853 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1854 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1855 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1856 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1859 MENABLE_INT(ioport);
1864 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1866 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1869 p_Sccb->SccbStatus = SCCB_ABORT;
1880 /*---------------------------------------------------------------------
1882 * Function: FlashPoint_InterruptPending
1884 * Description: Do a quick check to determine if there is a pending
1885 * interrupt for this card and disable the IRQ Pin if so.
1887 *---------------------------------------------------------------------*/
1888 static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
1890 unsigned long ioport;
1892 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1894 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1906 /*---------------------------------------------------------------------
1908 * Function: FlashPoint_HandleInterrupt
1910 * Description: This is our entry point when an interrupt is generated
1911 * by the card and the upper level driver passes it on to
1914 *---------------------------------------------------------------------*/
1915 static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
1917 struct sccb * currSCCB;
1918 unsigned char thisCard,result,bm_status, bm_int_st;
1919 unsigned short hp_int;
1920 unsigned char i, target;
1921 unsigned long ioport;
1923 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1924 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1926 MDISABLE_INT(ioport);
1928 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1929 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
1933 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1935 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1939 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1941 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1942 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1943 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1948 MENABLE_INT(ioport);
1954 else if (hp_int & ICMD_COMP) {
1956 if ( !(hp_int & BUS_FREE) ) {
1957 /* Wait for the BusFree before starting a new command. We
1958 must also check for being reselected since the BusFree
1959 may not show up if another device reselects us in 1.5us or
1960 less. SRR Wednesday, 3/8/1995.
1962 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1965 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1967 FPT_phaseChkFifo(ioport, thisCard);
1969 /* WRW_HARPOON((ioport+hp_intstat),
1970 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1973 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1975 FPT_autoCmdCmplt(ioport,thisCard);
1980 else if (hp_int & ITAR_DISC)
1983 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1985 FPT_phaseChkFifo(ioport, thisCard);
1989 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1991 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
1992 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1994 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1997 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1998 FPT_queueDisconnect(currSCCB,thisCard);
2000 /* Wait for the BusFree before starting a new command. We
2001 must also check for being reselected since the BusFree
2002 may not show up if another device reselects us in 1.5us or
2003 less. SRR Wednesday, 3/8/1995.
2005 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2006 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2007 RD_HARPOON((ioport+hp_scsisig)) ==
2008 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2011 The additional loop exit condition above detects a timing problem
2012 with the revision D/E harpoon chips. The caller should reset the
2013 host adapter to recover when 0xFE is returned.
2015 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2017 MENABLE_INT(ioport);
2021 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2024 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2029 else if (hp_int & RSEL) {
2031 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2033 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2035 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2037 FPT_phaseChkFifo(ioport, thisCard);
2040 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2042 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2043 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2044 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2047 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2048 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2049 FPT_queueDisconnect(currSCCB,thisCard);
2052 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2053 FPT_phaseDecode(ioport,thisCard);
2058 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2061 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2062 FPT_phaseDecode(ioport,thisCard);
2067 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2069 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2070 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
2072 FPT_phaseDecode(ioport,thisCard);
2076 /* Harpoon problem some SCSI target device respond to selection
2077 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2078 to latch the correct Target ID into reg. x53.
2079 The work around require to correct this reg. But when write to this
2080 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2081 need to read this reg first then restore it later. After update to 0x53 */
2083 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2084 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2085 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2086 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2087 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
2088 WR_HARPOON(ioport+hp_fifowrite, i);
2089 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2093 else if (hp_int & XFER_CNT_0) {
2095 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2097 FPT_schkdd(ioport,thisCard);
2102 else if (hp_int & BUS_FREE) {
2104 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2106 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2108 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
2111 FPT_phaseBusFree(ioport,thisCard);
2115 else if (hp_int & ITICKLE) {
2117 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2118 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2123 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2126 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2129 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2131 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
2134 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2135 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2136 FPT_ssel(ioport,thisCard);
2145 MENABLE_INT(ioport);
2150 /*---------------------------------------------------------------------
2152 * Function: Sccb_bad_isr
2154 * Description: Some type of interrupt has occurred which is slightly
2155 * out of the ordinary. We will now decode it fully, in
2156 * this routine. This is broken up in an attempt to save
2159 *---------------------------------------------------------------------*/
2160 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
2161 PSCCBcard pCurrCard, unsigned short p_int)
2163 unsigned char temp, ScamFlg;
2164 PSCCBMgr_tar_info currTar_Info;
2165 PNVRamInfo pCurrNvRam;
2168 if (RD_HARPOON(p_port+hp_ext_status) &
2169 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2172 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2175 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2178 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2181 WR_HARPOON(p_port+hp_pci_stat_cfg,
2182 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2184 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2188 if (pCurrCard->currentSCCB != NULL)
2191 if (!pCurrCard->currentSCCB->HostStatus)
2192 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2194 FPT_sxfrp(p_port,p_card);
2196 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
2197 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2198 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
2199 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2201 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2203 FPT_phaseDecode(p_port,p_card);
2209 else if (p_int & RESET)
2212 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2213 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2214 if (pCurrCard->currentSCCB != NULL) {
2216 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2218 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2222 DISABLE_AUTO(p_port);
2224 FPT_sresb(p_port,p_card);
2226 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2228 pCurrNvRam = pCurrCard->pNvRamInfo;
2230 ScamFlg = pCurrNvRam->niScamConf;
2233 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
2236 FPT_XbowInit(p_port, ScamFlg);
2238 FPT_scini(p_card, pCurrCard->ourId, 0);
2244 else if (p_int & FIFO) {
2246 WRW_HARPOON((p_port+hp_intstat), FIFO);
2248 if (pCurrCard->currentSCCB != NULL)
2249 FPT_sxfrp(p_port,p_card);
2252 else if (p_int & TIMEOUT)
2255 DISABLE_AUTO(p_port);
2257 WRW_HARPOON((p_port+hp_intstat),
2258 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2260 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2263 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2264 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2265 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2266 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
2268 currTar_Info->TarLUNBusy[0] = 0;
2271 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2273 currTar_Info->TarSyncCtrl = 0;
2274 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2277 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2279 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2282 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
2284 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2288 else if (p_int & SCAM_SEL)
2291 FPT_scarb(p_port,LEVEL2_TAR);
2293 FPT_scasid(p_card, p_port);
2297 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2304 /*---------------------------------------------------------------------
2306 * Function: SccbMgrTableInit
2308 * Description: Initialize all Sccb manager data structures.
2310 *---------------------------------------------------------------------*/
2312 static void FPT_SccbMgrTableInitAll()
2314 unsigned char thisCard;
2316 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2318 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
2320 FPT_BL_Card[thisCard].ioPort = 0x00;
2321 FPT_BL_Card[thisCard].cardInfo = NULL;
2322 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2323 FPT_BL_Card[thisCard].ourId = 0x00;
2324 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2329 /*---------------------------------------------------------------------
2331 * Function: SccbMgrTableInit
2333 * Description: Initialize all Sccb manager data structures.
2335 *---------------------------------------------------------------------*/
2337 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
2339 unsigned char scsiID, qtag;
2341 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2343 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2346 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2348 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2349 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2350 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2353 pCurrCard->scanIndex = 0x00;
2354 pCurrCard->currentSCCB = NULL;
2355 pCurrCard->globalFlags = 0x00;
2356 pCurrCard->cmdCounter = 0x00;
2357 pCurrCard->tagQ_Lst = 0x01;
2358 pCurrCard->discQCount = 0;
2364 /*---------------------------------------------------------------------
2366 * Function: SccbMgrTableInit
2368 * Description: Initialize all Sccb manager data structures.
2370 *---------------------------------------------------------------------*/
2372 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
2375 unsigned char lun, qtag;
2376 PSCCBMgr_tar_info currTar_Info;
2378 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2380 currTar_Info->TarSelQ_Cnt = 0;
2381 currTar_Info->TarSyncCtrl = 0;
2383 currTar_Info->TarSelQ_Head = NULL;
2384 currTar_Info->TarSelQ_Tail = NULL;
2385 currTar_Info->TarTagQ_Cnt = 0;
2386 currTar_Info->TarLUN_CA = 0;
2389 for (lun = 0; lun < MAX_LUN; lun++)
2391 currTar_Info->TarLUNBusy[lun] = 0;
2392 currTar_Info->LunDiscQ_Idx[lun] = 0;
2395 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2397 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
2399 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
2401 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2402 FPT_BL_Card[p_card].discQCount--;
2409 /*---------------------------------------------------------------------
2413 * Description: Read in a message byte from the SCSI bus, and check
2414 * for a parity error.
2416 *---------------------------------------------------------------------*/
2418 static unsigned char FPT_sfm(unsigned long port, struct sccb * pCurrSCCB)
2420 unsigned char message;
2421 unsigned short TimeOutLoop;
2424 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2425 (TimeOutLoop++ < 20000) ){}
2428 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2430 message = RD_HARPOON(port+hp_scsidata_0);
2432 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2435 if (TimeOutLoop > 20000)
2436 message = 0x00; /* force message byte = 0 if Time Out on Req */
2438 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2439 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2441 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2442 WR_HARPOON(port+hp_xferstat, 0);
2443 WR_HARPOON(port+hp_fiforead, 0);
2444 WR_HARPOON(port+hp_fifowrite, 0);
2445 if (pCurrSCCB != NULL)
2447 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2452 ACCEPT_MSG_ATN(port);
2454 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2455 (TimeOutLoop++ < 20000) ){}
2456 if (TimeOutLoop > 20000)
2458 WRW_HARPOON((port+hp_intstat), PARITY);
2461 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2463 WRW_HARPOON((port+hp_intstat), PARITY);
2466 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2468 RD_HARPOON(port+hp_scsidata_0);
2470 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2475 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2476 WR_HARPOON(port+hp_xferstat, 0);
2477 WR_HARPOON(port+hp_fiforead, 0);
2478 WR_HARPOON(port+hp_fifowrite, 0);
2483 /*---------------------------------------------------------------------
2485 * Function: FPT_ssel
2487 * Description: Load up automation and select target device.
2489 *---------------------------------------------------------------------*/
2491 static void FPT_ssel(unsigned long port, unsigned char p_card)
2494 unsigned char auto_loaded, i, target, *theCCB;
2496 unsigned long cdb_reg;
2498 struct sccb * currSCCB;
2499 PSCCBMgr_tar_info currTar_Info;
2500 unsigned char lastTag, lun;
2502 CurrCard = &FPT_BL_Card[p_card];
2503 currSCCB = CurrCard->currentSCCB;
2504 target = currSCCB->TargID;
2505 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2506 lastTag = CurrCard->tagQ_Lst;
2511 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2512 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2514 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2515 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2517 lun = currSCCB->Lun;
2522 if (CurrCard->globalFlags & F_TAG_STARTED)
2524 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2526 if ((currTar_Info->TarLUN_CA == 0)
2527 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2531 if (currTar_Info->TarTagQ_Cnt !=0)
2533 currTar_Info->TarLUNBusy[lun] = 1;
2534 FPT_queueSelectFail(CurrCard,p_card);
2540 currTar_Info->TarLUNBusy[lun] = 1;
2543 } /*End non-tagged */
2546 currTar_Info->TarLUNBusy[lun] = 1;
2549 } /*!Use cmd Q Tagged */
2552 if (currTar_Info->TarLUN_CA == 1)
2554 FPT_queueSelectFail(CurrCard,p_card);
2559 currTar_Info->TarLUNBusy[lun] = 1;
2561 } /*else use cmd Q tagged */
2563 } /*if glob tagged started */
2566 currTar_Info->TarLUNBusy[lun] = 1;
2571 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2572 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2573 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2575 if(CurrCard->discQCount >= QUEUE_DEPTH)
2577 currTar_Info->TarLUNBusy[lun] = 1;
2578 FPT_queueSelectFail(CurrCard,p_card);
2582 for (i = 1; i < QUEUE_DEPTH; i++)
2584 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2585 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2587 CurrCard->tagQ_Lst = lastTag;
2588 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2589 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2590 CurrCard->discQCount++;
2594 if(i == QUEUE_DEPTH)
2596 currTar_Info->TarLUNBusy[lun] = 1;
2597 FPT_queueSelectFail(CurrCard,p_card);
2607 WR_HARPOON(port+hp_select_id, target);
2608 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2610 if (currSCCB->OperationCode == RESET_COMMAND) {
2611 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2612 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2614 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2616 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2618 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2620 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2622 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2624 currTar_Info->TarSyncCtrl = 0;
2625 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2628 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2630 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2633 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2634 FPT_SccbMgrTableInitTarget(p_card, target);
2638 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2640 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2641 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2643 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2645 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2646 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2647 >> 6) | (unsigned char)0x20)));
2648 WRW_HARPOON((port+SYNC_MSGS+2),
2649 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2650 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2652 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2657 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2658 auto_loaded = FPT_siwidn(port,p_card);
2659 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2662 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2663 == SYNC_SUPPORTED)) {
2664 auto_loaded = FPT_sisyncn(port,p_card, 0);
2665 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2672 if (currSCCB->ControlByte & F_USE_CMD_Q)
2675 CurrCard->globalFlags |= F_TAG_STARTED;
2677 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2680 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2682 /* Fix up the start instruction with a jump to
2683 Non-Tag-CMD handling */
2684 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2686 WRW_HARPOON((port+NON_TAG_ID_MSG),
2687 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2689 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2691 /* Setup our STATE so we know what happend when
2692 the wheels fall off. */
2693 currSCCB->Sccb_scsistat = SELECT_ST;
2695 currTar_Info->TarLUNBusy[lun] = 1;
2700 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2702 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2703 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2704 >> 6) | (unsigned char)0x20)));
2706 for (i = 1; i < QUEUE_DEPTH; i++)
2708 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2709 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2711 WRW_HARPOON((port+ID_MSG_STRT+6),
2712 (MPM_OP+AMSG_OUT+lastTag));
2713 CurrCard->tagQ_Lst = lastTag;
2714 currSCCB->Sccb_tag = lastTag;
2715 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2716 CurrCard->discQCount++;
2722 if ( i == QUEUE_DEPTH )
2724 currTar_Info->TarLUNBusy[lun] = 1;
2725 FPT_queueSelectFail(CurrCard,p_card);
2730 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2732 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2739 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2741 WRW_HARPOON((port+NON_TAG_ID_MSG),
2742 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2744 currSCCB->Sccb_scsistat = SELECT_ST;
2746 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2750 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2752 cdb_reg = port + CMD_STRT;
2754 for (i=0; i < currSCCB->CdbLength; i++)
2756 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2761 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2762 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2766 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2767 WR_HARPOON(port+hp_xferstat, 0x00);
2769 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2771 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2774 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2776 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2781 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2782 auto_loaded |= AUTO_IMMED; */
2783 auto_loaded = AUTO_IMMED;
2787 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2794 /*---------------------------------------------------------------------
2796 * Function: FPT_sres
2798 * Description: Hookup the correct CCB and handle the incoming messages.
2800 *---------------------------------------------------------------------*/
2802 static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
2805 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2808 PSCCBMgr_tar_info currTar_Info;
2809 struct sccb * currSCCB;
2814 if(pCurrCard->currentSCCB != NULL)
2816 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2820 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2823 currSCCB = pCurrCard->currentSCCB;
2824 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2826 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2827 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2829 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2831 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2832 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2834 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2835 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2837 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2838 if(currSCCB->Sccb_scsistat != ABORT_ST)
2840 pCurrCard->discQCount--;
2841 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2847 currTar_Info->TarLUNBusy[0] = 0;
2848 if(currSCCB->Sccb_tag)
2850 if(currSCCB->Sccb_scsistat != ABORT_ST)
2852 pCurrCard->discQCount--;
2853 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2857 if(currSCCB->Sccb_scsistat != ABORT_ST)
2859 pCurrCard->discQCount--;
2860 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2865 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
2868 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2871 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
2872 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2879 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2883 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2885 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2888 WRW_HARPOON((port+hp_intstat), PHASE);
2893 WRW_HARPOON((port+hp_intstat), PHASE);
2894 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2897 message = FPT_sfm(port,pCurrCard->currentSCCB);
2901 if (message <= (0x80 | LUN_MASK))
2903 lun = message & (unsigned char)LUN_MASK;
2905 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2907 if (currTar_Info->TarTagQ_Cnt != 0)
2910 if (!(currTar_Info->TarLUN_CA))
2912 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2915 message = FPT_sfm(port,pCurrCard->currentSCCB);
2926 tag = FPT_sfm(port,pCurrCard->currentSCCB);
2934 } /*End Q cnt != 0 */
2936 } /*End Tag cmds supported! */
2938 } /*End valid ID message. */
2943 ACCEPT_MSG_ATN(port);
2946 } /* End good id message. */
2956 ACCEPT_MSG_ATN(port);
2958 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2959 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2960 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2968 if(msgRetryCount == 1)
2970 FPT_SendMsg(port, SMPARITY);
2974 FPT_SendMsg(port, SMDEV_RESET);
2976 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
2978 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
2981 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
2985 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
2988 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
2992 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
2993 FPT_SccbMgrTableInitTarget(p_card,our_target);
2997 }while(message == 0);
3001 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3002 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3004 currTar_Info->TarLUNBusy[lun] = 1;
3005 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3006 if(pCurrCard->currentSCCB != NULL)
3012 ACCEPT_MSG_ATN(port);
3017 currTar_Info->TarLUNBusy[0] = 1;
3022 if (pCurrCard->discQ_Tbl[tag] != NULL)
3024 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3025 currTar_Info->TarTagQ_Cnt--;
3030 ACCEPT_MSG_ATN(port);
3034 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3035 if(pCurrCard->currentSCCB != NULL)
3041 ACCEPT_MSG_ATN(port);
3046 if(pCurrCard->currentSCCB != NULL)
3048 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3050 /* During Abort Tag command, the target could have got re-selected
3051 and completed the command. Check the select Q and remove the CCB
3052 if it is in the Select Q */
3053 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
3058 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3059 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3060 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3063 static void FPT_SendMsg(unsigned long port, unsigned char message)
3065 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3067 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3070 WRW_HARPOON((port+hp_intstat), PHASE);
3075 WRW_HARPOON((port+hp_intstat), PHASE);
3076 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3078 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3081 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3083 WR_HARPOON(port+hp_scsidata_0,message);
3085 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3089 WR_HARPOON(port+hp_portctrl_0, 0x00);
3091 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3092 (message == SMABORT_TAG) )
3094 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3096 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3098 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3104 /*---------------------------------------------------------------------
3106 * Function: FPT_sdecm
3108 * Description: Determine the proper responce to the message from the
3111 *---------------------------------------------------------------------*/
3112 static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
3114 struct sccb * currSCCB;
3116 PSCCBMgr_tar_info currTar_Info;
3118 CurrCard = &FPT_BL_Card[p_card];
3119 currSCCB = CurrCard->currentSCCB;
3121 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3123 if (message == SMREST_DATA_PTR)
3125 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3127 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3129 FPT_hostDataXferRestart(currSCCB);
3133 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3136 else if (message == SMCMD_COMP)
3140 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3142 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3143 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
3150 else if ((message == SMNO_OP) || (message >= SMIDENT)
3151 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3155 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3158 else if (message == SMREJECT)
3161 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3162 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3163 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3164 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3167 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3172 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3173 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3175 if(currSCCB->Lun == 0x00)
3177 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3180 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3182 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3185 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3189 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3190 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3192 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3196 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3198 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3199 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3202 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3203 CurrCard->discQCount--;
3204 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3205 currSCCB->Sccb_tag = 0x00;
3210 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3214 if(currSCCB->Lun == 0x00)
3216 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3217 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3224 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3225 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3226 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
3228 currTar_Info->TarLUNBusy[0] = 1;
3231 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
3233 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3242 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3243 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3245 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3247 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3252 else if (message == SMEXT)
3256 FPT_shandem(port,p_card,currSCCB);
3259 else if (message == SMIGNORWR)
3262 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3264 message = FPT_sfm(port,currSCCB);
3266 if(currSCCB->Sccb_scsimsg != SMPARITY)
3268 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3275 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3276 currSCCB->Sccb_scsimsg = SMREJECT;
3278 ACCEPT_MSG_ATN(port);
3279 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3284 /*---------------------------------------------------------------------
3286 * Function: FPT_shandem
3288 * Description: Decide what to do with the extended message.
3290 *---------------------------------------------------------------------*/
3291 static void FPT_shandem(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
3293 unsigned char length,message;
3295 length = FPT_sfm(port,pCurrSCCB);
3300 message = FPT_sfm(port,pCurrSCCB);
3304 if (message == SMSYNC)
3311 FPT_stsyncn(port,p_card);
3316 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3317 ACCEPT_MSG_ATN(port);
3320 else if (message == SMWDTR)
3327 FPT_stwidn(port,p_card);
3332 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3333 ACCEPT_MSG_ATN(port);
3335 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3341 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3342 ACCEPT_MSG_ATN(port);
3344 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3349 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3351 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3355 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3356 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3361 /*---------------------------------------------------------------------
3363 * Function: FPT_sisyncn
3365 * Description: Read in a message byte from the SCSI bus, and check
3366 * for a parity error.
3368 *---------------------------------------------------------------------*/
3370 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
3372 struct sccb * currSCCB;
3373 PSCCBMgr_tar_info currTar_Info;
3375 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3376 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3378 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3381 WRW_HARPOON((port+ID_MSG_STRT),
3382 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3384 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3386 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3387 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3388 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3391 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3393 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3395 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3397 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3399 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3401 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3404 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3407 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3408 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3409 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3414 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3415 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3416 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
3420 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3429 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3430 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3437 /*---------------------------------------------------------------------
3439 * Function: FPT_stsyncn
3441 * Description: The has sent us a Sync Nego message so handle it as
3444 *---------------------------------------------------------------------*/
3445 static void FPT_stsyncn(unsigned long port, unsigned char p_card)
3447 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
3448 struct sccb * currSCCB;
3449 PSCCBMgr_tar_info currTar_Info;
3451 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3452 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3454 sync_msg = FPT_sfm(port,currSCCB);
3456 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3458 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3465 offset = FPT_sfm(port,currSCCB);
3467 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3469 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3473 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3475 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3477 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3479 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3481 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3483 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3486 our_sync_msg = 0; /* Message = Async */
3488 if (sync_msg < our_sync_msg) {
3489 sync_msg = our_sync_msg; /*if faster, then set to max. */
3492 if (offset == ASYNC)
3495 if (offset > MAX_OFFSET)
3496 offset = MAX_OFFSET;
3502 sync_reg = 0x20; /* Use 10MB/s */
3506 sync_reg = 0x40; /* Use 6.6MB/s */
3510 sync_reg = 0x60; /* Use 5MB/s */
3514 sync_reg = 0x80; /* Use 4MB/s */
3518 sync_reg = 0xA0; /* Use 3.33MB/s */
3522 sync_reg = 0xC0; /* Use 2.85MB/s */
3526 sync_reg = 0xE0; /* Use 2.5MB/s */
3528 if (sync_msg > 100) {
3530 sync_reg = 0x00; /* Use ASYNC */
3535 if (currTar_Info->TarStatus & WIDE_ENABLED)
3541 sync_reg |= (offset | NARROW_SCSI);
3543 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
3546 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3551 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3552 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3554 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3560 ACCEPT_MSG_ATN(port);
3562 FPT_sisyncr(port,sync_msg,offset);
3564 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3565 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3570 /*---------------------------------------------------------------------
3572 * Function: FPT_sisyncr
3574 * Description: Answer the targets sync message.
3576 *---------------------------------------------------------------------*/
3577 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
3580 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3581 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3582 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3583 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3584 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3585 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3586 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3589 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3590 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3592 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3594 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3599 /*---------------------------------------------------------------------
3601 * Function: FPT_siwidn
3603 * Description: Read in a message byte from the SCSI bus, and check
3604 * for a parity error.
3606 *---------------------------------------------------------------------*/
3608 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
3610 struct sccb * currSCCB;
3611 PSCCBMgr_tar_info currTar_Info;
3613 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3614 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3616 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3619 WRW_HARPOON((port+ID_MSG_STRT),
3620 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3622 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3624 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3625 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3626 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3627 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3628 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3629 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3631 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3634 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3635 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
3642 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3643 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3645 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3652 /*---------------------------------------------------------------------
3654 * Function: FPT_stwidn
3656 * Description: The has sent us a Wide Nego message so handle it as
3659 *---------------------------------------------------------------------*/
3660 static void FPT_stwidn(unsigned long port, unsigned char p_card)
3662 unsigned char width;
3663 struct sccb * currSCCB;
3664 PSCCBMgr_tar_info currTar_Info;
3666 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3667 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3669 width = FPT_sfm(port,currSCCB);
3671 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3673 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3678 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3682 currTar_Info->TarStatus |= WIDE_ENABLED;
3686 width = NARROW_SCSI;
3687 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3691 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
3694 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3699 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3701 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3703 ACCEPT_MSG_ATN(port);
3705 FPT_sisyncn(port,p_card, 1);
3706 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3712 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3719 ACCEPT_MSG_ATN(port);
3721 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3726 FPT_siwidr(port,width);
3728 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3733 /*---------------------------------------------------------------------
3735 * Function: FPT_siwidr
3737 * Description: Answer the targets Wide nego message.
3739 *---------------------------------------------------------------------*/
3740 static void FPT_siwidr(unsigned long port, unsigned char width)
3743 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3744 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3745 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3746 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3747 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3748 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3751 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3752 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3754 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3756 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3761 /*---------------------------------------------------------------------
3763 * Function: FPT_sssyncv
3765 * Description: Write the desired value to the Sync Register for the
3768 *---------------------------------------------------------------------*/
3769 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
3770 PSCCBMgr_tar_info currTar_Info)
3772 unsigned char index;
3779 index = 12; /* hp_synctarg_0 */
3782 index = 13; /* hp_synctarg_1 */
3785 index = 14; /* hp_synctarg_2 */
3788 index = 15; /* hp_synctarg_3 */
3791 index = 8; /* hp_synctarg_4 */
3794 index = 9; /* hp_synctarg_5 */
3797 index = 10; /* hp_synctarg_6 */
3800 index = 11; /* hp_synctarg_7 */
3803 index = 4; /* hp_synctarg_8 */
3806 index = 5; /* hp_synctarg_9 */
3809 index = 6; /* hp_synctarg_10 */
3812 index = 7; /* hp_synctarg_11 */
3815 index = 0; /* hp_synctarg_12 */
3818 index = 1; /* hp_synctarg_13 */
3821 index = 2; /* hp_synctarg_14 */
3824 index = 3; /* hp_synctarg_15 */
3828 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3830 currTar_Info->TarSyncCtrl = p_sync_value;
3834 /*---------------------------------------------------------------------
3836 * Function: FPT_sresb
3838 * Description: Reset the desired card's SCSI bus.
3840 *---------------------------------------------------------------------*/
3841 static void FPT_sresb(unsigned long port, unsigned char p_card)
3843 unsigned char scsiID, i;
3845 PSCCBMgr_tar_info currTar_Info;
3847 WR_HARPOON(port+hp_page_ctrl,
3848 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3849 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3851 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3853 scsiID = RD_HARPOON(port+hp_seltimeout);
3854 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3855 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3857 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3859 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3861 WR_HARPOON(port+hp_seltimeout,scsiID);
3863 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3865 FPT_Wait(port, TO_5ms);
3867 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3869 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3871 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3873 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3875 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3877 currTar_Info->TarSyncCtrl = 0;
3878 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3881 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3883 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3886 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
3888 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3891 FPT_BL_Card[p_card].scanIndex = 0x00;
3892 FPT_BL_Card[p_card].currentSCCB = NULL;
3893 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3895 FPT_BL_Card[p_card].cmdCounter = 0x00;
3896 FPT_BL_Card[p_card].discQCount = 0x00;
3897 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3899 for(i = 0; i < QUEUE_DEPTH; i++)
3900 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3902 WR_HARPOON(port+hp_page_ctrl,
3903 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3907 /*---------------------------------------------------------------------
3909 * Function: FPT_ssenss
3911 * Description: Setup for the Auto Sense command.
3913 *---------------------------------------------------------------------*/
3914 static void FPT_ssenss(PSCCBcard pCurrCard)
3917 struct sccb * currSCCB;
3919 currSCCB = pCurrCard->currentSCCB;
3922 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3924 for (i = 0; i < 6; i++) {
3926 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3929 currSCCB->CdbLength = SIX_BYTE_CMD;
3930 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3931 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3932 currSCCB->Cdb[2] = 0x00;
3933 currSCCB->Cdb[3] = 0x00;
3934 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3935 currSCCB->Cdb[5] = 0x00;
3937 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3939 currSCCB->Sccb_ATC = 0x00;
3941 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3943 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3945 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3947 currSCCB->ControlByte = 0x00;
3949 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3954 /*---------------------------------------------------------------------
3956 * Function: FPT_sxfrp
3958 * Description: Transfer data into the bit bucket until the device
3959 * decides to switch phase.
3961 *---------------------------------------------------------------------*/
3963 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
3965 unsigned char curr_phz;
3968 DISABLE_AUTO(p_port);
3970 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3972 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
3976 /* If the Automation handled the end of the transfer then do not
3977 match the phase or we will get out of sync with the ISR. */
3979 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3982 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3984 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3986 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3989 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3991 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
3992 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
3994 if (curr_phz & (unsigned char)SCSI_IOBIT)
3996 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3998 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4000 RD_HARPOON(p_port+hp_fifodata_0);
4005 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4006 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4008 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4011 } /* End of While loop for padding data I/O phase */
4013 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4015 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4019 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4020 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4022 RD_HARPOON(p_port+hp_fifodata_0);
4025 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4027 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4028 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4030 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4031 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4036 /*---------------------------------------------------------------------
4038 * Function: FPT_schkdd
4040 * Description: Make sure data has been flushed from both FIFOs and abort
4041 * the operations if necessary.
4043 *---------------------------------------------------------------------*/
4045 static void FPT_schkdd(unsigned long port, unsigned char p_card)
4047 unsigned short TimeOutLoop;
4048 unsigned char sPhase;
4050 struct sccb * currSCCB;
4052 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4055 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4056 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4062 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4065 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4067 currSCCB->Sccb_XferCnt = 1;
4069 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4070 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
4071 WR_HARPOON(port+hp_xferstat, 0x00);
4077 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4079 currSCCB->Sccb_XferCnt = 0;
4082 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4083 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4085 currSCCB->HostStatus = SCCB_PARITY_ERR;
4086 WRW_HARPOON((port+hp_intstat), PARITY);
4090 FPT_hostDataXferAbort(port,p_card,currSCCB);
4093 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4097 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4099 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4102 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
4105 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4108 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4112 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4113 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4114 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
4115 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4116 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4119 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4121 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4123 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4124 FPT_phaseDataIn(port,p_card);
4128 FPT_phaseDataOut(port,p_card);
4133 FPT_sxfrp(port,p_card);
4134 if (!(RDW_HARPOON((port+hp_intstat)) &
4135 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4137 WRW_HARPOON((port+hp_intstat), AUTO_INT);
4138 FPT_phaseDecode(port,p_card);
4145 WR_HARPOON(port+hp_portctrl_0, 0x00);
4150 /*---------------------------------------------------------------------
4152 * Function: FPT_sinits
4154 * Description: Setup SCCB manager fields in this SCCB.
4156 *---------------------------------------------------------------------*/
4158 static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card)
4160 PSCCBMgr_tar_info currTar_Info;
4162 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4166 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
4168 p_sccb->Sccb_XferState = 0x00;
4169 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4171 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4172 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4174 p_sccb->Sccb_SGoffset = 0;
4175 p_sccb->Sccb_XferState = F_SG_XFER;
4176 p_sccb->Sccb_XferCnt = 0x00;
4179 if (p_sccb->DataLength == 0x00)
4181 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4183 if (p_sccb->ControlByte & F_USE_CMD_Q)
4185 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4186 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4189 currTar_Info->TarStatus |= TAG_Q_TRYING;
4192 /* For !single SCSI device in system & device allow Disconnect
4193 or command is tag_q type then send Cmd with Disconnect Enable
4194 else send Cmd with Disconnect Disable */
4197 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4198 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4199 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4201 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4202 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4203 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4208 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
4211 p_sccb->HostStatus = 0x00;
4212 p_sccb->TargetStatus = 0x00;
4213 p_sccb->Sccb_tag = 0x00;
4214 p_sccb->Sccb_MGRFlags = 0x00;
4215 p_sccb->Sccb_sgseg = 0x00;
4216 p_sccb->Sccb_ATC = 0x00;
4217 p_sccb->Sccb_savedATC = 0x00;
4219 p_sccb->SccbVirtDataPtr = 0x00;
4220 p_sccb->Sccb_forwardlink = NULL;
4221 p_sccb->Sccb_backlink = NULL;
4223 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4224 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4225 p_sccb->Sccb_scsimsg = SMNO_OP;
4230 /*---------------------------------------------------------------------
4232 * Function: Phase Decode
4234 * Description: Determine the phase and call the appropriate function.
4236 *---------------------------------------------------------------------*/
4238 static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
4240 unsigned char phase_ref;
4241 void (*phase) (unsigned long, unsigned char);
4244 DISABLE_AUTO(p_port);
4246 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4248 phase = FPT_s_PhaseTbl[phase_ref];
4250 (*phase)(p_port, p_card); /* Call the correct phase func */
4255 /*---------------------------------------------------------------------
4257 * Function: Data Out Phase
4259 * Description: Start up both the BusMaster and Xbow.
4261 *---------------------------------------------------------------------*/
4263 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
4266 struct sccb * currSCCB;
4268 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4269 if (currSCCB == NULL)
4271 return; /* Exit if No SCCB record */
4274 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4275 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4277 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4279 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4281 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4283 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4285 if (currSCCB->Sccb_XferCnt == 0) {
4288 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4289 (currSCCB->HostStatus == SCCB_COMPLETE))
4290 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4292 FPT_sxfrp(port,p_card);
4293 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4294 FPT_phaseDecode(port,p_card);
4299 /*---------------------------------------------------------------------
4301 * Function: Data In Phase
4303 * Description: Startup the BusMaster and the XBOW.
4305 *---------------------------------------------------------------------*/
4307 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
4310 struct sccb * currSCCB;
4312 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4314 if (currSCCB == NULL)
4316 return; /* Exit if No SCCB record */
4320 currSCCB->Sccb_scsistat = DATA_IN_ST;
4321 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4322 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4324 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4326 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4328 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4330 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4332 if (currSCCB->Sccb_XferCnt == 0) {
4335 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4336 (currSCCB->HostStatus == SCCB_COMPLETE))
4337 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4339 FPT_sxfrp(port,p_card);
4340 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4341 FPT_phaseDecode(port,p_card);
4346 /*---------------------------------------------------------------------
4348 * Function: Command Phase
4350 * Description: Load the CDB into the automation and start it up.
4352 *---------------------------------------------------------------------*/
4354 static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
4356 struct sccb * currSCCB;
4357 unsigned long cdb_reg;
4360 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4362 if (currSCCB->OperationCode == RESET_COMMAND) {
4364 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4365 currSCCB->CdbLength = SIX_BYTE_CMD;
4368 WR_HARPOON(p_port+hp_scsisig, 0x00);
4370 ARAM_ACCESS(p_port);
4373 cdb_reg = p_port + CMD_STRT;
4375 for (i=0; i < currSCCB->CdbLength; i++) {
4377 if (currSCCB->OperationCode == RESET_COMMAND)
4379 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4382 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4386 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4387 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4389 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4391 currSCCB->Sccb_scsistat = COMMAND_ST;
4393 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4394 SGRAM_ACCESS(p_port);
4398 /*---------------------------------------------------------------------
4400 * Function: Status phase
4402 * Description: Bring in the status and command complete message bytes
4404 *---------------------------------------------------------------------*/
4406 static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
4408 /* Start-up the automation to finish off this command and let the
4409 isr handle the interrupt for command complete when it comes in.
4410 We could wait here for the interrupt to be generated?
4413 WR_HARPOON(port+hp_scsisig, 0x00);
4415 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4419 /*---------------------------------------------------------------------
4421 * Function: Phase Message Out
4423 * Description: Send out our message (if we have one) and handle whatever
4426 *---------------------------------------------------------------------*/
4428 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
4430 unsigned char message,scsiID;
4431 struct sccb * currSCCB;
4432 PSCCBMgr_tar_info currTar_Info;
4434 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4436 if (currSCCB != NULL) {
4438 message = currSCCB->Sccb_scsimsg;
4439 scsiID = currSCCB->TargID;
4441 if (message == SMDEV_RESET)
4445 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4446 currTar_Info->TarSyncCtrl = 0;
4447 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
4449 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
4452 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
4456 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
4459 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
4463 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4464 FPT_SccbMgrTableInitTarget(p_card,scsiID);
4466 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4468 currSCCB->HostStatus = SCCB_COMPLETE;
4469 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
4471 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4472 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4477 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4481 if(message == SMNO_OP)
4483 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4485 FPT_ssel(port,p_card);
4493 if (message == SMABORT)
4495 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4504 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4507 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4509 WR_HARPOON(port+hp_scsidata_0,message);
4511 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4515 WR_HARPOON(port+hp_portctrl_0, 0x00);
4517 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4518 (message == SMABORT_TAG) )
4521 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4523 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4525 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4527 if (currSCCB != NULL)
4530 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4531 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4532 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4534 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4536 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
4541 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4548 FPT_sxfrp(port,p_card);
4555 if(message == SMPARITY)
4557 currSCCB->Sccb_scsimsg = SMNO_OP;
4558 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4562 FPT_sxfrp(port,p_card);
4568 /*---------------------------------------------------------------------
4570 * Function: Message In phase
4572 * Description: Bring in the message and determine what to do with it.
4574 *---------------------------------------------------------------------*/
4576 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
4578 unsigned char message;
4579 struct sccb * currSCCB;
4581 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4583 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
4586 FPT_phaseChkFifo(port, p_card);
4589 message = RD_HARPOON(port+hp_scsidata_0);
4590 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4593 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4600 message = FPT_sfm(port,currSCCB);
4605 FPT_sdecm(message,port,p_card);
4610 if(currSCCB->Sccb_scsimsg != SMPARITY)
4612 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4619 /*---------------------------------------------------------------------
4621 * Function: Illegal phase
4623 * Description: Target switched to some illegal phase, so all we can do
4624 * is report an error back to the host (if that is possible)
4625 * and send an ABORT message to the misbehaving target.
4627 *---------------------------------------------------------------------*/
4629 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
4631 struct sccb * currSCCB;
4633 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4635 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4636 if (currSCCB != NULL) {
4638 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4639 currSCCB->Sccb_scsistat = ABORT_ST;
4640 currSCCB->Sccb_scsimsg = SMABORT;
4643 ACCEPT_MSG_ATN(port);
4648 /*---------------------------------------------------------------------
4650 * Function: Phase Check FIFO
4652 * Description: Make sure data has been flushed from both FIFOs and abort
4653 * the operations if necessary.
4655 *---------------------------------------------------------------------*/
4657 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
4659 unsigned long xfercnt;
4660 struct sccb * currSCCB;
4662 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4664 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4667 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4668 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4671 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4673 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4675 currSCCB->Sccb_XferCnt = 0;
4677 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4678 (currSCCB->HostStatus == SCCB_COMPLETE))
4680 currSCCB->HostStatus = SCCB_PARITY_ERR;
4681 WRW_HARPOON((port+hp_intstat), PARITY);
4684 FPT_hostDataXferAbort(port,p_card,currSCCB);
4686 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4688 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4689 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4692 } /*End Data In specific code. */
4696 GET_XFER_CNT(port,xfercnt);
4699 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4702 WR_HARPOON(port+hp_portctrl_0, 0x00);
4704 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4706 currSCCB->Sccb_XferCnt = xfercnt;
4708 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4709 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4711 currSCCB->HostStatus = SCCB_PARITY_ERR;
4712 WRW_HARPOON((port+hp_intstat), PARITY);
4716 FPT_hostDataXferAbort(port,p_card,currSCCB);
4719 WR_HARPOON(port+hp_fifowrite, 0x00);
4720 WR_HARPOON(port+hp_fiforead, 0x00);
4721 WR_HARPOON(port+hp_xferstat, 0x00);
4723 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4727 /*---------------------------------------------------------------------
4729 * Function: Phase Bus Free
4731 * Description: We just went bus free so figure out if it was
4732 * because of command complete or from a disconnect.
4734 *---------------------------------------------------------------------*/
4735 static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
4737 struct sccb * currSCCB;
4739 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4741 if (currSCCB != NULL)
4747 if (currSCCB->OperationCode == RESET_COMMAND)
4750 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4751 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4752 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4754 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4756 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4758 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
4762 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4764 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4765 (unsigned char)SYNC_SUPPORTED;
4766 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4769 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4771 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4772 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4773 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4775 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
4778 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4780 /* Make sure this is not a phony BUS_FREE. If we were
4781 reselected or if BUSY is NOT on then this is a
4782 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4784 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4785 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4787 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4788 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
4800 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4802 if (!currSCCB->HostStatus)
4804 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4807 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4808 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4809 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4811 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4813 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4818 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4820 } /*end if !=null */
4826 /*---------------------------------------------------------------------
4828 * Function: Auto Load Default Map
4830 * Description: Load the Automation RAM with the defualt map values.
4832 *---------------------------------------------------------------------*/
4833 static void FPT_autoLoadDefaultMap(unsigned long p_port)
4835 unsigned long map_addr;
4837 ARAM_ACCESS(p_port);
4838 map_addr = p_port + hp_aramBase;
4840 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4842 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4844 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4846 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4848 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4850 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4852 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4854 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4856 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4858 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4870 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4872 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4874 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4875 map_addr +=2; /*This means AYNC DATA IN */
4876 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4878 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4880 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4882 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4884 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4886 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4888 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4890 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4892 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4894 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4896 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4898 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4900 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4902 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4904 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4906 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4908 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4910 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4913 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4915 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4917 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4919 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4920 map_addr +=2; /* DIDN'T GET ONE */
4921 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4923 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4925 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4929 SGRAM_ACCESS(p_port);
4932 /*---------------------------------------------------------------------
4934 * Function: Auto Command Complete
4936 * Description: Post command back to host and find another command
4939 *---------------------------------------------------------------------*/
4941 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
4943 struct sccb * currSCCB;
4944 unsigned char status_byte;
4946 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4948 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4950 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4952 if (status_byte != SSGOOD) {
4954 if (status_byte == SSQ_FULL) {
4957 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4958 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4960 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4961 if(FPT_BL_Card[p_card].discQCount != 0)
4962 FPT_BL_Card[p_card].discQCount--;
4963 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
4967 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
4968 if(currSCCB->Sccb_tag)
4970 if(FPT_BL_Card[p_card].discQCount != 0)
4971 FPT_BL_Card[p_card].discQCount--;
4972 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4975 if(FPT_BL_Card[p_card].discQCount != 0)
4976 FPT_BL_Card[p_card].discQCount--;
4977 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
4981 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4983 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
4988 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4990 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4991 (unsigned char)SYNC_SUPPORTED;
4993 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4994 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4996 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4997 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4999 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5000 if(FPT_BL_Card[p_card].discQCount != 0)
5001 FPT_BL_Card[p_card].discQCount--;
5002 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5006 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5007 if(currSCCB->Sccb_tag)
5009 if(FPT_BL_Card[p_card].discQCount != 0)
5010 FPT_BL_Card[p_card].discQCount--;
5011 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5014 if(FPT_BL_Card[p_card].discQCount != 0)
5015 FPT_BL_Card[p_card].discQCount--;
5016 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5023 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5026 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5027 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
5028 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5030 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5031 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5033 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5034 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5036 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5037 if(FPT_BL_Card[p_card].discQCount != 0)
5038 FPT_BL_Card[p_card].discQCount--;
5039 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5043 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5044 if(currSCCB->Sccb_tag)
5046 if(FPT_BL_Card[p_card].discQCount != 0)
5047 FPT_BL_Card[p_card].discQCount--;
5048 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5051 if(FPT_BL_Card[p_card].discQCount != 0)
5052 FPT_BL_Card[p_card].discQCount--;
5053 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5060 if (status_byte == SSCHECK)
5062 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
5064 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
5066 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
5068 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
5070 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
5075 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5077 currSCCB->SccbStatus = SCCB_ERROR;
5078 currSCCB->TargetStatus = status_byte;
5080 if (status_byte == SSCHECK) {
5082 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5086 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5088 if (currSCCB->RequestSenseLength == 0)
5089 currSCCB->RequestSenseLength = 14;
5091 FPT_ssenss(&FPT_BL_Card[p_card]);
5092 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5094 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5095 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5097 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5098 if(FPT_BL_Card[p_card].discQCount != 0)
5099 FPT_BL_Card[p_card].discQCount--;
5100 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5104 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5105 if(currSCCB->Sccb_tag)
5107 if(FPT_BL_Card[p_card].discQCount != 0)
5108 FPT_BL_Card[p_card].discQCount--;
5109 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5112 if(FPT_BL_Card[p_card].discQCount != 0)
5113 FPT_BL_Card[p_card].discQCount--;
5114 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5124 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5125 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5126 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
5128 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5131 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
5134 #define SHORT_WAIT 0x0000000F
5135 #define LONG_WAIT 0x0000FFFFL
5138 /*---------------------------------------------------------------------
5140 * Function: Data Transfer Processor
5142 * Description: This routine performs two tasks.
5143 * (1) Start data transfer by calling HOST_DATA_XFER_START
5144 * function. Once data transfer is started, (2) Depends
5145 * on the type of data transfer mode Scatter/Gather mode
5146 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5147 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5148 * data transfer done. In Scatter/Gather mode, this routine
5149 * checks bus master command complete and dual rank busy
5150 * bit to keep chaining SC transfer command. Similarly,
5151 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5152 * (F_HOST_XFER_ACT bit) for data transfer done.
5154 *---------------------------------------------------------------------*/
5156 static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
5158 struct sccb * currSCCB;
5160 currSCCB = pCurrCard->currentSCCB;
5162 if (currSCCB->Sccb_XferState & F_SG_XFER)
5164 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5167 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
5168 currSCCB->Sccb_SGoffset = 0x00;
5170 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5172 FPT_busMstrSGDataXferStart(port, currSCCB);
5177 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5179 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5181 FPT_busMstrDataXferStart(port, currSCCB);
5187 /*---------------------------------------------------------------------
5189 * Function: BusMaster Scatter Gather Data Transfer Start
5193 *---------------------------------------------------------------------*/
5194 static void FPT_busMstrSGDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
5196 unsigned long count,addr,tmpSGCnt;
5197 unsigned int sg_index;
5198 unsigned char sg_count, i;
5199 unsigned long reg_offset;
5202 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5204 count = ((unsigned long) HOST_RD_CMD)<<24;
5208 count = ((unsigned long) HOST_WRT_CMD)<<24;
5213 sg_index = pcurrSCCB->Sccb_sgseg;
5214 reg_offset = hp_aramBase;
5217 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5220 WR_HARPOON(p_port+hp_page_ctrl, i);
5222 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
5223 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5225 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
5228 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
5231 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
5232 ((sg_index * 2) + 1));
5235 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5237 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5238 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5240 tmpSGCnt = count & 0x00FFFFFFL;
5243 WR_HARP32(p_port,reg_offset,addr);
5246 WR_HARP32(p_port,reg_offset,count);
5249 count &= 0xFF000000L;
5255 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5257 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5259 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5261 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5264 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5265 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5271 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5272 (tmpSGCnt & 0x000000001))
5275 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5280 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5282 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5283 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5287 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
5292 /*---------------------------------------------------------------------
5294 * Function: BusMaster Data Transfer Start
5298 *---------------------------------------------------------------------*/
5299 static void FPT_busMstrDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
5301 unsigned long addr,count;
5303 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5305 count = pcurrSCCB->Sccb_XferCnt;
5307 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5311 addr = pcurrSCCB->SensePointer;
5312 count = pcurrSCCB->RequestSenseLength;
5316 HP_SETUP_ADDR_CNT(p_port,addr,count);
5319 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5321 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5322 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5324 WR_HARPOON(p_port+hp_xfer_cmd,
5325 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5330 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5331 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5333 WR_HARPOON(p_port+hp_xfer_cmd,
5334 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5340 /*---------------------------------------------------------------------
5342 * Function: BusMaster Timeout Handler
5344 * Description: This function is called after a bus master command busy time
5345 * out is detected. This routines issue halt state machine
5346 * with a software time out for command busy. If command busy
5347 * is still asserted at the end of the time out, it issues
5348 * hard abort with another software time out. It hard abort
5349 * command busy is also time out, it'll just give up.
5351 *---------------------------------------------------------------------*/
5352 static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
5354 unsigned long timeout;
5356 timeout = LONG_WAIT;
5358 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5360 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5364 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5365 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5367 timeout = LONG_WAIT;
5368 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5371 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5373 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5383 /*---------------------------------------------------------------------
5385 * Function: Host Data Transfer Abort
5387 * Description: Abort any in progress transfer.
5389 *---------------------------------------------------------------------*/
5390 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
5393 unsigned long timeout;
5394 unsigned long remain_cnt;
5395 unsigned int sg_ptr;
5397 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5399 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5402 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5404 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5405 timeout = LONG_WAIT;
5407 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5409 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5411 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5413 if (FPT_busMstrTimeOut(port)) {
5415 if (pCurrSCCB->HostStatus == 0x00)
5417 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5421 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5423 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5425 if (pCurrSCCB->HostStatus == 0x00)
5428 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5434 else if (pCurrSCCB->Sccb_XferCnt) {
5436 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5439 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5442 WR_HARPOON(port+hp_sg_addr,0x00);
5444 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5446 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5448 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5451 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5453 while (remain_cnt < 0x01000000L) {
5457 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
5458 DataPointer) + (sg_ptr * 2)))) {
5460 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
5461 DataPointer) + (sg_ptr * 2)));
5472 if (remain_cnt < 0x01000000L) {
5475 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5477 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5480 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5481 && (remain_cnt == 0))
5483 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5489 if (pCurrSCCB->HostStatus == 0x00) {
5491 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5497 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5500 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5502 FPT_busMstrTimeOut(port);
5507 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5509 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5511 if (pCurrSCCB->HostStatus == 0x00) {
5513 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5524 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5526 timeout = SHORT_WAIT;
5528 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5529 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5533 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5535 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5538 timeout = LONG_WAIT;
5540 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5543 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5547 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5549 if (pCurrSCCB->HostStatus == 0x00) {
5551 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5554 FPT_busMstrTimeOut(port);
5558 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5560 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5562 if (pCurrSCCB->HostStatus == 0x00) {
5564 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5575 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5577 timeout = LONG_WAIT;
5579 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5581 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5583 if (pCurrSCCB->HostStatus == 0x00) {
5585 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5588 FPT_busMstrTimeOut(port);
5593 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5595 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5597 if (pCurrSCCB->HostStatus == 0x00) {
5599 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5605 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5607 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5610 WR_HARPOON(port+hp_sg_addr,0x00);
5612 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5614 pCurrSCCB->Sccb_SGoffset = 0x00;
5617 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5618 pCurrSCCB->DataLength) {
5620 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5622 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5629 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5631 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5635 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5640 /*---------------------------------------------------------------------
5642 * Function: Host Data Transfer Restart
5644 * Description: Reset the available count due to a restore data
5647 *---------------------------------------------------------------------*/
5648 static void FPT_hostDataXferRestart(struct sccb * currSCCB)
5650 unsigned long data_count;
5651 unsigned int sg_index;
5652 unsigned long *sg_ptr;
5654 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5656 currSCCB->Sccb_XferCnt = 0;
5658 sg_index = 0xffff; /*Index by long words into sg list. */
5659 data_count = 0; /*Running count of SG xfer counts. */
5661 sg_ptr = (unsigned long *)currSCCB->DataPointer;
5663 while (data_count < currSCCB->Sccb_ATC) {
5666 data_count += *(sg_ptr+(sg_index * 2));
5669 if (data_count == currSCCB->Sccb_ATC) {
5671 currSCCB->Sccb_SGoffset = 0;
5676 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5679 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5683 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5689 /*---------------------------------------------------------------------
5691 * Function: FPT_scini
5693 * Description: Setup all data structures necessary for SCAM selection.
5695 *---------------------------------------------------------------------*/
5697 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
5700 unsigned char loser,assigned_id;
5701 unsigned long p_port;
5703 unsigned char i,k,ScamFlg ;
5705 PNVRamInfo pCurrNvRam;
5707 currCard = &FPT_BL_Card[p_card];
5708 p_port = currCard->ioPort;
5709 pCurrNvRam = currCard->pNvRamInfo;
5713 ScamFlg = pCurrNvRam->niScamConf;
5714 i = pCurrNvRam->niSysConf;
5717 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5718 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
5720 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5723 FPT_inisci(p_card,p_port, p_our_id);
5725 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5726 too slow to return to SCAM selection */
5729 FPT_Wait1Second(p_port);
5731 FPT_Wait(p_port, TO_250ms); */
5733 FPT_Wait1Second(p_port);
5735 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5737 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5742 FPT_scxferc(p_port,SYNC_PTRN);
5743 FPT_scxferc(p_port,DOM_MSTR);
5744 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
5745 } while ( loser == 0xFF );
5749 if ((p_power_up) && (!loser))
5751 FPT_sresb(p_port,p_card);
5752 FPT_Wait(p_port, TO_250ms);
5754 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5759 FPT_scxferc(p_port, SYNC_PTRN);
5760 FPT_scxferc(p_port, DOM_MSTR);
5761 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
5763 } while ( loser == 0xFF );
5778 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5781 if (ScamFlg & SCAM_ENABLED)
5784 for (i=0; i < MAX_SCSI_TAR; i++)
5786 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5787 (FPT_scamInfo[i].state == ID_UNUSED))
5789 if (FPT_scsell(p_port,i))
5791 FPT_scamInfo[i].state = LEGACY;
5792 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5793 (FPT_scamInfo[i].id_string[1] != 0xFA))
5796 FPT_scamInfo[i].id_string[0] = 0xFF;
5797 FPT_scamInfo[i].id_string[1] = 0xFA;
5798 if(pCurrNvRam == NULL)
5799 currCard->globalFlags |= F_UPDATE_EEPROM;
5805 FPT_sresb(p_port,p_card);
5806 FPT_Wait1Second(p_port);
5807 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5809 FPT_scasid(p_card, p_port);
5814 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5816 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5818 FPT_scwtsel(p_port);
5821 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
5823 i = FPT_scxferc(p_port,0x00);
5826 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
5828 i = FPT_scxferc(p_port,0x00);
5831 k = FPT_scxferc(p_port,0x00);
5836 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
5837 FPT_inisci(p_card, p_port, p_our_id);
5838 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5839 FPT_scamInfo[currCard->ourId].id_string[0]
5847 else if (i == SET_P_FLAG)
5849 if (!(FPT_scsendi(p_port,
5850 &FPT_scamInfo[p_our_id].id_string[0])))
5851 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
5853 }while (!assigned_id);
5855 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
5858 if (ScamFlg & SCAM_ENABLED)
5861 if (currCard->globalFlags & F_UPDATE_EEPROM)
5863 FPT_scsavdi(p_card, p_port);
5864 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5870 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5872 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5873 (FPT_scamInfo[i].state == LEGACY))
5878 currCard->globalFlags |= F_SINGLE_DEVICE;
5880 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5885 /*---------------------------------------------------------------------
5887 * Function: FPT_scarb
5889 * Description: Gain control of the bus and wait SCAM select time (250ms)
5891 *---------------------------------------------------------------------*/
5893 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
5895 if (p_sel_type == INIT_SELTD)
5898 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5901 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
5904 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
5907 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5909 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5911 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5917 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5919 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5921 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5922 ~(SCSI_BSY | SCSI_SEL)));
5928 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5930 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5931 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5932 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
5933 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5935 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5937 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5940 FPT_Wait(p_port,TO_250ms);
5946 /*---------------------------------------------------------------------
5948 * Function: FPT_scbusf
5950 * Description: Release the SCSI bus and disable SCAM selection.
5952 *---------------------------------------------------------------------*/
5954 static void FPT_scbusf(unsigned long p_port)
5956 WR_HARPOON(p_port+hp_page_ctrl,
5957 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5960 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5962 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5965 WR_HARPOON(p_port+hp_scsisig, 0x00);
5968 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5971 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5974 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5976 WR_HARPOON(p_port+hp_page_ctrl,
5977 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5982 /*---------------------------------------------------------------------
5984 * Function: FPT_scasid
5986 * Description: Assign an ID to all the SCAM devices.
5988 *---------------------------------------------------------------------*/
5990 static void FPT_scasid(unsigned char p_card, unsigned long p_port)
5992 unsigned char temp_id_string[ID_STRING_LENGTH];
5994 unsigned char i,k,scam_id;
5995 unsigned char crcBytes[3];
5996 PNVRamInfo pCurrNvRam;
5997 unsigned short * pCrcBytes;
5999 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6006 for (k=0; k < ID_STRING_LENGTH; k++)
6008 temp_id_string[k] = (unsigned char) 0x00;
6011 FPT_scxferc(p_port,SYNC_PTRN);
6012 FPT_scxferc(p_port,ASSIGN_ID);
6014 if (!(FPT_sciso(p_port,&temp_id_string[0])))
6017 pCrcBytes = (unsigned short *)&crcBytes[0];
6018 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6019 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
6020 temp_id_string[1] = crcBytes[2];
6021 temp_id_string[2] = crcBytes[0];
6022 temp_id_string[3] = crcBytes[1];
6023 for(k = 4; k < ID_STRING_LENGTH; k++)
6024 temp_id_string[k] = (unsigned char) 0x00;
6026 i = FPT_scmachid(p_card,temp_id_string);
6028 if (i == CLR_PRIORITY)
6030 FPT_scxferc(p_port,MISC_CODE);
6031 FPT_scxferc(p_port,CLR_P_FLAG);
6032 i = 0; /*Not the last ID yet. */
6035 else if (i != NO_ID_AVAIL)
6038 FPT_scxferc(p_port,ID_0_7);
6040 FPT_scxferc(p_port,ID_8_F);
6042 scam_id = (i & (unsigned char) 0x07);
6045 for (k=1; k < 0x08; k <<= 1)
6047 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6049 FPT_scxferc(p_port,scam_id);
6051 i = 0; /*Not the last ID yet. */
6062 FPT_scxferc(p_port,SYNC_PTRN);
6063 FPT_scxferc(p_port,CFG_CMPLT);
6070 /*---------------------------------------------------------------------
6072 * Function: FPT_scsel
6074 * Description: Select all the SCAM devices.
6076 *---------------------------------------------------------------------*/
6078 static void FPT_scsel(unsigned long p_port)
6081 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6082 FPT_scwiros(p_port, SCSI_MSG);
6084 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6087 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6088 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6089 (unsigned char)(BIT(7)+BIT(6))));
6092 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6093 FPT_scwiros(p_port, SCSI_SEL);
6095 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6096 ~(unsigned char)BIT(6)));
6097 FPT_scwirod(p_port, BIT(6));
6099 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6104 /*---------------------------------------------------------------------
6106 * Function: FPT_scxferc
6108 * Description: Handshake the p_data (DB4-0) across the bus.
6110 *---------------------------------------------------------------------*/
6112 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
6114 unsigned char curr_data, ret_data;
6116 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6118 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6120 curr_data &= ~BIT(7);
6122 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6124 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
6125 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6127 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
6129 curr_data |= BIT(6);
6131 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6133 curr_data &= ~BIT(5);
6135 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6137 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
6139 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6140 curr_data |= BIT(7);
6142 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6144 curr_data &= ~BIT(6);
6146 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6148 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
6154 /*---------------------------------------------------------------------
6156 * Function: FPT_scsendi
6158 * Description: Transfer our Identification string to determine if we
6159 * will be the dominant master.
6161 *---------------------------------------------------------------------*/
6163 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
6165 unsigned char ret_data,byte_cnt,bit_cnt,defer;
6169 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6171 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6174 ret_data = FPT_scxferc(p_port,00);
6176 else if (p_id_string[byte_cnt] & bit_cnt)
6178 ret_data = FPT_scxferc(p_port,02);
6182 ret_data = FPT_scxferc(p_port,01);
6187 if ((ret_data & 0x1C) == 0x10)
6188 return(0x00); /*End of isolation stage, we won! */
6190 if (ret_data & 0x1C)
6193 if ((defer) && (!(ret_data & 0x1F)))
6194 return(0x01); /*End of isolation stage, we lost. */
6201 return(0x01); /*We lost */
6203 return(0); /*We WON! Yeeessss! */
6208 /*---------------------------------------------------------------------
6210 * Function: FPT_sciso
6212 * Description: Transfer the Identification string.
6214 *---------------------------------------------------------------------*/
6216 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
6218 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
6222 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6224 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6226 ret_data = FPT_scxferc(p_port,0);
6228 if (ret_data & 0xFC)
6234 if (ret_data & BIT(1)) {
6239 if ((ret_data & 0x1F) == 0)
6242 if(bit_cnt != 0 || bit_cnt != 8)
6246 FPT_scxferc(p_port, SYNC_PTRN);
6247 FPT_scxferc(p_port, ASSIGN_ID);
6259 p_id_string[byte_cnt] = the_data;
6268 /*---------------------------------------------------------------------
6270 * Function: FPT_scwirod
6272 * Description: Sample the SCSI data bus making sure the signal has been
6273 * deasserted for the correct number of consecutive samples.
6275 *---------------------------------------------------------------------*/
6277 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
6282 while ( i < MAX_SCSI_TAR ) {
6284 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6297 /*---------------------------------------------------------------------
6299 * Function: FPT_scwiros
6301 * Description: Sample the SCSI Signal lines making sure the signal has been
6302 * deasserted for the correct number of consecutive samples.
6304 *---------------------------------------------------------------------*/
6306 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
6311 while ( i < MAX_SCSI_TAR ) {
6313 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6325 /*---------------------------------------------------------------------
6327 * Function: FPT_scvalq
6329 * Description: Make sure we received a valid data byte.
6331 *---------------------------------------------------------------------*/
6333 static unsigned char FPT_scvalq(unsigned char p_quintet)
6335 unsigned char count;
6337 for (count=1; count < 0x08; count<<=1) {
6338 if (!(p_quintet & count))
6342 if (p_quintet & 0x18)
6350 /*---------------------------------------------------------------------
6352 * Function: FPT_scsell
6354 * Description: Select the specified device ID using a selection timeout
6355 * less than 4ms. If somebody responds then it is a legacy
6356 * drive and this ID must be marked as such.
6358 *---------------------------------------------------------------------*/
6360 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
6364 WR_HARPOON(p_port+hp_page_ctrl,
6365 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6367 ARAM_ACCESS(p_port);
6369 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6370 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6373 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6374 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6376 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6378 WRW_HARPOON((p_port+hp_intstat),
6379 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6381 WR_HARPOON(p_port+hp_select_id, targ_id);
6383 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6384 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6385 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6388 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6389 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6391 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6392 FPT_Wait(p_port, TO_250ms);
6394 DISABLE_AUTO(p_port);
6396 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6397 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6399 SGRAM_ACCESS(p_port);
6401 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6403 WRW_HARPOON((p_port+hp_intstat),
6404 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6406 WR_HARPOON(p_port+hp_page_ctrl,
6407 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6409 return(0); /*No legacy device */
6414 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6415 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6417 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6422 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6424 WR_HARPOON(p_port+hp_page_ctrl,
6425 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6427 return(1); /*Found one of them oldies! */
6431 /*---------------------------------------------------------------------
6433 * Function: FPT_scwtsel
6435 * Description: Wait to be selected by another SCAM initiator.
6437 *---------------------------------------------------------------------*/
6439 static void FPT_scwtsel(unsigned long p_port)
6441 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6445 /*---------------------------------------------------------------------
6447 * Function: FPT_inisci
6449 * Description: Setup the data Structure with the info from the EEPROM.
6451 *---------------------------------------------------------------------*/
6453 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
6455 unsigned char i,k,max_id;
6456 unsigned short ee_data;
6457 PNVRamInfo pCurrNvRam;
6459 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6461 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6468 for(i = 0; i < max_id; i++){
6470 for(k = 0; k < 4; k++)
6471 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
6472 for(k = 4; k < ID_STRING_LENGTH; k++)
6473 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
6475 if(FPT_scamInfo[i].id_string[0] == 0x00)
6476 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6478 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6482 for (i=0; i < max_id; i++)
6484 for (k=0; k < ID_STRING_LENGTH; k+=2)
6486 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6487 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6488 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
6490 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
6493 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6494 (FPT_scamInfo[i].id_string[0] == 0xFF))
6496 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6499 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6503 for(k = 0; k < ID_STRING_LENGTH; k++)
6504 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6508 /*---------------------------------------------------------------------
6510 * Function: FPT_scmachid
6512 * Description: Match the Device ID string with our values stored in
6515 *---------------------------------------------------------------------*/
6517 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
6520 unsigned char i,k,match;
6523 for (i=0; i < MAX_SCSI_TAR; i++) {
6527 for (k=0; k < ID_STRING_LENGTH; k++)
6529 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6535 FPT_scamInfo[i].state = ID_ASSIGNED;
6543 if (p_id_string[0] & BIT(5))
6548 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6549 match = p_id_string[1] & (unsigned char) 0x1F;
6557 if (FPT_scamInfo[match].state == ID_UNUSED)
6559 for (k=0; k < ID_STRING_LENGTH; k++)
6561 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6564 FPT_scamInfo[match].state = ID_ASSIGNED;
6566 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6567 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6577 if (p_id_string[0] & BIT(5))
6580 match = MAX_SCSI_TAR-1;
6586 if (p_id_string[0] & BIT(7))
6588 return(CLR_PRIORITY);
6592 if (p_id_string[0] & BIT(5))
6597 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6598 match = p_id_string[1] & (unsigned char) 0x1F;
6607 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
6609 for (k=0; k < ID_STRING_LENGTH; k++)
6611 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6614 FPT_scamInfo[match].id_string[0] |= BIT(7);
6615 FPT_scamInfo[match].state = ID_ASSIGNED;
6616 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6617 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6627 if (p_id_string[0] & BIT(5))
6630 match = MAX_SCSI_TAR-1;
6634 return(NO_ID_AVAIL);
6638 /*---------------------------------------------------------------------
6640 * Function: FPT_scsavdi
6642 * Description: Save off the device SCAM ID strings.
6644 *---------------------------------------------------------------------*/
6646 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
6648 unsigned char i,k,max_id;
6649 unsigned short ee_data,sum_data;
6654 for (i = 1; i < EE_SCAMBASE/2; i++)
6656 sum_data += FPT_utilEERead(p_port, i);
6660 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
6662 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6668 for (i=0; i < max_id; i++)
6671 for (k=0; k < ID_STRING_LENGTH; k+=2)
6673 ee_data = FPT_scamInfo[i].id_string[k+1];
6675 ee_data |= FPT_scamInfo[i].id_string[k];
6676 sum_data += ee_data;
6677 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6678 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6683 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6684 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
6687 /*---------------------------------------------------------------------
6689 * Function: FPT_XbowInit
6691 * Description: Setup the Xbow for normal operation.
6693 *---------------------------------------------------------------------*/
6695 static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
6699 i = RD_HARPOON(port+hp_page_ctrl);
6700 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
6702 WR_HARPOON(port+hp_scsireset,0x00);
6703 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6705 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6708 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6710 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6712 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6713 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6715 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6717 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6718 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6720 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6721 FPT_default_intena |= SCAM_SEL;
6723 WRW_HARPOON((port+hp_intena), FPT_default_intena);
6725 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6727 /* Turn on SCSI_MODE8 for narrow cards to fix the
6728 strapping issue with the DUAL CHANNEL card */
6729 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6730 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6732 WR_HARPOON(port+hp_page_ctrl, i);
6737 /*---------------------------------------------------------------------
6739 * Function: FPT_BusMasterInit
6741 * Description: Initialize the BusMaster for normal operations.
6743 *---------------------------------------------------------------------*/
6745 static void FPT_BusMasterInit(unsigned long p_port)
6749 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6750 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6752 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6755 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6757 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6760 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6761 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6762 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6767 /*---------------------------------------------------------------------
6769 * Function: FPT_DiagEEPROM
6771 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6774 *---------------------------------------------------------------------*/
6776 static void FPT_DiagEEPROM(unsigned long p_port)
6778 unsigned short index,temp,max_wd_cnt;
6780 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6781 max_wd_cnt = EEPROM_WD_CNT;
6783 max_wd_cnt = EEPROM_WD_CNT * 2;
6785 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
6787 if (temp == 0x4641) {
6789 for (index = 2; index < max_wd_cnt; index++) {
6791 temp += FPT_utilEERead(p_port, index);
6795 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
6797 return; /*EEPROM is Okay so return now! */
6802 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
6804 for (index = 0; index < max_wd_cnt; index++) {
6806 FPT_utilEEWrite(p_port, 0x0000, index);
6811 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
6813 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
6815 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
6817 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
6819 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
6821 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
6823 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
6825 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
6828 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
6830 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
6832 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
6835 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
6837 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
6839 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
6841 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
6843 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
6845 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
6847 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
6849 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
6853 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
6855 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
6857 FPT_utilEEWrite(p_port, 0x5068, 68/2);
6859 FPT_utilEEWrite(p_port, 0x696F, 70/2);
6861 FPT_utilEEWrite(p_port, 0x746E, 72/2);
6863 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
6865 FPT_utilEEWrite(p_port, 0x2054, 76/2);
6867 FPT_utilEEWrite(p_port, 0x2020, 78/2);
6870 index = ((EE_SCAMBASE/2)+(7*16));
6871 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
6872 temp += (0x0700+TYPE_CODE0);
6874 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6875 temp += 0x5542; /* BUSLOGIC */
6877 FPT_utilEEWrite(p_port, 0x4C53, index);
6880 FPT_utilEEWrite(p_port, 0x474F, index);
6883 FPT_utilEEWrite(p_port, 0x4349, index);
6886 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6887 temp += 0x5442; /* BT- 930 */
6889 FPT_utilEEWrite(p_port, 0x202D, index);
6892 FPT_utilEEWrite(p_port, 0x3339, index);
6894 index++; /*Serial # */
6895 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6898 FPT_utilEEWrite(p_port, 0x5453, index);
6901 FPT_utilEEWrite(p_port, 0x5645, index);
6904 FPT_utilEEWrite(p_port, 0x2045, index);
6907 FPT_utilEEWrite(p_port, 0x202F, index);
6910 FPT_utilEEWrite(p_port, 0x4F4A, index);
6913 FPT_utilEEWrite(p_port, 0x204E, index);
6916 FPT_utilEEWrite(p_port, 0x3539, index);
6921 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
6923 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
6928 /*---------------------------------------------------------------------
6930 * Function: Queue Search Select
6932 * Description: Try to find a new command to execute.
6934 *---------------------------------------------------------------------*/
6936 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
6938 unsigned char scan_ptr, lun;
6939 PSCCBMgr_tar_info currTar_Info;
6940 struct sccb * pOldSccb;
6942 scan_ptr = pCurrCard->scanIndex;
6945 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6946 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6947 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6949 if (currTar_Info->TarSelQ_Cnt != 0)
6953 if (scan_ptr == MAX_SCSI_TAR)
6956 for(lun=0; lun < MAX_LUN; lun++)
6958 if(currTar_Info->TarLUNBusy[lun] == 0)
6961 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6964 while((pCurrCard->currentSCCB != NULL) &&
6965 (lun != pCurrCard->currentSCCB->Lun))
6967 pOldSccb = pCurrCard->currentSCCB;
6968 pCurrCard->currentSCCB = (struct sccb *)(pCurrCard->currentSCCB)->
6971 if(pCurrCard->currentSCCB == NULL)
6973 if(pOldSccb != NULL)
6975 pOldSccb->Sccb_forwardlink = (struct sccb *)(pCurrCard->currentSCCB)->
6977 pOldSccb->Sccb_backlink = (struct sccb *)(pCurrCard->currentSCCB)->
6979 currTar_Info->TarSelQ_Cnt--;
6983 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6985 if (currTar_Info->TarSelQ_Head == NULL)
6987 currTar_Info->TarSelQ_Tail = NULL;
6988 currTar_Info->TarSelQ_Cnt = 0;
6992 currTar_Info->TarSelQ_Cnt--;
6993 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
6996 pCurrCard->scanIndex = scan_ptr;
6998 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7008 if (scan_ptr == MAX_SCSI_TAR) {
7016 if ((currTar_Info->TarSelQ_Cnt != 0) &&
7017 (currTar_Info->TarLUNBusy[0] == 0))
7020 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7022 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7024 if (currTar_Info->TarSelQ_Head == NULL)
7026 currTar_Info->TarSelQ_Tail = NULL;
7027 currTar_Info->TarSelQ_Cnt = 0;
7031 currTar_Info->TarSelQ_Cnt--;
7032 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
7036 if (scan_ptr == MAX_SCSI_TAR)
7039 pCurrCard->scanIndex = scan_ptr;
7041 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7049 if (scan_ptr == MAX_SCSI_TAR)
7055 } while (scan_ptr != pCurrCard->scanIndex);
7059 /*---------------------------------------------------------------------
7061 * Function: Queue Select Fail
7063 * Description: Add the current SCCB to the head of the Queue.
7065 *---------------------------------------------------------------------*/
7067 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
7069 unsigned char thisTarg;
7070 PSCCBMgr_tar_info currTar_Info;
7072 if (pCurrCard->currentSCCB != NULL)
7074 thisTarg = (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->TargID);
7075 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7077 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
7079 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7081 if (currTar_Info->TarSelQ_Cnt == 0)
7083 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7088 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7092 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7094 pCurrCard->currentSCCB = NULL;
7095 currTar_Info->TarSelQ_Cnt++;
7098 /*---------------------------------------------------------------------
7100 * Function: Queue Command Complete
7102 * Description: Call the callback function with the current SCCB.
7104 *---------------------------------------------------------------------*/
7106 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_sccb,
7107 unsigned char p_card)
7110 unsigned char i, SCSIcmd;
7111 CALL_BK_FN callback;
7112 PSCCBMgr_tar_info currTar_Info;
7114 SCSIcmd = p_sccb->Cdb[0];
7117 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7119 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7120 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7121 (p_sccb->TargetStatus != SSCHECK))
7123 if ((SCSIcmd == SCSI_READ) ||
7124 (SCSIcmd == SCSI_WRITE) ||
7125 (SCSIcmd == SCSI_READ_EXTENDED) ||
7126 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7127 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7128 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7129 (pCurrCard->globalFlags & F_NO_FILTER)
7131 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7135 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7137 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7138 p_sccb->SccbStatus = SCCB_ERROR;
7140 p_sccb->SccbStatus = SCCB_SUCCESS;
7143 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7145 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7146 for (i=0; i < 6; i++) {
7147 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7151 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7152 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7154 FPT_utilUpdateResidual(p_sccb);
7157 pCurrCard->cmdCounter--;
7158 if (!pCurrCard->cmdCounter) {
7160 if (pCurrCard->globalFlags & F_GREEN_PC) {
7161 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7162 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7165 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7166 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7170 if(pCurrCard->discQCount != 0)
7172 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7173 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7174 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7176 pCurrCard->discQCount--;
7177 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7181 if(p_sccb->Sccb_tag)
7183 pCurrCard->discQCount--;
7184 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7187 pCurrCard->discQCount--;
7188 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7194 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7196 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7197 pCurrCard->currentSCCB = NULL;
7201 /*---------------------------------------------------------------------
7203 * Function: Queue Disconnect
7205 * Description: Add SCCB to our disconnect array.
7207 *---------------------------------------------------------------------*/
7208 static void FPT_queueDisconnect(struct sccb * p_sccb, unsigned char p_card)
7210 PSCCBMgr_tar_info currTar_Info;
7212 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7214 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7215 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7217 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
7221 if (p_sccb->Sccb_tag)
7223 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7224 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7225 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7228 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
7231 FPT_BL_Card[p_card].currentSCCB = NULL;
7235 /*---------------------------------------------------------------------
7237 * Function: Queue Flush SCCB
7239 * Description: Flush all SCCB's back to the host driver for this target.
7241 *---------------------------------------------------------------------*/
7243 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
7245 unsigned char qtag,thisTarg;
7246 struct sccb * currSCCB;
7247 PSCCBMgr_tar_info currTar_Info;
7249 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7250 if(currSCCB != NULL)
7252 thisTarg = (unsigned char)currSCCB->TargID;
7253 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7255 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7257 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7258 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7261 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7263 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7265 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7266 currTar_Info->TarTagQ_Cnt--;
7274 /*---------------------------------------------------------------------
7276 * Function: Queue Flush Target SCCB
7278 * Description: Flush all SCCB's back to the host driver for this target.
7280 *---------------------------------------------------------------------*/
7282 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7283 unsigned char error_code)
7286 PSCCBMgr_tar_info currTar_Info;
7288 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7290 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7292 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7293 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7296 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7298 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7300 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7301 currTar_Info->TarTagQ_Cnt--;
7312 static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char p_card)
7314 PSCCBMgr_tar_info currTar_Info;
7315 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7317 p_SCCB->Sccb_forwardlink = NULL;
7319 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7321 if (currTar_Info->TarSelQ_Cnt == 0) {
7323 currTar_Info->TarSelQ_Head = p_SCCB;
7328 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7332 currTar_Info->TarSelQ_Tail = p_SCCB;
7333 currTar_Info->TarSelQ_Cnt++;
7337 /*---------------------------------------------------------------------
7339 * Function: Queue Find SCCB
7341 * Description: Search the target select Queue for this SCCB, and
7342 * remove it if found.
7344 *---------------------------------------------------------------------*/
7346 static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card)
7348 struct sccb * q_ptr;
7349 PSCCBMgr_tar_info currTar_Info;
7351 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7353 q_ptr = currTar_Info->TarSelQ_Head;
7355 while(q_ptr != NULL) {
7357 if (q_ptr == p_SCCB) {
7360 if (currTar_Info->TarSelQ_Head == q_ptr) {
7362 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7365 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7367 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7370 if (q_ptr->Sccb_forwardlink != NULL) {
7371 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7374 if (q_ptr->Sccb_backlink != NULL) {
7375 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7378 currTar_Info->TarSelQ_Cnt--;
7384 q_ptr = q_ptr->Sccb_forwardlink;
7394 /*---------------------------------------------------------------------
7396 * Function: Utility Update Residual Count
7398 * Description: Update the XferCnt to the remaining byte count.
7399 * If we transferred all the data then just write zero.
7400 * If Non-SG transfer then report Total Cnt - Actual Transfer
7401 * Cnt. For SG transfers add the count fields of all
7402 * remaining SG elements, as well as any partial remaining
7405 *---------------------------------------------------------------------*/
7407 static void FPT_utilUpdateResidual(struct sccb * p_SCCB)
7409 unsigned long partial_cnt;
7410 unsigned int sg_index;
7411 unsigned long *sg_ptr;
7413 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7415 p_SCCB->DataLength = 0x0000;
7418 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7420 partial_cnt = 0x0000;
7422 sg_index = p_SCCB->Sccb_sgseg;
7424 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
7426 if (p_SCCB->Sccb_SGoffset) {
7428 partial_cnt = p_SCCB->Sccb_SGoffset;
7432 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
7433 p_SCCB->DataLength ) {
7435 partial_cnt += *(sg_ptr+(sg_index * 2));
7439 p_SCCB->DataLength = partial_cnt;
7444 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7449 /*---------------------------------------------------------------------
7451 * Function: Wait 1 Second
7453 * Description: Wait for 1 second.
7455 *---------------------------------------------------------------------*/
7457 static void FPT_Wait1Second(unsigned long p_port)
7461 for(i=0; i < 4; i++) {
7463 FPT_Wait(p_port, TO_250ms);
7465 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7468 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7474 /*---------------------------------------------------------------------
7476 * Function: FPT_Wait
7478 * Description: Wait the desired delay.
7480 *---------------------------------------------------------------------*/
7482 static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
7484 unsigned char old_timer;
7485 unsigned char green_flag;
7487 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7489 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7490 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7492 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7493 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7494 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
7497 WR_HARPOON(p_port+hp_portctrl_0,
7498 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7500 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7502 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7505 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7509 WR_HARPOON(p_port+hp_portctrl_0,
7510 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7512 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7513 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
7515 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7517 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7521 /*---------------------------------------------------------------------
7523 * Function: Enable/Disable Write to EEPROM
7525 * Description: The EEPROM must first be enabled for writes
7526 * A total of 9 clocks are needed.
7528 *---------------------------------------------------------------------*/
7530 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
7532 unsigned char ee_value;
7534 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7538 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7543 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7545 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7546 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7550 /*---------------------------------------------------------------------
7552 * Function: Write EEPROM
7554 * Description: Write a word to the EEPROM at the specified
7557 *---------------------------------------------------------------------*/
7559 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
7562 unsigned char ee_value;
7565 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7570 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7573 ee_value |= (SEE_MS + SEE_CS);
7575 for(i = 0x8000; i != 0; i>>=1) {
7580 ee_value &= ~SEE_DO;
7582 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7583 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7584 ee_value |= SEE_CLK; /* Clock data! */
7585 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7586 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7587 ee_value &= ~SEE_CLK;
7588 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7589 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7591 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7592 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7594 FPT_Wait(p_port, TO_10ms);
7596 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7597 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7598 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7601 /*---------------------------------------------------------------------
7603 * Function: Read EEPROM
7605 * Description: Read a word from the EEPROM at the desired
7608 *---------------------------------------------------------------------*/
7610 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
7612 unsigned short i, ee_data1, ee_data2;
7615 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7618 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7620 if(ee_data1 == ee_data2)
7623 ee_data1 = ee_data2;
7631 /*---------------------------------------------------------------------
7633 * Function: Read EEPROM Original
7635 * Description: Read a word from the EEPROM at the desired
7638 *---------------------------------------------------------------------*/
7640 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
7643 unsigned char ee_value;
7644 unsigned short i, ee_data;
7646 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7650 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7653 ee_value |= (SEE_MS + SEE_CS);
7656 for(i = 1; i <= 16; i++) {
7658 ee_value |= SEE_CLK; /* Clock data! */
7659 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7660 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7661 ee_value &= ~SEE_CLK;
7662 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7663 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7667 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7671 ee_value &= ~(SEE_MS + SEE_CS);
7672 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7673 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7679 /*---------------------------------------------------------------------
7681 * Function: Send EE command and Address to the EEPROM
7683 * Description: Transfers the correct command and sends the address
7686 *---------------------------------------------------------------------*/
7688 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
7690 unsigned char ee_value;
7691 unsigned char narrow_flg;
7696 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7700 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7702 ee_value |= SEE_CS; /* Set CS to EEPROM */
7703 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7706 for(i = 0x04; i != 0; i>>=1) {
7711 ee_value &= ~SEE_DO;
7713 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7714 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7715 ee_value |= SEE_CLK; /* Clock data! */
7716 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7717 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7718 ee_value &= ~SEE_CLK;
7719 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7720 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7736 ee_value &= ~SEE_DO;
7738 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7739 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7740 ee_value |= SEE_CLK; /* Clock data! */
7741 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7742 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7743 ee_value &= ~SEE_CLK;
7744 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7745 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7751 static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7753 unsigned short crc=0;
7756 for (i=0; i < ID_STRING_LENGTH; i++)
7758 ch = (unsigned short) buffer[i];
7759 for(j=0; j < 8; j++)
7762 crc = (crc >> 1) ^ CRCMASK;
7771 static unsigned char FPT_CalcLrc(unsigned char buffer[])
7776 for(i = 0; i < ID_STRING_LENGTH; i++)
7784 The following inline definitions avoid type conflicts.
7787 static inline unsigned char
7788 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7790 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
7794 static inline FlashPoint_CardHandle_T
7795 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7797 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
7801 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7803 FlashPoint_ReleaseHostAdapter(CardHandle);
7808 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7810 FlashPoint_StartCCB(CardHandle, (struct sccb *) CCB);
7815 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7817 FlashPoint_AbortCCB(CardHandle, (struct sccb *) CCB);
7821 static inline boolean
7822 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7824 return FlashPoint_InterruptPending(CardHandle);
7829 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7831 return FlashPoint_HandleInterrupt(CardHandle);
7835 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7836 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7837 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7838 #define FlashPoint_StartCCB FlashPoint__StartCCB
7839 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7840 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7841 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7844 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7848 Define prototypes for the FlashPoint SCCB Manager Functions.
7851 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7852 extern FlashPoint_CardHandle_T
7853 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7854 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7855 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7856 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7857 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7858 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7861 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */