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 u08bits unsigned s08bits
52 #define u16bits unsigned s16bits
53 #define u32bits unsigned s32bits
57 #define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
58 #define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
63 typedef struct _SCCB *PSCCB;
64 typedef void (*CALL_BK_FN)(PSCCB);
67 typedef struct SCCBMgr_info {
68 unsigned long si_baseaddr;
69 unsigned char si_present;
70 unsigned char si_intvect;
73 unsigned short si_fw_revision;
74 unsigned short si_per_targ_init_sync;
75 unsigned short si_per_targ_fast_nego;
76 unsigned short si_per_targ_ultra_nego;
77 unsigned short si_per_targ_no_disc;
78 unsigned short si_per_targ_wide_nego;
79 unsigned short si_flags;
80 unsigned char si_card_family;
81 unsigned char si_bustype;
82 unsigned char si_card_model[3];
83 unsigned char si_relative_cardnum;
84 unsigned char si_reserved[4];
85 unsigned long si_OS_reserved;
86 unsigned char si_XlatInfo[4];
87 unsigned long si_reserved2[5];
88 unsigned long si_secondary_range;
91 typedef SCCBMGR_INFO * PSCCBMGR_INFO;
94 #define SCSI_PARITY_ENA 0x0001
95 #define LOW_BYTE_TERM 0x0010
96 #define HIGH_BYTE_TERM 0x0020
97 #define BUSTYPE_PCI 0x3
99 #define SUPPORT_16TAR_32LUN 0x0002
100 #define SOFT_RESET 0x0004
101 #define EXTENDED_TRANSLATION 0x0008
102 #define POST_ALL_UNDERRRUNS 0x0040
103 #define FLAG_SCAM_ENABLED 0x0080
104 #define FLAG_SCAM_LEVEL2 0x0100
109 #define HARPOON_FAMILY 0x02
113 /* SCCB struct used for both SCCB and UCB manager compiles!
114 * The UCB Manager treats the SCCB as it's 'native hardware structure'
119 typedef struct _SCCB {
120 unsigned char OperationCode;
121 unsigned char ControlByte;
122 unsigned char CdbLength;
123 unsigned char RequestSenseLength;
124 unsigned long DataLength;
125 unsigned long DataPointer;
126 unsigned char CcbRes[2];
127 unsigned char HostStatus;
128 unsigned char TargetStatus;
129 unsigned char TargID;
131 unsigned char Cdb[12];
132 unsigned char CcbRes1;
133 unsigned char Reserved1;
134 unsigned long Reserved2;
135 unsigned long SensePointer;
138 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
139 unsigned long SccbIOPort; /* Identifies board base port */
140 unsigned char SccbStatus;
141 unsigned char SCCBRes2;
142 unsigned short SccbOSFlags;
145 unsigned long Sccb_XferCnt; /* actual transfer count */
146 unsigned long Sccb_ATC;
147 unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */
148 unsigned long Sccb_res1;
149 unsigned short Sccb_MGRFlags;
150 unsigned short Sccb_sgseg;
151 unsigned char Sccb_scsimsg; /* identify msg for selection */
152 unsigned char Sccb_tag;
153 unsigned char Sccb_scsistat;
154 unsigned char Sccb_idmsg; /* image of last msg in */
155 PSCCB Sccb_forwardlink;
157 unsigned long Sccb_savedATC;
158 unsigned char Save_Cdb[6];
159 unsigned char Save_CdbLen;
160 unsigned char Sccb_XferState;
161 unsigned long Sccb_SGoffset;
169 #define SCATTER_GATHER_COMMAND 0x02
170 #define RESIDUAL_COMMAND 0x03
171 #define RESIDUAL_SG_COMMAND 0x04
172 #define RESET_COMMAND 0x81
175 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
176 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
177 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
178 #define SCCB_DATA_XFER_IN 0x08 /* Read */
181 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
184 #define BUS_FREE_ST 0
186 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
187 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
188 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
189 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
191 #define DATA_OUT_ST 7
193 #define DISCONNECT_ST 9
197 #define F_HOST_XFER_DIR 0x01
198 #define F_ALL_XFERRED 0x02
199 #define F_SG_XFER 0x04
200 #define F_AUTO_SENSE 0x08
201 #define F_ODD_BALL_CNT 0x10
202 #define F_NO_DATA_YET 0x80
205 #define F_STATUSLOADED 0x01
206 #define F_DEV_SELECTED 0x04
209 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
210 #define SCCB_DATA_UNDER_RUN 0x0C
211 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
212 #define SCCB_DATA_OVER_RUN 0x12
213 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
215 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
216 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
217 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
223 #define SCCB_IN_PROCESS 0x00
224 #define SCCB_SUCCESS 0x01
225 #define SCCB_ABORT 0x02
226 #define SCCB_ERROR 0x04
230 #define ORION_FW_REV 3110
234 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
236 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
239 #define MAX_SCSI_TAR 16
241 #define LUN_MASK 0x1f
243 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
245 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
248 #define RD_HARPOON(ioport) inb((u32bits)ioport)
249 #define RDW_HARPOON(ioport) inw((u32bits)ioport)
250 #define RD_HARP32(ioport,offset,data) (data = inl((u32bits)(ioport + offset)))
251 #define WR_HARPOON(ioport,val) outb((u08bits) val, (u32bits)ioport)
252 #define WRW_HARPOON(ioport,val) outw((u16bits)val, (u32bits)ioport)
253 #define WR_HARP32(ioport,offset,data) outl(data, (u32bits)(ioport + offset))
256 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
257 #define SYNC_TRYING BIT(6)
258 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
260 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
261 #define WIDE_ENABLED BIT(4)
262 #define WIDE_NEGOCIATED BIT(5)
264 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
265 #define TAG_Q_TRYING BIT(2)
266 #define TAG_Q_REJECT BIT(3)
268 #define TAR_ALLOW_DISC BIT(0)
271 #define EE_SYNC_MASK (BIT(0)+BIT(1))
272 #define EE_SYNC_5MB BIT(0)
273 #define EE_SYNC_10MB BIT(1)
274 #define EE_SYNC_20MB (BIT(0)+BIT(1))
276 #define EE_WIDE_SCSI BIT(7)
279 typedef struct SCCBMgr_tar_info *PSCCBMgr_tar_info;
282 typedef struct SCCBMgr_tar_info {
286 unsigned char TarLUN_CA; /*Contingent Allgiance */
287 unsigned char TarTagQ_Cnt;
288 unsigned char TarSelQ_Cnt;
289 unsigned char TarStatus;
290 unsigned char TarEEValue;
291 unsigned char TarSyncCtrl;
292 unsigned char TarReserved[2]; /* for alignment */
293 unsigned char LunDiscQ_Idx[MAX_LUN];
294 unsigned char TarLUNBusy[MAX_LUN];
297 typedef struct NVRAMInfo {
298 unsigned char niModel; /* Model No. of card */
299 unsigned char niCardNo; /* Card no. */
300 unsigned long niBaseAddr; /* Port Address of card */
301 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
302 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
303 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
304 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
305 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
306 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
309 typedef NVRAMINFO *PNVRamInfo;
317 typedef struct SCCBcard {
319 PSCCBMGR_INFO cardInfo;
321 unsigned long ioPort;
323 unsigned short cmdCounter;
324 unsigned char discQCount;
325 unsigned char tagQ_Lst;
326 unsigned char cardIndex;
327 unsigned char scanIndex;
328 unsigned char globalFlags;
330 PNVRamInfo pNvRamInfo;
331 PSCCB discQ_Tbl[QUEUE_DEPTH];
335 typedef struct SCCBcard *PSCCBcard;
338 #define F_TAG_STARTED 0x01
339 #define F_CONLUN_IO 0x02
340 #define F_DO_RENEGO 0x04
341 #define F_NO_FILTER 0x08
342 #define F_GREEN_PC 0x10
343 #define F_HOST_XFER_ACT 0x20
344 #define F_NEW_SCCB_CMD 0x40
345 #define F_UPDATE_EEPROM 0x80
348 #define ID_STRING_LENGTH 32
349 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
352 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
354 #define ASSIGN_ID 0x00
355 #define SET_P_FLAG 0x01
356 #define CFG_CMPLT 0x03
357 #define DOM_MSTR 0x0F
358 #define SYNC_PTRN 0x1F
362 #define MISC_CODE 0x14
363 #define CLR_P_FLAG 0x18
367 #define INIT_SELTD 0x01
368 #define LEVEL2_TAR 0x02
371 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
372 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
373 CLR_PRIORITY,NO_ID_AVAIL };
375 typedef struct SCCBscam_info {
377 unsigned char id_string[ID_STRING_LENGTH];
378 enum scam_id_st state;
383 #define SCSI_REQUEST_SENSE 0x03
384 #define SCSI_READ 0x08
385 #define SCSI_WRITE 0x0A
386 #define SCSI_START_STOP_UNIT 0x1B
387 #define SCSI_READ_EXTENDED 0x28
388 #define SCSI_WRITE_EXTENDED 0x2A
389 #define SCSI_WRITE_AND_VERIFY 0x2E
395 #define SSQ_FULL 0x28
400 #define SMCMD_COMP 0x00
402 #define SMSAVE_DATA_PTR 0x02
403 #define SMREST_DATA_PTR 0x03
406 #define SMREJECT 0x07
408 #define SMPARITY 0x09
409 #define SMDEV_RESET 0x0C
410 #define SMABORT_TAG 0x0D
411 #define SMINIT_RECOVERY 0x0F
412 #define SMREL_RECOVERY 0x10
415 #define DISC_PRIV 0x40
422 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
431 #define SIX_BYTE_CMD 0x06
432 #define TWELVE_BYTE_CMD 0x0C
435 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
438 #define EEPROM_WD_CNT 256
440 #define EEPROM_CHECK_SUM 0
441 #define FW_SIGNATURE 2
442 #define MODEL_NUMB_0 4
443 #define MODEL_NUMB_2 6
444 #define MODEL_NUMB_4 8
445 #define SYSTEM_CONFIG 16
446 #define SCSI_CONFIG 17
447 #define BIOS_CONFIG 18
448 #define SCAM_CONFIG 20
449 #define ADAPTER_SCSI_ID 24
452 #define IGNORE_B_SCAN 32
453 #define SEND_START_ENA 34
454 #define DEVICE_ENABLE 36
456 #define SYNC_RATE_TBL 38
457 #define SYNC_RATE_TBL01 38
458 #define SYNC_RATE_TBL23 40
459 #define SYNC_RATE_TBL45 42
460 #define SYNC_RATE_TBL67 44
461 #define SYNC_RATE_TBL89 46
462 #define SYNC_RATE_TBLab 48
463 #define SYNC_RATE_TBLcd 50
464 #define SYNC_RATE_TBLef 52
468 #define EE_SCAMBASE 256
472 #define SCAM_ENABLED BIT(2)
473 #define SCAM_LEVEL2 BIT(3)
476 #define RENEGO_ENA BITW(10)
477 #define CONNIO_ENA BITW(11)
478 #define GREEN_PC_ENA BITW(12)
481 #define AUTO_RATE_00 00
482 #define AUTO_RATE_05 01
483 #define AUTO_RATE_10 02
484 #define AUTO_RATE_20 03
486 #define WIDE_NEGO_BIT BIT(7)
487 #define DISC_ENABLE_BIT BIT(6)
491 #define hp_vendor_id_0 0x00 /* LSB */
492 #define ORION_VEND_0 0x4B
494 #define hp_vendor_id_1 0x01 /* MSB */
495 #define ORION_VEND_1 0x10
497 #define hp_device_id_0 0x02 /* LSB */
498 #define ORION_DEV_0 0x30
500 #define hp_device_id_1 0x03 /* MSB */
501 #define ORION_DEV_1 0x81
503 /* Sub Vendor ID and Sub Device ID only available in
504 Harpoon Version 2 and higher */
506 #define hp_sub_device_id_0 0x06 /* LSB */
510 #define hp_semaphore 0x0C
511 #define SCCB_MGR_ACTIVE BIT(0)
512 #define TICKLE_ME BIT(1)
513 #define SCCB_MGR_PRESENT BIT(3)
514 #define BIOS_IN_USE BIT(4)
518 #define hp_sys_ctrl 0x0F
520 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
521 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
522 #define HALT_MACH BIT(3) /*Halt State Machine */
523 #define HARD_ABORT BIT(4) /*Hard Abort */
533 #define hp_host_blk_cnt 0x13
535 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
537 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
541 #define hp_int_mask 0x17
543 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
544 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
547 #define hp_xfer_cnt_lo 0x18
548 #define hp_xfer_cnt_hi 0x1A
549 #define hp_xfer_cmd 0x1B
551 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
552 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
555 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
557 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
559 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
561 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
562 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
564 #define hp_host_addr_lo 0x1C
565 #define hp_host_addr_hmi 0x1E
567 #define hp_ee_ctrl 0x22
569 #define EXT_ARB_ACK BIT(7)
570 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
571 #define SEE_MS BIT(5)
572 #define SEE_CS BIT(3)
573 #define SEE_CLK BIT(2)
574 #define SEE_DO BIT(1)
575 #define SEE_DI BIT(0)
578 #define EE_WRITE 0x05
580 #define EWEN_ADDR 0x03C0
582 #define EWDS_ADDR 0x0000
590 #define hp_bm_ctrl 0x26
592 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
593 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
594 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
595 #define FAST_SINGLE BIT(6) /*?? */
597 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
600 #define hp_sg_addr 0x28
601 #define hp_page_ctrl 0x29
603 #define SCATTER_EN BIT(0)
604 #define SGRAM_ARAM BIT(1)
605 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
606 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
611 #define hp_pci_stat_cfg 0x2D
613 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
622 #define hp_rev_num 0x33
625 #define hp_stack_data 0x34
626 #define hp_stack_addr 0x35
628 #define hp_ext_status 0x36
630 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
631 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
632 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
633 #define CMD_ABORTED BIT(4) /*Command aborted */
634 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
635 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
636 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
637 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
638 BM_PARITY_ERR | PIO_OVERRUN)
640 #define hp_int_status 0x37
642 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
643 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
644 #define INT_ASSERTED BIT(5) /* */
647 #define hp_fifo_cnt 0x38
652 #define hp_intena 0x40
654 #define RESET BITW(7)
655 #define PROG_HLT BITW(6)
656 #define PARITY BITW(5)
659 #define SCAM_SEL BITW(2)
661 #define TIMEOUT BITW(0)
662 #define BUS_FREE BITW(15)
663 #define XFER_CNT_0 BITW(14)
664 #define PHASE BITW(13)
665 #define IUNKWN BITW(12)
666 #define ICMD_COMP BITW(11)
667 #define ITICKLE BITW(10)
668 #define IDO_STRT BITW(9)
669 #define ITAR_DISC BITW(8)
670 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
671 #define CLR_ALL_INT 0xFFFF
672 #define CLR_ALL_INT_1 0xFF00
674 #define hp_intstat 0x42
676 #define hp_scsisig 0x44
678 #define SCSI_SEL BIT(7)
679 #define SCSI_BSY BIT(6)
680 #define SCSI_REQ BIT(5)
681 #define SCSI_ACK BIT(4)
682 #define SCSI_ATN BIT(3)
683 #define SCSI_CD BIT(2)
684 #define SCSI_MSG BIT(1)
685 #define SCSI_IOBIT BIT(0)
687 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
688 #define S_MSGO_PH (BIT(2)+BIT(1) )
689 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
690 #define S_DATAI_PH ( BIT(0))
691 #define S_DATAO_PH 0x00
692 #define S_ILL_PH ( BIT(1) )
694 #define hp_scsictrl_0 0x45
696 #define SEL_TAR BIT(6)
697 #define ENA_ATN BIT(4)
698 #define ENA_RESEL BIT(2)
699 #define SCSI_RST BIT(1)
700 #define ENA_SCAM_SEL BIT(0)
704 #define hp_portctrl_0 0x46
706 #define SCSI_PORT BIT(7)
707 #define SCSI_INBIT BIT(6)
708 #define DMA_PORT BIT(5)
709 #define DMA_RD BIT(4)
710 #define HOST_PORT BIT(3)
711 #define HOST_WRT BIT(2)
712 #define SCSI_BUS_EN BIT(1)
713 #define START_TO BIT(0)
715 #define hp_scsireset 0x47
717 #define SCSI_INI BIT(6)
718 #define SCAM_EN BIT(5)
719 #define DMA_RESET BIT(3)
720 #define HPSCSI_RESET BIT(2)
721 #define PROG_RESET BIT(1)
722 #define FIFO_CLR BIT(0)
724 #define hp_xfercnt_0 0x48
725 #define hp_xfercnt_2 0x4A
727 #define hp_fifodata_0 0x4C
728 #define hp_addstat 0x4E
730 #define SCAM_TIMER BIT(7)
731 #define SCSI_MODE8 BIT(3)
732 #define SCSI_PAR_ERR BIT(0)
734 #define hp_prgmcnt_0 0x4F
737 #define hp_selfid_0 0x50
738 #define hp_selfid_1 0x51
739 #define hp_arb_id 0x52
742 #define hp_select_id 0x53
745 #define hp_synctarg_base 0x54
746 #define hp_synctarg_12 0x54
747 #define hp_synctarg_13 0x55
748 #define hp_synctarg_14 0x56
749 #define hp_synctarg_15 0x57
751 #define hp_synctarg_8 0x58
752 #define hp_synctarg_9 0x59
753 #define hp_synctarg_10 0x5A
754 #define hp_synctarg_11 0x5B
756 #define hp_synctarg_4 0x5C
757 #define hp_synctarg_5 0x5D
758 #define hp_synctarg_6 0x5E
759 #define hp_synctarg_7 0x5F
761 #define hp_synctarg_0 0x60
762 #define hp_synctarg_1 0x61
763 #define hp_synctarg_2 0x62
764 #define hp_synctarg_3 0x63
766 #define NARROW_SCSI BIT(4)
767 #define DEFAULT_OFFSET 0x0F
769 #define hp_autostart_0 0x64
770 #define hp_autostart_1 0x65
771 #define hp_autostart_3 0x67
775 #define AUTO_IMMED BIT(5)
776 #define SELECT BIT(6)
777 #define END_DATA (BIT(7)+BIT(6))
779 #define hp_gp_reg_0 0x68
780 #define hp_gp_reg_1 0x69
781 #define hp_gp_reg_3 0x6B
783 #define hp_seltimeout 0x6C
786 #define TO_4ms 0x67 /* 3.9959ms */
788 #define TO_5ms 0x03 /* 4.9152ms */
789 #define TO_10ms 0x07 /* 11.xxxms */
790 #define TO_250ms 0x99 /* 250.68ms */
791 #define TO_290ms 0xB1 /* 289.99ms */
793 #define hp_clkctrl_0 0x6D
795 #define PWR_DWN BIT(6)
796 #define ACTdeassert BIT(4)
797 #define CLK_40MHZ (BIT(1) + BIT(0))
799 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
801 #define hp_fiforead 0x6E
802 #define hp_fifowrite 0x6F
804 #define hp_offsetctr 0x70
805 #define hp_xferstat 0x71
807 #define FIFO_EMPTY BIT(6)
809 #define hp_portctrl_1 0x72
811 #define CHK_SCSI_P BIT(3)
812 #define HOST_MODE8 BIT(0)
814 #define hp_xfer_pad 0x73
816 #define ID_UNLOCK BIT(3)
818 #define hp_scsidata_0 0x74
819 #define hp_scsidata_1 0x75
823 #define hp_aramBase 0x80
824 #define BIOS_DATA_OFFSET 0x60
825 #define BIOS_RELATIVE_CARD 0x64
830 #define AR3 (BITW(9) + BITW(8))
831 #define SDATA BITW(10)
834 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
836 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
840 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
842 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
845 #define ADATA_OUT 0x00
846 #define ADATA_IN BITW(8)
847 #define ACOMMAND BITW(10)
848 #define ASTATUS (BITW(10)+BITW(8))
849 #define AMSG_OUT (BITW(10)+BITW(9))
850 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
853 #define BRH_OP BITW(13) /* Branch */
857 #define EQUAL BITW(8)
858 #define NOT_EQ BITW(9)
860 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
863 #define FIFO_0 BITW(10)
866 #define MPM_OP BITW(15) /* Match phase and move data */
869 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
872 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
877 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
887 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
889 #define SSI_OP (BITW(15)+BITW(11))
892 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
893 #define SSI_IDO_STRT (IDO_STRT >> 8)
895 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
896 #define SSI_ITICKLE (ITICKLE >> 8)
898 #define SSI_IUNKWN (IUNKWN >> 8)
899 #define SSI_INO_CC (IUNKWN >> 8)
900 #define SSI_IRFAIL (IUNKWN >> 8)
903 #define NP 0x10 /*Next Phase */
904 #define NTCMD 0x02 /*Non- Tagged Command start */
905 #define CMDPZ 0x04 /*Command phase */
906 #define DINT 0x12 /*Data Out/In interrupt */
907 #define DI 0x13 /*Data Out */
908 #define DC 0x19 /*Disconnect Message */
909 #define ST 0x1D /*Status Phase */
910 #define UNKNWN 0x24 /*Unknown bus action */
911 #define CC 0x25 /*Command Completion failure */
912 #define TICK 0x26 /*New target reselected us. */
913 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
916 #define ID_MSG_STRT hp_aramBase + 0x00
917 #define NON_TAG_ID_MSG hp_aramBase + 0x06
918 #define CMD_STRT hp_aramBase + 0x08
919 #define SYNC_MSGS hp_aramBase + 0x08
925 #define TAG_STRT 0x00
926 #define DISCONNECT_START 0x10/2
927 #define END_DATA_START 0x14/2
928 #define CMD_ONLY_STRT CMDPZ/2
929 #define SELCHK_STRT SELCHK/2
939 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
940 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
942 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
944 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
946 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
947 WR_HARP32(port,hp_xfercnt_0,count),\
948 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
950 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
952 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
953 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
956 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
957 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
961 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
962 WR_HARPOON(port+hp_scsireset, 0x00))
964 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
965 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
967 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
968 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
970 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
971 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
973 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
974 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
979 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
980 static void FPT_ssel(unsigned long port, unsigned char p_card);
981 static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
982 static void FPT_shandem(unsigned long port, unsigned char p_card,PSCCB pCurrSCCB);
983 static void FPT_stsyncn(unsigned long port, unsigned char p_card);
984 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
985 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
986 PSCCBMgr_tar_info currTar_Info);
987 static void FPT_sresb(unsigned long port, unsigned char p_card);
988 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
989 static void FPT_schkdd(unsigned long port, unsigned char p_card);
990 static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
991 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
992 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
994 static void FPT_SendMsg(unsigned long port, unsigned char message);
995 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
996 unsigned char error_code);
998 static void FPT_sinits(PSCCB p_sccb, unsigned char p_card);
999 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo);
1001 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
1002 static void FPT_stwidn(unsigned long port, unsigned char p_card);
1003 static void FPT_siwidr(unsigned long port, unsigned char width);
1006 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
1007 static void FPT_queueDisconnect(PSCCB p_SCCB, unsigned char p_card);
1008 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_SCCB,
1009 unsigned char p_card);
1010 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1011 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1012 static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char card);
1013 static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card);
1014 static void FPT_utilUpdateResidual(PSCCB p_SCCB);
1015 static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
1016 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
1019 static void FPT_Wait1Second(unsigned long p_port);
1020 static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1021 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1022 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1023 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1024 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1025 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
1029 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1030 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1031 static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1032 static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1033 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1034 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1035 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
1037 static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1038 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1039 static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
1044 static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1045 static void FPT_BusMasterInit(unsigned long p_port);
1046 static void FPT_DiagEEPROM(unsigned long p_port);
1051 static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
1052 static void FPT_busMstrSGDataXferStart(unsigned long port, PSCCB pCurrSCCB);
1053 static void FPT_busMstrDataXferStart(unsigned long port, PSCCB pCurrSCCB);
1054 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB);
1055 static void FPT_hostDataXferRestart(PSCCB currSCCB);
1058 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
1059 PSCCBcard pCurrCard, unsigned short p_int);
1061 static void FPT_SccbMgrTableInitAll(void);
1062 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1063 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
1067 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
1069 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1070 static void FPT_scbusf(unsigned long p_port);
1071 static void FPT_scsel(unsigned long p_port);
1072 static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1073 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1074 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1075 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1076 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1077 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
1078 static unsigned char FPT_scvalq(unsigned char p_quintet);
1079 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1080 static void FPT_scwtsel(unsigned long p_port);
1081 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1082 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
1083 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
1086 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1087 static void FPT_autoLoadDefaultMap(unsigned long p_port);
1092 static SCCBMGR_TAR_INFO FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1093 static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1094 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1095 static NVRAMINFO FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1098 static unsigned char FPT_mbCards = 0;
1099 static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1100 ' ', 'B', 'T', '-', '9', '3', '0', \
1101 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1102 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1104 static unsigned short FPT_default_intena = 0;
1107 static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
1110 /*---------------------------------------------------------------------
1112 * Function: FlashPoint_ProbeHostAdapter
1114 * Description: Setup and/or Search for cards and return info to caller.
1116 *---------------------------------------------------------------------*/
1118 static int FlashPoint_ProbeHostAdapter(PSCCBMGR_INFO pCardInfo)
1120 static unsigned char first_time = 1;
1122 unsigned char i,j,id,ScamFlg;
1123 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
1124 unsigned long ioport;
1125 PNVRamInfo pCurrNvRam;
1127 ioport = pCardInfo->si_baseaddr;
1130 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1131 return((int)FAILURE);
1133 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1134 return((int)FAILURE);
1136 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1137 return((int)FAILURE);
1139 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1140 return((int)FAILURE);
1143 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1145 /* For new Harpoon then check for sub_device ID LSB
1146 the bits(0-3) must be all ZERO for compatible with
1147 current version of SCCBMgr, else skip this Harpoon
1150 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1151 return((int)FAILURE);
1156 FPT_SccbMgrTableInitAll();
1161 if(FPT_RdStack(ioport, 0) != 0x00) {
1162 if(FPT_ChkIfChipInitialized(ioport) == 0)
1165 WR_HARPOON(ioport+hp_semaphore, 0x00);
1166 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1167 FPT_DiagEEPROM(ioport);
1171 if(FPT_mbCards < MAX_MB_CARDS) {
1172 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1174 pCurrNvRam->niBaseAddr = ioport;
1175 FPT_RNVRamData(pCurrNvRam);
1177 return((int) FAILURE);
1182 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1183 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1186 pCardInfo->si_id = pCurrNvRam->niAdapId;
1188 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1189 (unsigned char)0x0FF);
1191 pCardInfo->si_lun = 0x00;
1192 pCardInfo->si_fw_revision = ORION_FW_REV;
1199 for (id = 0; id < (16/2); id++) {
1202 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1203 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1204 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1206 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1208 for (i = 0; i < 2; temp >>=8,i++) {
1217 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1218 temp6 |= 0x8000; /* Fall through */
1219 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1220 temp5 |= 0x8000; /* Fall through */
1221 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1222 temp2 |= 0x8000; /* Fall through */
1223 case AUTO_RATE_00: /* Asynchronous */
1227 if (temp & DISC_ENABLE_BIT)
1230 if (temp & WIDE_NEGO_BIT)
1236 pCardInfo->si_per_targ_init_sync = temp2;
1237 pCardInfo->si_per_targ_no_disc = temp3;
1238 pCardInfo->si_per_targ_wide_nego = temp4;
1239 pCardInfo->si_per_targ_fast_nego = temp5;
1240 pCardInfo->si_per_targ_ultra_nego = temp6;
1243 i = pCurrNvRam->niSysConf;
1245 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1248 ScamFlg = pCurrNvRam->niScamConf;
1250 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1252 pCardInfo->si_flags = 0x0000;
1255 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1258 pCardInfo->si_flags |= SOFT_RESET;
1261 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1263 if (ScamFlg & SCAM_ENABLED)
1264 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1266 if (ScamFlg & SCAM_LEVEL2)
1267 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1269 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1271 j |= SCSI_TERM_ENA_L;
1273 WR_HARPOON(ioport+hp_bm_ctrl, j );
1275 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1277 j |= SCSI_TERM_ENA_H;
1279 WR_HARPOON(ioport+hp_ee_ctrl, j );
1281 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1283 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1285 pCardInfo->si_card_family = HARPOON_FAMILY;
1286 pCardInfo->si_bustype = BUSTYPE_PCI;
1289 pCardInfo->si_card_model[0] = '9';
1290 switch(pCurrNvRam->niModel & 0x0f){
1292 pCardInfo->si_card_model[1] = '3';
1293 pCardInfo->si_card_model[2] = '0';
1296 pCardInfo->si_card_model[1] = '5';
1297 pCardInfo->si_card_model[2] = '0';
1300 pCardInfo->si_card_model[1] = '3';
1301 pCardInfo->si_card_model[2] = '2';
1304 pCardInfo->si_card_model[1] = '5';
1305 pCardInfo->si_card_model[2] = '2';
1309 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1310 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1311 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1313 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1314 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1317 if (pCardInfo->si_card_model[1] == '3')
1319 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1320 pCardInfo->si_flags |= LOW_BYTE_TERM;
1322 else if (pCardInfo->si_card_model[2] == '0')
1324 temp = RD_HARPOON(ioport+hp_xfer_pad);
1325 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1326 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1327 pCardInfo->si_flags |= LOW_BYTE_TERM;
1328 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1329 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1330 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1331 WR_HARPOON(ioport+hp_xfer_pad, temp);
1335 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1336 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1337 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1338 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1340 for (i = 0; i < 8; i++)
1343 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1345 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1346 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1348 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1349 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1350 if (!(temp3 & BIT(7)))
1351 pCardInfo->si_flags |= LOW_BYTE_TERM;
1352 if (!(temp3 & BIT(6)))
1353 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1357 ARAM_ACCESS(ioport);
1359 for ( i = 0; i < 4; i++ ) {
1361 pCardInfo->si_XlatInfo[i] =
1362 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1365 /* return with -1 if no sort, else return with
1366 logical card number sorted by BIOS (zero-based) */
1368 pCardInfo->si_relative_cardnum =
1369 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1371 SGRAM_ACCESS(ioport);
1373 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1374 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1375 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1376 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1377 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1378 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1379 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1380 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1382 pCardInfo->si_present = 0x01;
1388 /*---------------------------------------------------------------------
1390 * Function: FlashPoint_HardwareResetHostAdapter
1392 * Description: Setup adapter for normal operation (hard reset).
1394 *---------------------------------------------------------------------*/
1396 static unsigned long FlashPoint_HardwareResetHostAdapter(PSCCBMGR_INFO pCardInfo)
1398 PSCCBcard CurrCard = NULL;
1399 PNVRamInfo pCurrNvRam;
1400 unsigned char i,j,thisCard, ScamFlg;
1401 unsigned short temp,sync_bit_map,id;
1402 unsigned long ioport;
1404 ioport = pCardInfo->si_baseaddr;
1406 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1408 if (thisCard == MAX_CARDS) {
1413 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1415 CurrCard = &FPT_BL_Card[thisCard];
1416 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1420 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1422 FPT_BL_Card[thisCard].ioPort = ioport;
1423 CurrCard = &FPT_BL_Card[thisCard];
1426 for(i = 0; i < FPT_mbCards; i++){
1427 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1428 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1430 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1431 CurrCard->cardIndex = thisCard;
1432 CurrCard->cardInfo = pCardInfo;
1438 pCurrNvRam = CurrCard->pNvRamInfo;
1441 ScamFlg = pCurrNvRam->niScamConf;
1444 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1448 FPT_BusMasterInit(ioport);
1449 FPT_XbowInit(ioport, ScamFlg);
1451 FPT_autoLoadDefaultMap(ioport);
1454 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1456 WR_HARPOON(ioport+hp_selfid_0, id);
1457 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1458 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1459 CurrCard->ourId = pCardInfo->si_id;
1461 i = (unsigned char) pCardInfo->si_flags;
1462 if (i & SCSI_PARITY_ENA)
1463 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1465 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1466 if (i & LOW_BYTE_TERM)
1467 j |= SCSI_TERM_ENA_L;
1468 WR_HARPOON(ioport+hp_bm_ctrl, j);
1470 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1471 if (i & HIGH_BYTE_TERM)
1472 j |= SCSI_TERM_ENA_H;
1473 WR_HARPOON(ioport+hp_ee_ctrl, j );
1476 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1478 FPT_sresb(ioport,thisCard);
1480 FPT_scini(thisCard, pCardInfo->si_id, 0);
1485 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1486 CurrCard->globalFlags |= F_NO_FILTER;
1489 if(pCurrNvRam->niSysConf & 0x10)
1490 CurrCard->globalFlags |= F_GREEN_PC;
1493 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1494 CurrCard->globalFlags |= F_GREEN_PC;
1497 /* Set global flag to indicate Re-Negotiation to be done on all
1500 if(pCurrNvRam->niScsiConf & 0x04)
1501 CurrCard->globalFlags |= F_DO_RENEGO;
1504 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1505 CurrCard->globalFlags |= F_DO_RENEGO;
1509 if(pCurrNvRam->niScsiConf & 0x08)
1510 CurrCard->globalFlags |= F_CONLUN_IO;
1513 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1514 CurrCard->globalFlags |= F_CONLUN_IO;
1518 temp = pCardInfo->si_per_targ_no_disc;
1520 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1523 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1526 sync_bit_map = 0x0001;
1528 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1531 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1532 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1533 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1535 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1537 for (i = 0; i < 2; temp >>=8,i++) {
1539 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1541 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
1545 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1546 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1547 (unsigned char)(temp & ~EE_SYNC_MASK);
1550 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1553 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1555 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1559 else { /* NARROW SCSI */
1560 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1571 WR_HARPOON((ioport+hp_semaphore),
1572 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1574 return((unsigned long)CurrCard);
1577 static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
1580 unsigned long portBase;
1581 unsigned long regOffset;
1582 unsigned long scamData;
1583 unsigned long *pScamTbl;
1584 PNVRamInfo pCurrNvRam;
1586 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1589 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1590 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1591 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1592 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1593 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1595 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1596 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
1598 portBase = pCurrNvRam->niBaseAddr;
1600 for(i = 0; i < MAX_SCSI_TAR; i++){
1601 regOffset = hp_aramBase + 64 + i*4;
1602 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
1603 scamData = *pScamTbl;
1604 WR_HARP32(portBase, regOffset, scamData);
1608 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1613 static void FPT_RNVRamData(PNVRamInfo pNvRamInfo)
1616 unsigned long portBase;
1617 unsigned long regOffset;
1618 unsigned long scamData;
1619 unsigned long *pScamTbl;
1621 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1622 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1623 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1624 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1625 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1627 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1628 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
1630 portBase = pNvRamInfo->niBaseAddr;
1632 for(i = 0; i < MAX_SCSI_TAR; i++){
1633 regOffset = hp_aramBase + 64 + i*4;
1634 RD_HARP32(portBase, regOffset, scamData);
1635 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
1636 *pScamTbl = scamData;
1641 static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
1643 WR_HARPOON(portBase + hp_stack_addr, index);
1644 return(RD_HARPOON(portBase + hp_stack_data));
1647 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
1649 WR_HARPOON(portBase + hp_stack_addr, index);
1650 WR_HARPOON(portBase + hp_stack_data, data);
1654 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
1656 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1658 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1661 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1662 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1667 /*---------------------------------------------------------------------
1669 * Function: FlashPoint_StartCCB
1671 * Description: Start a command pointed to by p_Sccb. When the
1672 * command is completed it will be returned via the
1673 * callback function.
1675 *---------------------------------------------------------------------*/
1676 static void FlashPoint_StartCCB(unsigned long pCurrCard, PSCCB p_Sccb)
1678 unsigned long ioport;
1679 unsigned char thisCard, lun;
1681 CALL_BK_FN callback;
1683 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1684 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1686 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1689 p_Sccb->HostStatus = SCCB_COMPLETE;
1690 p_Sccb->SccbStatus = SCCB_ERROR;
1691 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1698 FPT_sinits(p_Sccb,thisCard);
1701 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1703 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1704 | SCCB_MGR_ACTIVE));
1706 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1708 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1709 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1713 ((PSCCBcard)pCurrCard)->cmdCounter++;
1715 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1717 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1719 if(p_Sccb->OperationCode == RESET_COMMAND)
1721 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1722 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1723 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1724 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1728 FPT_queueAddSccb(p_Sccb,thisCard);
1732 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1734 if(p_Sccb->OperationCode == RESET_COMMAND)
1736 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1737 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1738 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1739 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1743 FPT_queueAddSccb(p_Sccb,thisCard);
1749 MDISABLE_INT(ioport);
1751 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
1752 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1756 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
1757 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1758 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1761 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1762 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1767 if(p_Sccb->OperationCode == RESET_COMMAND)
1769 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1770 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1771 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1772 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1776 FPT_queueAddSccb(p_Sccb,thisCard);
1781 MENABLE_INT(ioport);
1787 /*---------------------------------------------------------------------
1789 * Function: FlashPoint_AbortCCB
1791 * Description: Abort the command pointed to by p_Sccb. When the
1792 * command is completed it will be returned via the
1793 * callback function.
1795 *---------------------------------------------------------------------*/
1796 static int FlashPoint_AbortCCB(unsigned long pCurrCard, PSCCB p_Sccb)
1798 unsigned long ioport;
1800 unsigned char thisCard;
1801 CALL_BK_FN callback;
1804 PSCCBMgr_tar_info currTar_Info;
1807 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1809 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1811 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1814 if (FPT_queueFindSccb(p_Sccb,thisCard))
1817 ((PSCCBcard)pCurrCard)->cmdCounter--;
1819 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1820 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1821 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1823 p_Sccb->SccbStatus = SCCB_ABORT;
1824 callback = p_Sccb->SccbCallback;
1832 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1834 p_Sccb->SccbStatus = SCCB_ABORT;
1842 TID = p_Sccb->TargID;
1845 if(p_Sccb->Sccb_tag)
1847 MDISABLE_INT(ioport);
1848 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1850 p_Sccb->SccbStatus = SCCB_ABORT;
1851 p_Sccb->Sccb_scsistat = ABORT_ST;
1852 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1854 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1856 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1857 FPT_ssel(ioport, thisCard);
1861 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1862 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1863 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1864 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1867 MENABLE_INT(ioport);
1872 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1874 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1877 p_Sccb->SccbStatus = SCCB_ABORT;
1888 /*---------------------------------------------------------------------
1890 * Function: FlashPoint_InterruptPending
1892 * Description: Do a quick check to determine if there is a pending
1893 * interrupt for this card and disable the IRQ Pin if so.
1895 *---------------------------------------------------------------------*/
1896 static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
1898 unsigned long ioport;
1900 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1902 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1914 /*---------------------------------------------------------------------
1916 * Function: FlashPoint_HandleInterrupt
1918 * Description: This is our entry point when an interrupt is generated
1919 * by the card and the upper level driver passes it on to
1922 *---------------------------------------------------------------------*/
1923 static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
1926 unsigned char thisCard,result,bm_status, bm_int_st;
1927 unsigned short hp_int;
1928 unsigned char i, target;
1929 unsigned long ioport;
1931 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1932 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1934 MDISABLE_INT(ioport);
1936 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1937 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
1941 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1943 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1947 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1949 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1950 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1951 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1956 MENABLE_INT(ioport);
1962 else if (hp_int & ICMD_COMP) {
1964 if ( !(hp_int & BUS_FREE) ) {
1965 /* Wait for the BusFree before starting a new command. We
1966 must also check for being reselected since the BusFree
1967 may not show up if another device reselects us in 1.5us or
1968 less. SRR Wednesday, 3/8/1995.
1970 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1973 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1975 FPT_phaseChkFifo(ioport, thisCard);
1977 /* WRW_HARPOON((ioport+hp_intstat),
1978 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1981 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1983 FPT_autoCmdCmplt(ioport,thisCard);
1988 else if (hp_int & ITAR_DISC)
1991 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1993 FPT_phaseChkFifo(ioport, thisCard);
1997 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1999 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2000 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2002 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2005 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2006 FPT_queueDisconnect(currSCCB,thisCard);
2008 /* Wait for the BusFree before starting a new command. We
2009 must also check for being reselected since the BusFree
2010 may not show up if another device reselects us in 1.5us or
2011 less. SRR Wednesday, 3/8/1995.
2013 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2014 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2015 RD_HARPOON((ioport+hp_scsisig)) ==
2016 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2019 The additional loop exit condition above detects a timing problem
2020 with the revision D/E harpoon chips. The caller should reset the
2021 host adapter to recover when 0xFE is returned.
2023 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2025 MENABLE_INT(ioport);
2029 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2032 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2037 else if (hp_int & RSEL) {
2039 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2041 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2043 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2045 FPT_phaseChkFifo(ioport, thisCard);
2048 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2050 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2051 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2052 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2055 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2056 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2057 FPT_queueDisconnect(currSCCB,thisCard);
2060 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2061 FPT_phaseDecode(ioport,thisCard);
2066 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2069 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2070 FPT_phaseDecode(ioport,thisCard);
2075 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2077 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2078 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
2080 FPT_phaseDecode(ioport,thisCard);
2084 /* Harpoon problem some SCSI target device respond to selection
2085 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2086 to latch the correct Target ID into reg. x53.
2087 The work around require to correct this reg. But when write to this
2088 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2089 need to read this reg first then restore it later. After update to 0x53 */
2091 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2092 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2093 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2094 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2095 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
2096 WR_HARPOON(ioport+hp_fifowrite, i);
2097 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2101 else if (hp_int & XFER_CNT_0) {
2103 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2105 FPT_schkdd(ioport,thisCard);
2110 else if (hp_int & BUS_FREE) {
2112 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2114 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2116 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
2119 FPT_phaseBusFree(ioport,thisCard);
2123 else if (hp_int & ITICKLE) {
2125 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2126 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2131 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2134 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2137 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2139 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
2142 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2143 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2144 FPT_ssel(ioport,thisCard);
2153 MENABLE_INT(ioport);
2158 /*---------------------------------------------------------------------
2160 * Function: Sccb_bad_isr
2162 * Description: Some type of interrupt has occurred which is slightly
2163 * out of the ordinary. We will now decode it fully, in
2164 * this routine. This is broken up in an attempt to save
2167 *---------------------------------------------------------------------*/
2168 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
2169 PSCCBcard pCurrCard, unsigned short p_int)
2171 unsigned char temp, ScamFlg;
2172 PSCCBMgr_tar_info currTar_Info;
2173 PNVRamInfo pCurrNvRam;
2176 if (RD_HARPOON(p_port+hp_ext_status) &
2177 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2180 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2183 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2186 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2189 WR_HARPOON(p_port+hp_pci_stat_cfg,
2190 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2192 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2196 if (pCurrCard->currentSCCB != NULL)
2199 if (!pCurrCard->currentSCCB->HostStatus)
2200 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2202 FPT_sxfrp(p_port,p_card);
2204 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
2205 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2206 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
2207 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2209 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2211 FPT_phaseDecode(p_port,p_card);
2217 else if (p_int & RESET)
2220 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2221 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2222 if (pCurrCard->currentSCCB != NULL) {
2224 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2226 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2230 DISABLE_AUTO(p_port);
2232 FPT_sresb(p_port,p_card);
2234 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2236 pCurrNvRam = pCurrCard->pNvRamInfo;
2238 ScamFlg = pCurrNvRam->niScamConf;
2241 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
2244 FPT_XbowInit(p_port, ScamFlg);
2246 FPT_scini(p_card, pCurrCard->ourId, 0);
2252 else if (p_int & FIFO) {
2254 WRW_HARPOON((p_port+hp_intstat), FIFO);
2256 if (pCurrCard->currentSCCB != NULL)
2257 FPT_sxfrp(p_port,p_card);
2260 else if (p_int & TIMEOUT)
2263 DISABLE_AUTO(p_port);
2265 WRW_HARPOON((p_port+hp_intstat),
2266 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2268 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2271 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2272 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2273 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2274 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
2276 currTar_Info->TarLUNBusy[0] = 0;
2279 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2281 currTar_Info->TarSyncCtrl = 0;
2282 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2285 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2287 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2290 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
2292 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2296 else if (p_int & SCAM_SEL)
2299 FPT_scarb(p_port,LEVEL2_TAR);
2301 FPT_scasid(p_card, p_port);
2305 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2312 /*---------------------------------------------------------------------
2314 * Function: SccbMgrTableInit
2316 * Description: Initialize all Sccb manager data structures.
2318 *---------------------------------------------------------------------*/
2320 static void FPT_SccbMgrTableInitAll()
2322 unsigned char thisCard;
2324 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2326 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
2328 FPT_BL_Card[thisCard].ioPort = 0x00;
2329 FPT_BL_Card[thisCard].cardInfo = NULL;
2330 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2331 FPT_BL_Card[thisCard].ourId = 0x00;
2332 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2337 /*---------------------------------------------------------------------
2339 * Function: SccbMgrTableInit
2341 * Description: Initialize all Sccb manager data structures.
2343 *---------------------------------------------------------------------*/
2345 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
2347 unsigned char scsiID, qtag;
2349 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2351 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2354 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2356 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2357 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2358 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2361 pCurrCard->scanIndex = 0x00;
2362 pCurrCard->currentSCCB = NULL;
2363 pCurrCard->globalFlags = 0x00;
2364 pCurrCard->cmdCounter = 0x00;
2365 pCurrCard->tagQ_Lst = 0x01;
2366 pCurrCard->discQCount = 0;
2372 /*---------------------------------------------------------------------
2374 * Function: SccbMgrTableInit
2376 * Description: Initialize all Sccb manager data structures.
2378 *---------------------------------------------------------------------*/
2380 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
2383 unsigned char lun, qtag;
2384 PSCCBMgr_tar_info currTar_Info;
2386 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2388 currTar_Info->TarSelQ_Cnt = 0;
2389 currTar_Info->TarSyncCtrl = 0;
2391 currTar_Info->TarSelQ_Head = NULL;
2392 currTar_Info->TarSelQ_Tail = NULL;
2393 currTar_Info->TarTagQ_Cnt = 0;
2394 currTar_Info->TarLUN_CA = 0;
2397 for (lun = 0; lun < MAX_LUN; lun++)
2399 currTar_Info->TarLUNBusy[lun] = 0;
2400 currTar_Info->LunDiscQ_Idx[lun] = 0;
2403 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2405 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
2407 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
2409 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2410 FPT_BL_Card[p_card].discQCount--;
2417 /*---------------------------------------------------------------------
2421 * Description: Read in a message byte from the SCSI bus, and check
2422 * for a parity error.
2424 *---------------------------------------------------------------------*/
2426 static unsigned char FPT_sfm(unsigned long port, PSCCB pCurrSCCB)
2428 unsigned char message;
2429 unsigned short TimeOutLoop;
2432 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2433 (TimeOutLoop++ < 20000) ){}
2436 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2438 message = RD_HARPOON(port+hp_scsidata_0);
2440 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2443 if (TimeOutLoop > 20000)
2444 message = 0x00; /* force message byte = 0 if Time Out on Req */
2446 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2447 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2449 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2450 WR_HARPOON(port+hp_xferstat, 0);
2451 WR_HARPOON(port+hp_fiforead, 0);
2452 WR_HARPOON(port+hp_fifowrite, 0);
2453 if (pCurrSCCB != NULL)
2455 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2460 ACCEPT_MSG_ATN(port);
2462 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2463 (TimeOutLoop++ < 20000) ){}
2464 if (TimeOutLoop > 20000)
2466 WRW_HARPOON((port+hp_intstat), PARITY);
2469 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2471 WRW_HARPOON((port+hp_intstat), PARITY);
2474 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2476 RD_HARPOON(port+hp_scsidata_0);
2478 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2483 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2484 WR_HARPOON(port+hp_xferstat, 0);
2485 WR_HARPOON(port+hp_fiforead, 0);
2486 WR_HARPOON(port+hp_fifowrite, 0);
2491 /*---------------------------------------------------------------------
2493 * Function: FPT_ssel
2495 * Description: Load up automation and select target device.
2497 *---------------------------------------------------------------------*/
2499 static void FPT_ssel(unsigned long port, unsigned char p_card)
2502 unsigned char auto_loaded, i, target, *theCCB;
2504 unsigned long cdb_reg;
2507 PSCCBMgr_tar_info currTar_Info;
2508 unsigned char lastTag, lun;
2510 CurrCard = &FPT_BL_Card[p_card];
2511 currSCCB = CurrCard->currentSCCB;
2512 target = currSCCB->TargID;
2513 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2514 lastTag = CurrCard->tagQ_Lst;
2519 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2520 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2522 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2523 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2525 lun = currSCCB->Lun;
2530 if (CurrCard->globalFlags & F_TAG_STARTED)
2532 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2534 if ((currTar_Info->TarLUN_CA == 0)
2535 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2539 if (currTar_Info->TarTagQ_Cnt !=0)
2541 currTar_Info->TarLUNBusy[lun] = 1;
2542 FPT_queueSelectFail(CurrCard,p_card);
2548 currTar_Info->TarLUNBusy[lun] = 1;
2551 } /*End non-tagged */
2554 currTar_Info->TarLUNBusy[lun] = 1;
2557 } /*!Use cmd Q Tagged */
2560 if (currTar_Info->TarLUN_CA == 1)
2562 FPT_queueSelectFail(CurrCard,p_card);
2567 currTar_Info->TarLUNBusy[lun] = 1;
2569 } /*else use cmd Q tagged */
2571 } /*if glob tagged started */
2574 currTar_Info->TarLUNBusy[lun] = 1;
2579 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2580 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2581 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2583 if(CurrCard->discQCount >= QUEUE_DEPTH)
2585 currTar_Info->TarLUNBusy[lun] = 1;
2586 FPT_queueSelectFail(CurrCard,p_card);
2590 for (i = 1; i < QUEUE_DEPTH; i++)
2592 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2593 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2595 CurrCard->tagQ_Lst = lastTag;
2596 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2597 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2598 CurrCard->discQCount++;
2602 if(i == QUEUE_DEPTH)
2604 currTar_Info->TarLUNBusy[lun] = 1;
2605 FPT_queueSelectFail(CurrCard,p_card);
2615 WR_HARPOON(port+hp_select_id, target);
2616 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2618 if (currSCCB->OperationCode == RESET_COMMAND) {
2619 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2620 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2622 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2624 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2626 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2628 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2630 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2632 currTar_Info->TarSyncCtrl = 0;
2633 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2636 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2638 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2641 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2642 FPT_SccbMgrTableInitTarget(p_card, target);
2646 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2648 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2649 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2651 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2653 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2654 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2655 >> 6) | (unsigned char)0x20)));
2656 WRW_HARPOON((port+SYNC_MSGS+2),
2657 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2658 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2660 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2665 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2666 auto_loaded = FPT_siwidn(port,p_card);
2667 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2670 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2671 == SYNC_SUPPORTED)) {
2672 auto_loaded = FPT_sisyncn(port,p_card, 0);
2673 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2680 if (currSCCB->ControlByte & F_USE_CMD_Q)
2683 CurrCard->globalFlags |= F_TAG_STARTED;
2685 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2688 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2690 /* Fix up the start instruction with a jump to
2691 Non-Tag-CMD handling */
2692 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2694 WRW_HARPOON((port+NON_TAG_ID_MSG),
2695 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2697 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2699 /* Setup our STATE so we know what happend when
2700 the wheels fall off. */
2701 currSCCB->Sccb_scsistat = SELECT_ST;
2703 currTar_Info->TarLUNBusy[lun] = 1;
2708 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2710 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2711 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2712 >> 6) | (unsigned char)0x20)));
2714 for (i = 1; i < QUEUE_DEPTH; i++)
2716 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2717 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2719 WRW_HARPOON((port+ID_MSG_STRT+6),
2720 (MPM_OP+AMSG_OUT+lastTag));
2721 CurrCard->tagQ_Lst = lastTag;
2722 currSCCB->Sccb_tag = lastTag;
2723 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2724 CurrCard->discQCount++;
2730 if ( i == QUEUE_DEPTH )
2732 currTar_Info->TarLUNBusy[lun] = 1;
2733 FPT_queueSelectFail(CurrCard,p_card);
2738 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2740 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2747 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2749 WRW_HARPOON((port+NON_TAG_ID_MSG),
2750 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2752 currSCCB->Sccb_scsistat = SELECT_ST;
2754 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2758 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2760 cdb_reg = port + CMD_STRT;
2762 for (i=0; i < currSCCB->CdbLength; i++)
2764 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2769 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2770 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2774 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2775 WR_HARPOON(port+hp_xferstat, 0x00);
2777 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2779 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2782 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2784 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2789 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2790 auto_loaded |= AUTO_IMMED; */
2791 auto_loaded = AUTO_IMMED;
2795 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2802 /*---------------------------------------------------------------------
2804 * Function: FPT_sres
2806 * Description: Hookup the correct CCB and handle the incoming messages.
2808 *---------------------------------------------------------------------*/
2810 static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
2813 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2816 PSCCBMgr_tar_info currTar_Info;
2822 if(pCurrCard->currentSCCB != NULL)
2824 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2828 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2831 currSCCB = pCurrCard->currentSCCB;
2832 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2834 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2835 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2837 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2839 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2840 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2842 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2843 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2845 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2846 if(currSCCB->Sccb_scsistat != ABORT_ST)
2848 pCurrCard->discQCount--;
2849 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2855 currTar_Info->TarLUNBusy[0] = 0;
2856 if(currSCCB->Sccb_tag)
2858 if(currSCCB->Sccb_scsistat != ABORT_ST)
2860 pCurrCard->discQCount--;
2861 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2865 if(currSCCB->Sccb_scsistat != ABORT_ST)
2867 pCurrCard->discQCount--;
2868 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2873 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
2876 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2879 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
2880 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2887 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2891 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2893 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2896 WRW_HARPOON((port+hp_intstat), PHASE);
2901 WRW_HARPOON((port+hp_intstat), PHASE);
2902 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2905 message = FPT_sfm(port,pCurrCard->currentSCCB);
2909 if (message <= (0x80 | LUN_MASK))
2911 lun = message & (unsigned char)LUN_MASK;
2913 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2915 if (currTar_Info->TarTagQ_Cnt != 0)
2918 if (!(currTar_Info->TarLUN_CA))
2920 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2923 message = FPT_sfm(port,pCurrCard->currentSCCB);
2934 tag = FPT_sfm(port,pCurrCard->currentSCCB);
2942 } /*End Q cnt != 0 */
2944 } /*End Tag cmds supported! */
2946 } /*End valid ID message. */
2951 ACCEPT_MSG_ATN(port);
2954 } /* End good id message. */
2964 ACCEPT_MSG_ATN(port);
2966 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2967 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2968 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2976 if(msgRetryCount == 1)
2978 FPT_SendMsg(port, SMPARITY);
2982 FPT_SendMsg(port, SMDEV_RESET);
2984 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
2986 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
2989 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
2993 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
2996 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
3000 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
3001 FPT_SccbMgrTableInitTarget(p_card,our_target);
3005 }while(message == 0);
3009 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3010 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3012 currTar_Info->TarLUNBusy[lun] = 1;
3013 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3014 if(pCurrCard->currentSCCB != NULL)
3020 ACCEPT_MSG_ATN(port);
3025 currTar_Info->TarLUNBusy[0] = 1;
3030 if (pCurrCard->discQ_Tbl[tag] != NULL)
3032 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3033 currTar_Info->TarTagQ_Cnt--;
3038 ACCEPT_MSG_ATN(port);
3042 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3043 if(pCurrCard->currentSCCB != NULL)
3049 ACCEPT_MSG_ATN(port);
3054 if(pCurrCard->currentSCCB != NULL)
3056 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3058 /* During Abort Tag command, the target could have got re-selected
3059 and completed the command. Check the select Q and remove the CCB
3060 if it is in the Select Q */
3061 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
3066 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3067 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3068 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3071 static void FPT_SendMsg(unsigned long port, unsigned char message)
3073 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3075 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3078 WRW_HARPOON((port+hp_intstat), PHASE);
3083 WRW_HARPOON((port+hp_intstat), PHASE);
3084 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3086 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3089 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3091 WR_HARPOON(port+hp_scsidata_0,message);
3093 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3097 WR_HARPOON(port+hp_portctrl_0, 0x00);
3099 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3100 (message == SMABORT_TAG) )
3102 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3104 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3106 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3112 /*---------------------------------------------------------------------
3114 * Function: FPT_sdecm
3116 * Description: Determine the proper responce to the message from the
3119 *---------------------------------------------------------------------*/
3120 static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
3124 PSCCBMgr_tar_info currTar_Info;
3126 CurrCard = &FPT_BL_Card[p_card];
3127 currSCCB = CurrCard->currentSCCB;
3129 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3131 if (message == SMREST_DATA_PTR)
3133 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3135 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3137 FPT_hostDataXferRestart(currSCCB);
3141 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3144 else if (message == SMCMD_COMP)
3148 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3150 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3151 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
3158 else if ((message == SMNO_OP) || (message >= SMIDENT)
3159 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3163 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3166 else if (message == SMREJECT)
3169 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3170 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3171 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3172 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3175 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3180 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3181 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3183 if(currSCCB->Lun == 0x00)
3185 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3188 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3190 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3193 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3197 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3198 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3200 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3204 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3206 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3207 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3210 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3211 CurrCard->discQCount--;
3212 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3213 currSCCB->Sccb_tag = 0x00;
3218 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3222 if(currSCCB->Lun == 0x00)
3224 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3225 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3232 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3233 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3234 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
3236 currTar_Info->TarLUNBusy[0] = 1;
3239 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
3241 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3250 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3251 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3253 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3255 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3260 else if (message == SMEXT)
3264 FPT_shandem(port,p_card,currSCCB);
3267 else if (message == SMIGNORWR)
3270 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3272 message = FPT_sfm(port,currSCCB);
3274 if(currSCCB->Sccb_scsimsg != SMPARITY)
3276 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3283 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3284 currSCCB->Sccb_scsimsg = SMREJECT;
3286 ACCEPT_MSG_ATN(port);
3287 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3292 /*---------------------------------------------------------------------
3294 * Function: FPT_shandem
3296 * Description: Decide what to do with the extended message.
3298 *---------------------------------------------------------------------*/
3299 static void FPT_shandem(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB)
3301 unsigned char length,message;
3303 length = FPT_sfm(port,pCurrSCCB);
3308 message = FPT_sfm(port,pCurrSCCB);
3312 if (message == SMSYNC)
3319 FPT_stsyncn(port,p_card);
3324 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3325 ACCEPT_MSG_ATN(port);
3328 else if (message == SMWDTR)
3335 FPT_stwidn(port,p_card);
3340 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3341 ACCEPT_MSG_ATN(port);
3343 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3349 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3350 ACCEPT_MSG_ATN(port);
3352 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3357 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3359 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3363 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3364 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3369 /*---------------------------------------------------------------------
3371 * Function: FPT_sisyncn
3373 * Description: Read in a message byte from the SCSI bus, and check
3374 * for a parity error.
3376 *---------------------------------------------------------------------*/
3378 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
3381 PSCCBMgr_tar_info currTar_Info;
3383 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3384 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3386 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3389 WRW_HARPOON((port+ID_MSG_STRT),
3390 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3392 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3394 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3395 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3396 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3399 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3401 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3403 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3405 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3407 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3409 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3412 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3415 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3416 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3417 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3422 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3423 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3424 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
3428 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3437 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3438 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3445 /*---------------------------------------------------------------------
3447 * Function: FPT_stsyncn
3449 * Description: The has sent us a Sync Nego message so handle it as
3452 *---------------------------------------------------------------------*/
3453 static void FPT_stsyncn(unsigned long port, unsigned char p_card)
3455 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
3457 PSCCBMgr_tar_info currTar_Info;
3459 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3460 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3462 sync_msg = FPT_sfm(port,currSCCB);
3464 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3466 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3473 offset = FPT_sfm(port,currSCCB);
3475 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3477 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3481 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3483 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3485 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3487 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3489 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3491 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3494 our_sync_msg = 0; /* Message = Async */
3496 if (sync_msg < our_sync_msg) {
3497 sync_msg = our_sync_msg; /*if faster, then set to max. */
3500 if (offset == ASYNC)
3503 if (offset > MAX_OFFSET)
3504 offset = MAX_OFFSET;
3510 sync_reg = 0x20; /* Use 10MB/s */
3514 sync_reg = 0x40; /* Use 6.6MB/s */
3518 sync_reg = 0x60; /* Use 5MB/s */
3522 sync_reg = 0x80; /* Use 4MB/s */
3526 sync_reg = 0xA0; /* Use 3.33MB/s */
3530 sync_reg = 0xC0; /* Use 2.85MB/s */
3534 sync_reg = 0xE0; /* Use 2.5MB/s */
3536 if (sync_msg > 100) {
3538 sync_reg = 0x00; /* Use ASYNC */
3543 if (currTar_Info->TarStatus & WIDE_ENABLED)
3549 sync_reg |= (offset | NARROW_SCSI);
3551 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
3554 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3559 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3560 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3562 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3568 ACCEPT_MSG_ATN(port);
3570 FPT_sisyncr(port,sync_msg,offset);
3572 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3573 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3578 /*---------------------------------------------------------------------
3580 * Function: FPT_sisyncr
3582 * Description: Answer the targets sync message.
3584 *---------------------------------------------------------------------*/
3585 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
3588 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3589 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3590 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3591 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3592 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3593 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3594 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3597 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3598 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3600 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3602 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3607 /*---------------------------------------------------------------------
3609 * Function: FPT_siwidn
3611 * Description: Read in a message byte from the SCSI bus, and check
3612 * for a parity error.
3614 *---------------------------------------------------------------------*/
3616 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
3619 PSCCBMgr_tar_info currTar_Info;
3621 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3622 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3624 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3627 WRW_HARPOON((port+ID_MSG_STRT),
3628 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3630 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3632 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3633 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3634 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3635 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3636 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3637 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3639 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3642 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3643 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
3650 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3651 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3653 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3660 /*---------------------------------------------------------------------
3662 * Function: FPT_stwidn
3664 * Description: The has sent us a Wide Nego message so handle it as
3667 *---------------------------------------------------------------------*/
3668 static void FPT_stwidn(unsigned long port, unsigned char p_card)
3670 unsigned char width;
3672 PSCCBMgr_tar_info currTar_Info;
3674 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3675 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3677 width = FPT_sfm(port,currSCCB);
3679 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3681 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3686 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3690 currTar_Info->TarStatus |= WIDE_ENABLED;
3694 width = NARROW_SCSI;
3695 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3699 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
3702 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3707 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3709 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3711 ACCEPT_MSG_ATN(port);
3713 FPT_sisyncn(port,p_card, 1);
3714 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3720 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3727 ACCEPT_MSG_ATN(port);
3729 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3734 FPT_siwidr(port,width);
3736 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3741 /*---------------------------------------------------------------------
3743 * Function: FPT_siwidr
3745 * Description: Answer the targets Wide nego message.
3747 *---------------------------------------------------------------------*/
3748 static void FPT_siwidr(unsigned long port, unsigned char width)
3751 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3752 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3753 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3754 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3755 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3756 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3759 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3760 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3762 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3764 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3769 /*---------------------------------------------------------------------
3771 * Function: FPT_sssyncv
3773 * Description: Write the desired value to the Sync Register for the
3776 *---------------------------------------------------------------------*/
3777 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
3778 PSCCBMgr_tar_info currTar_Info)
3780 unsigned char index;
3787 index = 12; /* hp_synctarg_0 */
3790 index = 13; /* hp_synctarg_1 */
3793 index = 14; /* hp_synctarg_2 */
3796 index = 15; /* hp_synctarg_3 */
3799 index = 8; /* hp_synctarg_4 */
3802 index = 9; /* hp_synctarg_5 */
3805 index = 10; /* hp_synctarg_6 */
3808 index = 11; /* hp_synctarg_7 */
3811 index = 4; /* hp_synctarg_8 */
3814 index = 5; /* hp_synctarg_9 */
3817 index = 6; /* hp_synctarg_10 */
3820 index = 7; /* hp_synctarg_11 */
3823 index = 0; /* hp_synctarg_12 */
3826 index = 1; /* hp_synctarg_13 */
3829 index = 2; /* hp_synctarg_14 */
3832 index = 3; /* hp_synctarg_15 */
3836 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3838 currTar_Info->TarSyncCtrl = p_sync_value;
3842 /*---------------------------------------------------------------------
3844 * Function: FPT_sresb
3846 * Description: Reset the desired card's SCSI bus.
3848 *---------------------------------------------------------------------*/
3849 static void FPT_sresb(unsigned long port, unsigned char p_card)
3851 unsigned char scsiID, i;
3853 PSCCBMgr_tar_info currTar_Info;
3855 WR_HARPOON(port+hp_page_ctrl,
3856 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3857 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3859 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3861 scsiID = RD_HARPOON(port+hp_seltimeout);
3862 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3863 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3865 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3867 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3869 WR_HARPOON(port+hp_seltimeout,scsiID);
3871 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3873 FPT_Wait(port, TO_5ms);
3875 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3877 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3879 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3881 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3883 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3885 currTar_Info->TarSyncCtrl = 0;
3886 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3889 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3891 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3894 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
3896 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3899 FPT_BL_Card[p_card].scanIndex = 0x00;
3900 FPT_BL_Card[p_card].currentSCCB = NULL;
3901 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3903 FPT_BL_Card[p_card].cmdCounter = 0x00;
3904 FPT_BL_Card[p_card].discQCount = 0x00;
3905 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3907 for(i = 0; i < QUEUE_DEPTH; i++)
3908 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3910 WR_HARPOON(port+hp_page_ctrl,
3911 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3915 /*---------------------------------------------------------------------
3917 * Function: FPT_ssenss
3919 * Description: Setup for the Auto Sense command.
3921 *---------------------------------------------------------------------*/
3922 static void FPT_ssenss(PSCCBcard pCurrCard)
3927 currSCCB = pCurrCard->currentSCCB;
3930 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3932 for (i = 0; i < 6; i++) {
3934 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3937 currSCCB->CdbLength = SIX_BYTE_CMD;
3938 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3939 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3940 currSCCB->Cdb[2] = 0x00;
3941 currSCCB->Cdb[3] = 0x00;
3942 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3943 currSCCB->Cdb[5] = 0x00;
3945 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3947 currSCCB->Sccb_ATC = 0x00;
3949 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3951 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3953 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3955 currSCCB->ControlByte = 0x00;
3957 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3962 /*---------------------------------------------------------------------
3964 * Function: FPT_sxfrp
3966 * Description: Transfer data into the bit bucket until the device
3967 * decides to switch phase.
3969 *---------------------------------------------------------------------*/
3971 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
3973 unsigned char curr_phz;
3976 DISABLE_AUTO(p_port);
3978 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3980 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
3984 /* If the Automation handled the end of the transfer then do not
3985 match the phase or we will get out of sync with the ISR. */
3987 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3990 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3992 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3994 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3997 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3999 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
4000 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
4002 if (curr_phz & (unsigned char)SCSI_IOBIT)
4004 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4006 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4008 RD_HARPOON(p_port+hp_fifodata_0);
4013 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4014 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4016 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4019 } /* End of While loop for padding data I/O phase */
4021 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4023 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4027 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4028 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4030 RD_HARPOON(p_port+hp_fifodata_0);
4033 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4035 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4036 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4038 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4039 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4044 /*---------------------------------------------------------------------
4046 * Function: FPT_schkdd
4048 * Description: Make sure data has been flushed from both FIFOs and abort
4049 * the operations if necessary.
4051 *---------------------------------------------------------------------*/
4053 static void FPT_schkdd(unsigned long port, unsigned char p_card)
4055 unsigned short TimeOutLoop;
4056 unsigned char sPhase;
4060 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4063 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4064 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4070 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4073 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4075 currSCCB->Sccb_XferCnt = 1;
4077 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4078 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
4079 WR_HARPOON(port+hp_xferstat, 0x00);
4085 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4087 currSCCB->Sccb_XferCnt = 0;
4090 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4091 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4093 currSCCB->HostStatus = SCCB_PARITY_ERR;
4094 WRW_HARPOON((port+hp_intstat), PARITY);
4098 FPT_hostDataXferAbort(port,p_card,currSCCB);
4101 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4105 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4107 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4110 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
4113 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4116 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4120 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4121 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4122 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
4123 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4124 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4127 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4129 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4131 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4132 FPT_phaseDataIn(port,p_card);
4136 FPT_phaseDataOut(port,p_card);
4141 FPT_sxfrp(port,p_card);
4142 if (!(RDW_HARPOON((port+hp_intstat)) &
4143 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4145 WRW_HARPOON((port+hp_intstat), AUTO_INT);
4146 FPT_phaseDecode(port,p_card);
4153 WR_HARPOON(port+hp_portctrl_0, 0x00);
4158 /*---------------------------------------------------------------------
4160 * Function: FPT_sinits
4162 * Description: Setup SCCB manager fields in this SCCB.
4164 *---------------------------------------------------------------------*/
4166 static void FPT_sinits(PSCCB p_sccb, unsigned char p_card)
4168 PSCCBMgr_tar_info currTar_Info;
4170 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4174 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
4176 p_sccb->Sccb_XferState = 0x00;
4177 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4179 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4180 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4182 p_sccb->Sccb_SGoffset = 0;
4183 p_sccb->Sccb_XferState = F_SG_XFER;
4184 p_sccb->Sccb_XferCnt = 0x00;
4187 if (p_sccb->DataLength == 0x00)
4189 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4191 if (p_sccb->ControlByte & F_USE_CMD_Q)
4193 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4194 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4197 currTar_Info->TarStatus |= TAG_Q_TRYING;
4200 /* For !single SCSI device in system & device allow Disconnect
4201 or command is tag_q type then send Cmd with Disconnect Enable
4202 else send Cmd with Disconnect Disable */
4205 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4206 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4207 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4209 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4210 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4211 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4216 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
4219 p_sccb->HostStatus = 0x00;
4220 p_sccb->TargetStatus = 0x00;
4221 p_sccb->Sccb_tag = 0x00;
4222 p_sccb->Sccb_MGRFlags = 0x00;
4223 p_sccb->Sccb_sgseg = 0x00;
4224 p_sccb->Sccb_ATC = 0x00;
4225 p_sccb->Sccb_savedATC = 0x00;
4227 p_sccb->SccbVirtDataPtr = 0x00;
4228 p_sccb->Sccb_forwardlink = NULL;
4229 p_sccb->Sccb_backlink = NULL;
4231 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4232 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4233 p_sccb->Sccb_scsimsg = SMNO_OP;
4238 /*---------------------------------------------------------------------
4240 * Function: Phase Decode
4242 * Description: Determine the phase and call the appropriate function.
4244 *---------------------------------------------------------------------*/
4246 static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
4248 unsigned char phase_ref;
4249 void (*phase) (unsigned long, unsigned char);
4252 DISABLE_AUTO(p_port);
4254 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4256 phase = FPT_s_PhaseTbl[phase_ref];
4258 (*phase)(p_port, p_card); /* Call the correct phase func */
4263 /*---------------------------------------------------------------------
4265 * Function: Data Out Phase
4267 * Description: Start up both the BusMaster and Xbow.
4269 *---------------------------------------------------------------------*/
4271 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
4276 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4277 if (currSCCB == NULL)
4279 return; /* Exit if No SCCB record */
4282 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4283 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4285 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4287 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4289 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4291 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4293 if (currSCCB->Sccb_XferCnt == 0) {
4296 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4297 (currSCCB->HostStatus == SCCB_COMPLETE))
4298 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4300 FPT_sxfrp(port,p_card);
4301 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4302 FPT_phaseDecode(port,p_card);
4307 /*---------------------------------------------------------------------
4309 * Function: Data In Phase
4311 * Description: Startup the BusMaster and the XBOW.
4313 *---------------------------------------------------------------------*/
4315 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
4320 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4322 if (currSCCB == NULL)
4324 return; /* Exit if No SCCB record */
4328 currSCCB->Sccb_scsistat = DATA_IN_ST;
4329 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4330 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4332 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4334 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4336 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4338 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4340 if (currSCCB->Sccb_XferCnt == 0) {
4343 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4344 (currSCCB->HostStatus == SCCB_COMPLETE))
4345 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4347 FPT_sxfrp(port,p_card);
4348 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4349 FPT_phaseDecode(port,p_card);
4354 /*---------------------------------------------------------------------
4356 * Function: Command Phase
4358 * Description: Load the CDB into the automation and start it up.
4360 *---------------------------------------------------------------------*/
4362 static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
4365 unsigned long cdb_reg;
4368 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4370 if (currSCCB->OperationCode == RESET_COMMAND) {
4372 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4373 currSCCB->CdbLength = SIX_BYTE_CMD;
4376 WR_HARPOON(p_port+hp_scsisig, 0x00);
4378 ARAM_ACCESS(p_port);
4381 cdb_reg = p_port + CMD_STRT;
4383 for (i=0; i < currSCCB->CdbLength; i++) {
4385 if (currSCCB->OperationCode == RESET_COMMAND)
4387 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4390 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4394 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4395 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4397 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4399 currSCCB->Sccb_scsistat = COMMAND_ST;
4401 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4402 SGRAM_ACCESS(p_port);
4406 /*---------------------------------------------------------------------
4408 * Function: Status phase
4410 * Description: Bring in the status and command complete message bytes
4412 *---------------------------------------------------------------------*/
4414 static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
4416 /* Start-up the automation to finish off this command and let the
4417 isr handle the interrupt for command complete when it comes in.
4418 We could wait here for the interrupt to be generated?
4421 WR_HARPOON(port+hp_scsisig, 0x00);
4423 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4427 /*---------------------------------------------------------------------
4429 * Function: Phase Message Out
4431 * Description: Send out our message (if we have one) and handle whatever
4434 *---------------------------------------------------------------------*/
4436 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
4438 unsigned char message,scsiID;
4440 PSCCBMgr_tar_info currTar_Info;
4442 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4444 if (currSCCB != NULL) {
4446 message = currSCCB->Sccb_scsimsg;
4447 scsiID = currSCCB->TargID;
4449 if (message == SMDEV_RESET)
4453 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4454 currTar_Info->TarSyncCtrl = 0;
4455 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
4457 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
4460 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
4464 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
4467 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
4471 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4472 FPT_SccbMgrTableInitTarget(p_card,scsiID);
4474 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4476 currSCCB->HostStatus = SCCB_COMPLETE;
4477 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
4479 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4480 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4485 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4489 if(message == SMNO_OP)
4491 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4493 FPT_ssel(port,p_card);
4501 if (message == SMABORT)
4503 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4512 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4515 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4517 WR_HARPOON(port+hp_scsidata_0,message);
4519 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4523 WR_HARPOON(port+hp_portctrl_0, 0x00);
4525 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4526 (message == SMABORT_TAG) )
4529 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4531 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4533 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4535 if (currSCCB != NULL)
4538 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4539 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4540 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4542 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4544 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
4549 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4556 FPT_sxfrp(port,p_card);
4563 if(message == SMPARITY)
4565 currSCCB->Sccb_scsimsg = SMNO_OP;
4566 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4570 FPT_sxfrp(port,p_card);
4576 /*---------------------------------------------------------------------
4578 * Function: Message In phase
4580 * Description: Bring in the message and determine what to do with it.
4582 *---------------------------------------------------------------------*/
4584 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
4586 unsigned char message;
4589 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4591 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
4594 FPT_phaseChkFifo(port, p_card);
4597 message = RD_HARPOON(port+hp_scsidata_0);
4598 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4601 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4608 message = FPT_sfm(port,currSCCB);
4613 FPT_sdecm(message,port,p_card);
4618 if(currSCCB->Sccb_scsimsg != SMPARITY)
4620 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4627 /*---------------------------------------------------------------------
4629 * Function: Illegal phase
4631 * Description: Target switched to some illegal phase, so all we can do
4632 * is report an error back to the host (if that is possible)
4633 * and send an ABORT message to the misbehaving target.
4635 *---------------------------------------------------------------------*/
4637 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
4641 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4643 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4644 if (currSCCB != NULL) {
4646 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4647 currSCCB->Sccb_scsistat = ABORT_ST;
4648 currSCCB->Sccb_scsimsg = SMABORT;
4651 ACCEPT_MSG_ATN(port);
4656 /*---------------------------------------------------------------------
4658 * Function: Phase Check FIFO
4660 * Description: Make sure data has been flushed from both FIFOs and abort
4661 * the operations if necessary.
4663 *---------------------------------------------------------------------*/
4665 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
4667 unsigned long xfercnt;
4670 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4672 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4675 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4676 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4679 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4681 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4683 currSCCB->Sccb_XferCnt = 0;
4685 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4686 (currSCCB->HostStatus == SCCB_COMPLETE))
4688 currSCCB->HostStatus = SCCB_PARITY_ERR;
4689 WRW_HARPOON((port+hp_intstat), PARITY);
4692 FPT_hostDataXferAbort(port,p_card,currSCCB);
4694 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4696 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4697 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4700 } /*End Data In specific code. */
4704 GET_XFER_CNT(port,xfercnt);
4707 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4710 WR_HARPOON(port+hp_portctrl_0, 0x00);
4712 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4714 currSCCB->Sccb_XferCnt = xfercnt;
4716 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4717 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4719 currSCCB->HostStatus = SCCB_PARITY_ERR;
4720 WRW_HARPOON((port+hp_intstat), PARITY);
4724 FPT_hostDataXferAbort(port,p_card,currSCCB);
4727 WR_HARPOON(port+hp_fifowrite, 0x00);
4728 WR_HARPOON(port+hp_fiforead, 0x00);
4729 WR_HARPOON(port+hp_xferstat, 0x00);
4731 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4735 /*---------------------------------------------------------------------
4737 * Function: Phase Bus Free
4739 * Description: We just went bus free so figure out if it was
4740 * because of command complete or from a disconnect.
4742 *---------------------------------------------------------------------*/
4743 static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
4747 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4749 if (currSCCB != NULL)
4755 if (currSCCB->OperationCode == RESET_COMMAND)
4758 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4759 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4760 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4762 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4764 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4766 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
4770 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4772 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4773 (unsigned char)SYNC_SUPPORTED;
4774 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4777 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4779 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4780 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4781 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4783 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
4786 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4788 /* Make sure this is not a phony BUS_FREE. If we were
4789 reselected or if BUSY is NOT on then this is a
4790 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4792 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4793 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4795 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4796 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
4808 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4810 if (!currSCCB->HostStatus)
4812 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4815 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4816 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4817 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4819 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4821 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4826 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4828 } /*end if !=null */
4834 /*---------------------------------------------------------------------
4836 * Function: Auto Load Default Map
4838 * Description: Load the Automation RAM with the defualt map values.
4840 *---------------------------------------------------------------------*/
4841 static void FPT_autoLoadDefaultMap(unsigned long p_port)
4843 unsigned long map_addr;
4845 ARAM_ACCESS(p_port);
4846 map_addr = p_port + hp_aramBase;
4848 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4850 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4852 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4854 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4856 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4858 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4870 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4872 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4874 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4876 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4878 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4880 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4882 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4883 map_addr +=2; /*This means AYNC DATA IN */
4884 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4886 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4888 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4890 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4892 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4894 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4896 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4898 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4900 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4902 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4904 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4906 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4908 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4910 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4912 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4914 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4916 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4918 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4921 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4923 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4925 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4927 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4928 map_addr +=2; /* DIDN'T GET ONE */
4929 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4931 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4933 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4937 SGRAM_ACCESS(p_port);
4940 /*---------------------------------------------------------------------
4942 * Function: Auto Command Complete
4944 * Description: Post command back to host and find another command
4947 *---------------------------------------------------------------------*/
4949 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
4952 unsigned char status_byte;
4954 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4956 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4958 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4960 if (status_byte != SSGOOD) {
4962 if (status_byte == SSQ_FULL) {
4965 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4966 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4968 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4969 if(FPT_BL_Card[p_card].discQCount != 0)
4970 FPT_BL_Card[p_card].discQCount--;
4971 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
4975 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
4976 if(currSCCB->Sccb_tag)
4978 if(FPT_BL_Card[p_card].discQCount != 0)
4979 FPT_BL_Card[p_card].discQCount--;
4980 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4983 if(FPT_BL_Card[p_card].discQCount != 0)
4984 FPT_BL_Card[p_card].discQCount--;
4985 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
4989 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4991 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
4996 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4998 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4999 (unsigned char)SYNC_SUPPORTED;
5001 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
5002 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5004 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5005 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5007 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5008 if(FPT_BL_Card[p_card].discQCount != 0)
5009 FPT_BL_Card[p_card].discQCount--;
5010 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5014 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5015 if(currSCCB->Sccb_tag)
5017 if(FPT_BL_Card[p_card].discQCount != 0)
5018 FPT_BL_Card[p_card].discQCount--;
5019 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5022 if(FPT_BL_Card[p_card].discQCount != 0)
5023 FPT_BL_Card[p_card].discQCount--;
5024 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5031 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5034 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5035 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
5036 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5038 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5039 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5041 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5042 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5044 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5045 if(FPT_BL_Card[p_card].discQCount != 0)
5046 FPT_BL_Card[p_card].discQCount--;
5047 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5051 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5052 if(currSCCB->Sccb_tag)
5054 if(FPT_BL_Card[p_card].discQCount != 0)
5055 FPT_BL_Card[p_card].discQCount--;
5056 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5059 if(FPT_BL_Card[p_card].discQCount != 0)
5060 FPT_BL_Card[p_card].discQCount--;
5061 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5068 if (status_byte == SSCHECK)
5070 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
5072 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
5074 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
5076 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
5078 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
5083 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5085 currSCCB->SccbStatus = SCCB_ERROR;
5086 currSCCB->TargetStatus = status_byte;
5088 if (status_byte == SSCHECK) {
5090 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5094 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5096 if (currSCCB->RequestSenseLength == 0)
5097 currSCCB->RequestSenseLength = 14;
5099 FPT_ssenss(&FPT_BL_Card[p_card]);
5100 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5102 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5103 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5105 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5106 if(FPT_BL_Card[p_card].discQCount != 0)
5107 FPT_BL_Card[p_card].discQCount--;
5108 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5112 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5113 if(currSCCB->Sccb_tag)
5115 if(FPT_BL_Card[p_card].discQCount != 0)
5116 FPT_BL_Card[p_card].discQCount--;
5117 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5120 if(FPT_BL_Card[p_card].discQCount != 0)
5121 FPT_BL_Card[p_card].discQCount--;
5122 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5132 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5133 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5134 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
5136 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5139 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
5142 #define SHORT_WAIT 0x0000000F
5143 #define LONG_WAIT 0x0000FFFFL
5146 /*---------------------------------------------------------------------
5148 * Function: Data Transfer Processor
5150 * Description: This routine performs two tasks.
5151 * (1) Start data transfer by calling HOST_DATA_XFER_START
5152 * function. Once data transfer is started, (2) Depends
5153 * on the type of data transfer mode Scatter/Gather mode
5154 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5155 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5156 * data transfer done. In Scatter/Gather mode, this routine
5157 * checks bus master command complete and dual rank busy
5158 * bit to keep chaining SC transfer command. Similarly,
5159 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5160 * (F_HOST_XFER_ACT bit) for data transfer done.
5162 *---------------------------------------------------------------------*/
5164 static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
5168 currSCCB = pCurrCard->currentSCCB;
5170 if (currSCCB->Sccb_XferState & F_SG_XFER)
5172 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5175 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
5176 currSCCB->Sccb_SGoffset = 0x00;
5178 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5180 FPT_busMstrSGDataXferStart(port, currSCCB);
5185 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5187 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5189 FPT_busMstrDataXferStart(port, currSCCB);
5195 /*---------------------------------------------------------------------
5197 * Function: BusMaster Scatter Gather Data Transfer Start
5201 *---------------------------------------------------------------------*/
5202 static void FPT_busMstrSGDataXferStart(unsigned long p_port, PSCCB pcurrSCCB)
5204 unsigned long count,addr,tmpSGCnt;
5205 unsigned int sg_index;
5206 unsigned char sg_count, i;
5207 unsigned long reg_offset;
5210 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5212 count = ((unsigned long) HOST_RD_CMD)<<24;
5216 count = ((unsigned long) HOST_WRT_CMD)<<24;
5221 sg_index = pcurrSCCB->Sccb_sgseg;
5222 reg_offset = hp_aramBase;
5225 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5228 WR_HARPOON(p_port+hp_page_ctrl, i);
5230 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
5231 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5233 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
5236 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
5239 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
5240 ((sg_index * 2) + 1));
5243 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5245 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5246 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5248 tmpSGCnt = count & 0x00FFFFFFL;
5251 WR_HARP32(p_port,reg_offset,addr);
5254 WR_HARP32(p_port,reg_offset,count);
5257 count &= 0xFF000000L;
5263 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5265 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5267 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5269 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5272 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5273 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5279 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5280 (tmpSGCnt & 0x000000001))
5283 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5288 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5290 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5291 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5295 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
5300 /*---------------------------------------------------------------------
5302 * Function: BusMaster Data Transfer Start
5306 *---------------------------------------------------------------------*/
5307 static void FPT_busMstrDataXferStart(unsigned long p_port, PSCCB pcurrSCCB)
5309 unsigned long addr,count;
5311 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5313 count = pcurrSCCB->Sccb_XferCnt;
5315 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5319 addr = pcurrSCCB->SensePointer;
5320 count = pcurrSCCB->RequestSenseLength;
5324 HP_SETUP_ADDR_CNT(p_port,addr,count);
5327 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5329 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5330 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5332 WR_HARPOON(p_port+hp_xfer_cmd,
5333 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5338 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5339 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5341 WR_HARPOON(p_port+hp_xfer_cmd,
5342 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5348 /*---------------------------------------------------------------------
5350 * Function: BusMaster Timeout Handler
5352 * Description: This function is called after a bus master command busy time
5353 * out is detected. This routines issue halt state machine
5354 * with a software time out for command busy. If command busy
5355 * is still asserted at the end of the time out, it issues
5356 * hard abort with another software time out. It hard abort
5357 * command busy is also time out, it'll just give up.
5359 *---------------------------------------------------------------------*/
5360 static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
5362 unsigned long timeout;
5364 timeout = LONG_WAIT;
5366 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5368 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5372 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5373 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5375 timeout = LONG_WAIT;
5376 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5379 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5381 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5391 /*---------------------------------------------------------------------
5393 * Function: Host Data Transfer Abort
5395 * Description: Abort any in progress transfer.
5397 *---------------------------------------------------------------------*/
5398 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, PSCCB pCurrSCCB)
5401 unsigned long timeout;
5402 unsigned long remain_cnt;
5403 unsigned int sg_ptr;
5405 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5407 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5410 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5412 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5413 timeout = LONG_WAIT;
5415 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5417 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5419 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5421 if (FPT_busMstrTimeOut(port)) {
5423 if (pCurrSCCB->HostStatus == 0x00)
5425 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5429 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5431 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5433 if (pCurrSCCB->HostStatus == 0x00)
5436 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5442 else if (pCurrSCCB->Sccb_XferCnt) {
5444 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5447 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5450 WR_HARPOON(port+hp_sg_addr,0x00);
5452 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5454 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5456 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5459 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5461 while (remain_cnt < 0x01000000L) {
5465 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
5466 DataPointer) + (sg_ptr * 2)))) {
5468 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
5469 DataPointer) + (sg_ptr * 2)));
5480 if (remain_cnt < 0x01000000L) {
5483 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5485 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5488 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5489 && (remain_cnt == 0))
5491 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5497 if (pCurrSCCB->HostStatus == 0x00) {
5499 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5505 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5508 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5510 FPT_busMstrTimeOut(port);
5515 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5517 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5519 if (pCurrSCCB->HostStatus == 0x00) {
5521 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5532 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5534 timeout = SHORT_WAIT;
5536 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5537 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5541 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5543 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5546 timeout = LONG_WAIT;
5548 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5551 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5555 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5557 if (pCurrSCCB->HostStatus == 0x00) {
5559 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5562 FPT_busMstrTimeOut(port);
5566 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5568 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5570 if (pCurrSCCB->HostStatus == 0x00) {
5572 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5583 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5585 timeout = LONG_WAIT;
5587 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5589 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5591 if (pCurrSCCB->HostStatus == 0x00) {
5593 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5596 FPT_busMstrTimeOut(port);
5601 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5603 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5605 if (pCurrSCCB->HostStatus == 0x00) {
5607 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5613 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5615 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5618 WR_HARPOON(port+hp_sg_addr,0x00);
5620 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5622 pCurrSCCB->Sccb_SGoffset = 0x00;
5625 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5626 pCurrSCCB->DataLength) {
5628 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5630 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5637 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5639 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5643 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5648 /*---------------------------------------------------------------------
5650 * Function: Host Data Transfer Restart
5652 * Description: Reset the available count due to a restore data
5655 *---------------------------------------------------------------------*/
5656 static void FPT_hostDataXferRestart(PSCCB currSCCB)
5658 unsigned long data_count;
5659 unsigned int sg_index;
5660 unsigned long *sg_ptr;
5662 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5664 currSCCB->Sccb_XferCnt = 0;
5666 sg_index = 0xffff; /*Index by long words into sg list. */
5667 data_count = 0; /*Running count of SG xfer counts. */
5669 sg_ptr = (unsigned long *)currSCCB->DataPointer;
5671 while (data_count < currSCCB->Sccb_ATC) {
5674 data_count += *(sg_ptr+(sg_index * 2));
5677 if (data_count == currSCCB->Sccb_ATC) {
5679 currSCCB->Sccb_SGoffset = 0;
5684 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5687 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5691 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5697 /*---------------------------------------------------------------------
5699 * Function: FPT_scini
5701 * Description: Setup all data structures necessary for SCAM selection.
5703 *---------------------------------------------------------------------*/
5705 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
5708 unsigned char loser,assigned_id;
5709 unsigned long p_port;
5711 unsigned char i,k,ScamFlg ;
5713 PNVRamInfo pCurrNvRam;
5715 currCard = &FPT_BL_Card[p_card];
5716 p_port = currCard->ioPort;
5717 pCurrNvRam = currCard->pNvRamInfo;
5721 ScamFlg = pCurrNvRam->niScamConf;
5722 i = pCurrNvRam->niSysConf;
5725 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5726 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
5728 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5731 FPT_inisci(p_card,p_port, p_our_id);
5733 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5734 too slow to return to SCAM selection */
5737 FPT_Wait1Second(p_port);
5739 FPT_Wait(p_port, TO_250ms); */
5741 FPT_Wait1Second(p_port);
5743 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5745 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5750 FPT_scxferc(p_port,SYNC_PTRN);
5751 FPT_scxferc(p_port,DOM_MSTR);
5752 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
5753 } while ( loser == 0xFF );
5757 if ((p_power_up) && (!loser))
5759 FPT_sresb(p_port,p_card);
5760 FPT_Wait(p_port, TO_250ms);
5762 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5767 FPT_scxferc(p_port, SYNC_PTRN);
5768 FPT_scxferc(p_port, DOM_MSTR);
5769 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
5771 } while ( loser == 0xFF );
5786 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5789 if (ScamFlg & SCAM_ENABLED)
5792 for (i=0; i < MAX_SCSI_TAR; i++)
5794 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5795 (FPT_scamInfo[i].state == ID_UNUSED))
5797 if (FPT_scsell(p_port,i))
5799 FPT_scamInfo[i].state = LEGACY;
5800 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5801 (FPT_scamInfo[i].id_string[1] != 0xFA))
5804 FPT_scamInfo[i].id_string[0] = 0xFF;
5805 FPT_scamInfo[i].id_string[1] = 0xFA;
5806 if(pCurrNvRam == NULL)
5807 currCard->globalFlags |= F_UPDATE_EEPROM;
5813 FPT_sresb(p_port,p_card);
5814 FPT_Wait1Second(p_port);
5815 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5817 FPT_scasid(p_card, p_port);
5822 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5824 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5826 FPT_scwtsel(p_port);
5829 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
5831 i = FPT_scxferc(p_port,0x00);
5834 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
5836 i = FPT_scxferc(p_port,0x00);
5839 k = FPT_scxferc(p_port,0x00);
5844 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
5845 FPT_inisci(p_card, p_port, p_our_id);
5846 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5847 FPT_scamInfo[currCard->ourId].id_string[0]
5855 else if (i == SET_P_FLAG)
5857 if (!(FPT_scsendi(p_port,
5858 &FPT_scamInfo[p_our_id].id_string[0])))
5859 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
5861 }while (!assigned_id);
5863 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
5866 if (ScamFlg & SCAM_ENABLED)
5869 if (currCard->globalFlags & F_UPDATE_EEPROM)
5871 FPT_scsavdi(p_card, p_port);
5872 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5878 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5880 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5881 (FPT_scamInfo[i].state == LEGACY))
5886 currCard->globalFlags |= F_SINGLE_DEVICE;
5888 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5893 /*---------------------------------------------------------------------
5895 * Function: FPT_scarb
5897 * Description: Gain control of the bus and wait SCAM select time (250ms)
5899 *---------------------------------------------------------------------*/
5901 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
5903 if (p_sel_type == INIT_SELTD)
5906 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5909 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
5912 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
5915 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5917 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5919 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5925 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5927 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5929 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5930 ~(SCSI_BSY | SCSI_SEL)));
5936 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5938 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5939 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5940 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
5941 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5943 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5945 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5948 FPT_Wait(p_port,TO_250ms);
5954 /*---------------------------------------------------------------------
5956 * Function: FPT_scbusf
5958 * Description: Release the SCSI bus and disable SCAM selection.
5960 *---------------------------------------------------------------------*/
5962 static void FPT_scbusf(unsigned long p_port)
5964 WR_HARPOON(p_port+hp_page_ctrl,
5965 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5968 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5970 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5973 WR_HARPOON(p_port+hp_scsisig, 0x00);
5976 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5979 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5982 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5984 WR_HARPOON(p_port+hp_page_ctrl,
5985 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5990 /*---------------------------------------------------------------------
5992 * Function: FPT_scasid
5994 * Description: Assign an ID to all the SCAM devices.
5996 *---------------------------------------------------------------------*/
5998 static void FPT_scasid(unsigned char p_card, unsigned long p_port)
6000 unsigned char temp_id_string[ID_STRING_LENGTH];
6002 unsigned char i,k,scam_id;
6003 unsigned char crcBytes[3];
6004 PNVRamInfo pCurrNvRam;
6005 unsigned short * pCrcBytes;
6007 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6014 for (k=0; k < ID_STRING_LENGTH; k++)
6016 temp_id_string[k] = (unsigned char) 0x00;
6019 FPT_scxferc(p_port,SYNC_PTRN);
6020 FPT_scxferc(p_port,ASSIGN_ID);
6022 if (!(FPT_sciso(p_port,&temp_id_string[0])))
6025 pCrcBytes = (unsigned short *)&crcBytes[0];
6026 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6027 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
6028 temp_id_string[1] = crcBytes[2];
6029 temp_id_string[2] = crcBytes[0];
6030 temp_id_string[3] = crcBytes[1];
6031 for(k = 4; k < ID_STRING_LENGTH; k++)
6032 temp_id_string[k] = (unsigned char) 0x00;
6034 i = FPT_scmachid(p_card,temp_id_string);
6036 if (i == CLR_PRIORITY)
6038 FPT_scxferc(p_port,MISC_CODE);
6039 FPT_scxferc(p_port,CLR_P_FLAG);
6040 i = 0; /*Not the last ID yet. */
6043 else if (i != NO_ID_AVAIL)
6046 FPT_scxferc(p_port,ID_0_7);
6048 FPT_scxferc(p_port,ID_8_F);
6050 scam_id = (i & (unsigned char) 0x07);
6053 for (k=1; k < 0x08; k <<= 1)
6055 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6057 FPT_scxferc(p_port,scam_id);
6059 i = 0; /*Not the last ID yet. */
6070 FPT_scxferc(p_port,SYNC_PTRN);
6071 FPT_scxferc(p_port,CFG_CMPLT);
6078 /*---------------------------------------------------------------------
6080 * Function: FPT_scsel
6082 * Description: Select all the SCAM devices.
6084 *---------------------------------------------------------------------*/
6086 static void FPT_scsel(unsigned long p_port)
6089 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6090 FPT_scwiros(p_port, SCSI_MSG);
6092 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6095 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6096 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6097 (unsigned char)(BIT(7)+BIT(6))));
6100 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6101 FPT_scwiros(p_port, SCSI_SEL);
6103 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6104 ~(unsigned char)BIT(6)));
6105 FPT_scwirod(p_port, BIT(6));
6107 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6112 /*---------------------------------------------------------------------
6114 * Function: FPT_scxferc
6116 * Description: Handshake the p_data (DB4-0) across the bus.
6118 *---------------------------------------------------------------------*/
6120 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
6122 unsigned char curr_data, ret_data;
6124 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6126 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6128 curr_data &= ~BIT(7);
6130 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6132 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
6133 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6135 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
6137 curr_data |= BIT(6);
6139 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6141 curr_data &= ~BIT(5);
6143 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6145 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
6147 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6148 curr_data |= BIT(7);
6150 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6152 curr_data &= ~BIT(6);
6154 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6156 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
6162 /*---------------------------------------------------------------------
6164 * Function: FPT_scsendi
6166 * Description: Transfer our Identification string to determine if we
6167 * will be the dominant master.
6169 *---------------------------------------------------------------------*/
6171 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
6173 unsigned char ret_data,byte_cnt,bit_cnt,defer;
6177 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6179 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6182 ret_data = FPT_scxferc(p_port,00);
6184 else if (p_id_string[byte_cnt] & bit_cnt)
6186 ret_data = FPT_scxferc(p_port,02);
6190 ret_data = FPT_scxferc(p_port,01);
6195 if ((ret_data & 0x1C) == 0x10)
6196 return(0x00); /*End of isolation stage, we won! */
6198 if (ret_data & 0x1C)
6201 if ((defer) && (!(ret_data & 0x1F)))
6202 return(0x01); /*End of isolation stage, we lost. */
6209 return(0x01); /*We lost */
6211 return(0); /*We WON! Yeeessss! */
6216 /*---------------------------------------------------------------------
6218 * Function: FPT_sciso
6220 * Description: Transfer the Identification string.
6222 *---------------------------------------------------------------------*/
6224 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
6226 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
6230 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6232 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6234 ret_data = FPT_scxferc(p_port,0);
6236 if (ret_data & 0xFC)
6242 if (ret_data & BIT(1)) {
6247 if ((ret_data & 0x1F) == 0)
6250 if(bit_cnt != 0 || bit_cnt != 8)
6254 FPT_scxferc(p_port, SYNC_PTRN);
6255 FPT_scxferc(p_port, ASSIGN_ID);
6267 p_id_string[byte_cnt] = the_data;
6276 /*---------------------------------------------------------------------
6278 * Function: FPT_scwirod
6280 * Description: Sample the SCSI data bus making sure the signal has been
6281 * deasserted for the correct number of consecutive samples.
6283 *---------------------------------------------------------------------*/
6285 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
6290 while ( i < MAX_SCSI_TAR ) {
6292 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6305 /*---------------------------------------------------------------------
6307 * Function: FPT_scwiros
6309 * Description: Sample the SCSI Signal lines making sure the signal has been
6310 * deasserted for the correct number of consecutive samples.
6312 *---------------------------------------------------------------------*/
6314 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
6319 while ( i < MAX_SCSI_TAR ) {
6321 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6333 /*---------------------------------------------------------------------
6335 * Function: FPT_scvalq
6337 * Description: Make sure we received a valid data byte.
6339 *---------------------------------------------------------------------*/
6341 static unsigned char FPT_scvalq(unsigned char p_quintet)
6343 unsigned char count;
6345 for (count=1; count < 0x08; count<<=1) {
6346 if (!(p_quintet & count))
6350 if (p_quintet & 0x18)
6358 /*---------------------------------------------------------------------
6360 * Function: FPT_scsell
6362 * Description: Select the specified device ID using a selection timeout
6363 * less than 4ms. If somebody responds then it is a legacy
6364 * drive and this ID must be marked as such.
6366 *---------------------------------------------------------------------*/
6368 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
6372 WR_HARPOON(p_port+hp_page_ctrl,
6373 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6375 ARAM_ACCESS(p_port);
6377 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6378 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6381 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6382 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6384 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6386 WRW_HARPOON((p_port+hp_intstat),
6387 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6389 WR_HARPOON(p_port+hp_select_id, targ_id);
6391 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6392 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6393 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6396 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6397 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6399 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6400 FPT_Wait(p_port, TO_250ms);
6402 DISABLE_AUTO(p_port);
6404 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6405 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6407 SGRAM_ACCESS(p_port);
6409 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6411 WRW_HARPOON((p_port+hp_intstat),
6412 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6414 WR_HARPOON(p_port+hp_page_ctrl,
6415 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6417 return(0); /*No legacy device */
6422 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6423 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6425 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6430 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6432 WR_HARPOON(p_port+hp_page_ctrl,
6433 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6435 return(1); /*Found one of them oldies! */
6439 /*---------------------------------------------------------------------
6441 * Function: FPT_scwtsel
6443 * Description: Wait to be selected by another SCAM initiator.
6445 *---------------------------------------------------------------------*/
6447 static void FPT_scwtsel(unsigned long p_port)
6449 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6453 /*---------------------------------------------------------------------
6455 * Function: FPT_inisci
6457 * Description: Setup the data Structure with the info from the EEPROM.
6459 *---------------------------------------------------------------------*/
6461 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
6463 unsigned char i,k,max_id;
6464 unsigned short ee_data;
6465 PNVRamInfo pCurrNvRam;
6467 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6469 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6476 for(i = 0; i < max_id; i++){
6478 for(k = 0; k < 4; k++)
6479 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
6480 for(k = 4; k < ID_STRING_LENGTH; k++)
6481 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
6483 if(FPT_scamInfo[i].id_string[0] == 0x00)
6484 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6486 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6490 for (i=0; i < max_id; i++)
6492 for (k=0; k < ID_STRING_LENGTH; k+=2)
6494 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6495 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6496 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
6498 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
6501 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6502 (FPT_scamInfo[i].id_string[0] == 0xFF))
6504 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6507 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6511 for(k = 0; k < ID_STRING_LENGTH; k++)
6512 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6516 /*---------------------------------------------------------------------
6518 * Function: FPT_scmachid
6520 * Description: Match the Device ID string with our values stored in
6523 *---------------------------------------------------------------------*/
6525 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
6528 unsigned char i,k,match;
6531 for (i=0; i < MAX_SCSI_TAR; i++) {
6535 for (k=0; k < ID_STRING_LENGTH; k++)
6537 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6543 FPT_scamInfo[i].state = ID_ASSIGNED;
6551 if (p_id_string[0] & BIT(5))
6556 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6557 match = p_id_string[1] & (unsigned char) 0x1F;
6565 if (FPT_scamInfo[match].state == ID_UNUSED)
6567 for (k=0; k < ID_STRING_LENGTH; k++)
6569 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6572 FPT_scamInfo[match].state = ID_ASSIGNED;
6574 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6575 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6585 if (p_id_string[0] & BIT(5))
6588 match = MAX_SCSI_TAR-1;
6594 if (p_id_string[0] & BIT(7))
6596 return(CLR_PRIORITY);
6600 if (p_id_string[0] & BIT(5))
6605 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6606 match = p_id_string[1] & (unsigned char) 0x1F;
6615 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
6617 for (k=0; k < ID_STRING_LENGTH; k++)
6619 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6622 FPT_scamInfo[match].id_string[0] |= BIT(7);
6623 FPT_scamInfo[match].state = ID_ASSIGNED;
6624 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6625 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6635 if (p_id_string[0] & BIT(5))
6638 match = MAX_SCSI_TAR-1;
6642 return(NO_ID_AVAIL);
6646 /*---------------------------------------------------------------------
6648 * Function: FPT_scsavdi
6650 * Description: Save off the device SCAM ID strings.
6652 *---------------------------------------------------------------------*/
6654 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
6656 unsigned char i,k,max_id;
6657 unsigned short ee_data,sum_data;
6662 for (i = 1; i < EE_SCAMBASE/2; i++)
6664 sum_data += FPT_utilEERead(p_port, i);
6668 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
6670 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6676 for (i=0; i < max_id; i++)
6679 for (k=0; k < ID_STRING_LENGTH; k+=2)
6681 ee_data = FPT_scamInfo[i].id_string[k+1];
6683 ee_data |= FPT_scamInfo[i].id_string[k];
6684 sum_data += ee_data;
6685 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6686 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6691 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6692 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
6695 /*---------------------------------------------------------------------
6697 * Function: FPT_XbowInit
6699 * Description: Setup the Xbow for normal operation.
6701 *---------------------------------------------------------------------*/
6703 static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
6707 i = RD_HARPOON(port+hp_page_ctrl);
6708 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
6710 WR_HARPOON(port+hp_scsireset,0x00);
6711 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6713 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6716 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6718 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6720 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6721 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6723 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6725 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6726 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6728 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6729 FPT_default_intena |= SCAM_SEL;
6731 WRW_HARPOON((port+hp_intena), FPT_default_intena);
6733 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6735 /* Turn on SCSI_MODE8 for narrow cards to fix the
6736 strapping issue with the DUAL CHANNEL card */
6737 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6738 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6740 WR_HARPOON(port+hp_page_ctrl, i);
6745 /*---------------------------------------------------------------------
6747 * Function: FPT_BusMasterInit
6749 * Description: Initialize the BusMaster for normal operations.
6751 *---------------------------------------------------------------------*/
6753 static void FPT_BusMasterInit(unsigned long p_port)
6757 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6758 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6760 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6763 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6765 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6768 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6769 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6770 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6775 /*---------------------------------------------------------------------
6777 * Function: FPT_DiagEEPROM
6779 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6782 *---------------------------------------------------------------------*/
6784 static void FPT_DiagEEPROM(unsigned long p_port)
6786 unsigned short index,temp,max_wd_cnt;
6788 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6789 max_wd_cnt = EEPROM_WD_CNT;
6791 max_wd_cnt = EEPROM_WD_CNT * 2;
6793 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
6795 if (temp == 0x4641) {
6797 for (index = 2; index < max_wd_cnt; index++) {
6799 temp += FPT_utilEERead(p_port, index);
6803 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
6805 return; /*EEPROM is Okay so return now! */
6810 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
6812 for (index = 0; index < max_wd_cnt; index++) {
6814 FPT_utilEEWrite(p_port, 0x0000, index);
6819 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
6821 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
6823 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
6825 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
6827 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
6829 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
6831 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
6833 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
6836 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
6838 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
6840 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
6843 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
6845 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
6847 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
6849 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
6851 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
6853 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
6855 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
6857 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
6861 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
6863 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
6865 FPT_utilEEWrite(p_port, 0x5068, 68/2);
6867 FPT_utilEEWrite(p_port, 0x696F, 70/2);
6869 FPT_utilEEWrite(p_port, 0x746E, 72/2);
6871 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
6873 FPT_utilEEWrite(p_port, 0x2054, 76/2);
6875 FPT_utilEEWrite(p_port, 0x2020, 78/2);
6878 index = ((EE_SCAMBASE/2)+(7*16));
6879 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
6880 temp += (0x0700+TYPE_CODE0);
6882 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6883 temp += 0x5542; /* BUSLOGIC */
6885 FPT_utilEEWrite(p_port, 0x4C53, index);
6888 FPT_utilEEWrite(p_port, 0x474F, index);
6891 FPT_utilEEWrite(p_port, 0x4349, index);
6894 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6895 temp += 0x5442; /* BT- 930 */
6897 FPT_utilEEWrite(p_port, 0x202D, index);
6900 FPT_utilEEWrite(p_port, 0x3339, index);
6902 index++; /*Serial # */
6903 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6906 FPT_utilEEWrite(p_port, 0x5453, index);
6909 FPT_utilEEWrite(p_port, 0x5645, index);
6912 FPT_utilEEWrite(p_port, 0x2045, index);
6915 FPT_utilEEWrite(p_port, 0x202F, index);
6918 FPT_utilEEWrite(p_port, 0x4F4A, index);
6921 FPT_utilEEWrite(p_port, 0x204E, index);
6924 FPT_utilEEWrite(p_port, 0x3539, index);
6929 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
6931 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
6936 /*---------------------------------------------------------------------
6938 * Function: Queue Search Select
6940 * Description: Try to find a new command to execute.
6942 *---------------------------------------------------------------------*/
6944 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
6946 unsigned char scan_ptr, lun;
6947 PSCCBMgr_tar_info currTar_Info;
6950 scan_ptr = pCurrCard->scanIndex;
6953 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6954 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6955 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6957 if (currTar_Info->TarSelQ_Cnt != 0)
6961 if (scan_ptr == MAX_SCSI_TAR)
6964 for(lun=0; lun < MAX_LUN; lun++)
6966 if(currTar_Info->TarLUNBusy[lun] == 0)
6969 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6972 while((pCurrCard->currentSCCB != NULL) &&
6973 (lun != pCurrCard->currentSCCB->Lun))
6975 pOldSccb = pCurrCard->currentSCCB;
6976 pCurrCard->currentSCCB = (PSCCB)(pCurrCard->currentSCCB)->
6979 if(pCurrCard->currentSCCB == NULL)
6981 if(pOldSccb != NULL)
6983 pOldSccb->Sccb_forwardlink = (PSCCB)(pCurrCard->currentSCCB)->
6985 pOldSccb->Sccb_backlink = (PSCCB)(pCurrCard->currentSCCB)->
6987 currTar_Info->TarSelQ_Cnt--;
6991 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6993 if (currTar_Info->TarSelQ_Head == NULL)
6995 currTar_Info->TarSelQ_Tail = NULL;
6996 currTar_Info->TarSelQ_Cnt = 0;
7000 currTar_Info->TarSelQ_Cnt--;
7001 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7004 pCurrCard->scanIndex = scan_ptr;
7006 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7016 if (scan_ptr == MAX_SCSI_TAR) {
7024 if ((currTar_Info->TarSelQ_Cnt != 0) &&
7025 (currTar_Info->TarLUNBusy[0] == 0))
7028 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7030 currTar_Info->TarSelQ_Head = (PSCCB)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7032 if (currTar_Info->TarSelQ_Head == NULL)
7034 currTar_Info->TarSelQ_Tail = NULL;
7035 currTar_Info->TarSelQ_Cnt = 0;
7039 currTar_Info->TarSelQ_Cnt--;
7040 currTar_Info->TarSelQ_Head->Sccb_backlink = (PSCCB)NULL;
7044 if (scan_ptr == MAX_SCSI_TAR)
7047 pCurrCard->scanIndex = scan_ptr;
7049 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7057 if (scan_ptr == MAX_SCSI_TAR)
7063 } while (scan_ptr != pCurrCard->scanIndex);
7067 /*---------------------------------------------------------------------
7069 * Function: Queue Select Fail
7071 * Description: Add the current SCCB to the head of the Queue.
7073 *---------------------------------------------------------------------*/
7075 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
7077 unsigned char thisTarg;
7078 PSCCBMgr_tar_info currTar_Info;
7080 if (pCurrCard->currentSCCB != NULL)
7082 thisTarg = (unsigned char)(((PSCCB)(pCurrCard->currentSCCB))->TargID);
7083 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7085 pCurrCard->currentSCCB->Sccb_backlink = (PSCCB)NULL;
7087 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7089 if (currTar_Info->TarSelQ_Cnt == 0)
7091 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7096 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7100 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7102 pCurrCard->currentSCCB = NULL;
7103 currTar_Info->TarSelQ_Cnt++;
7106 /*---------------------------------------------------------------------
7108 * Function: Queue Command Complete
7110 * Description: Call the callback function with the current SCCB.
7112 *---------------------------------------------------------------------*/
7114 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, PSCCB p_sccb,
7115 unsigned char p_card)
7118 unsigned char i, SCSIcmd;
7119 CALL_BK_FN callback;
7120 PSCCBMgr_tar_info currTar_Info;
7122 SCSIcmd = p_sccb->Cdb[0];
7125 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7127 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7128 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7129 (p_sccb->TargetStatus != SSCHECK))
7131 if ((SCSIcmd == SCSI_READ) ||
7132 (SCSIcmd == SCSI_WRITE) ||
7133 (SCSIcmd == SCSI_READ_EXTENDED) ||
7134 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7135 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7136 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7137 (pCurrCard->globalFlags & F_NO_FILTER)
7139 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7143 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7145 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7146 p_sccb->SccbStatus = SCCB_ERROR;
7148 p_sccb->SccbStatus = SCCB_SUCCESS;
7151 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7153 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7154 for (i=0; i < 6; i++) {
7155 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7159 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7160 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7162 FPT_utilUpdateResidual(p_sccb);
7165 pCurrCard->cmdCounter--;
7166 if (!pCurrCard->cmdCounter) {
7168 if (pCurrCard->globalFlags & F_GREEN_PC) {
7169 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7170 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7173 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7174 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7178 if(pCurrCard->discQCount != 0)
7180 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7181 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7182 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7184 pCurrCard->discQCount--;
7185 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7189 if(p_sccb->Sccb_tag)
7191 pCurrCard->discQCount--;
7192 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7195 pCurrCard->discQCount--;
7196 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7202 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7204 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7205 pCurrCard->currentSCCB = NULL;
7209 /*---------------------------------------------------------------------
7211 * Function: Queue Disconnect
7213 * Description: Add SCCB to our disconnect array.
7215 *---------------------------------------------------------------------*/
7216 static void FPT_queueDisconnect(PSCCB p_sccb, unsigned char p_card)
7218 PSCCBMgr_tar_info currTar_Info;
7220 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7222 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7223 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7225 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
7229 if (p_sccb->Sccb_tag)
7231 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7232 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7233 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7236 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
7239 FPT_BL_Card[p_card].currentSCCB = NULL;
7243 /*---------------------------------------------------------------------
7245 * Function: Queue Flush SCCB
7247 * Description: Flush all SCCB's back to the host driver for this target.
7249 *---------------------------------------------------------------------*/
7251 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
7253 unsigned char qtag,thisTarg;
7255 PSCCBMgr_tar_info currTar_Info;
7257 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7258 if(currSCCB != NULL)
7260 thisTarg = (unsigned char)currSCCB->TargID;
7261 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7263 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7265 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7266 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7269 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7271 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7273 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7274 currTar_Info->TarTagQ_Cnt--;
7282 /*---------------------------------------------------------------------
7284 * Function: Queue Flush Target SCCB
7286 * Description: Flush all SCCB's back to the host driver for this target.
7288 *---------------------------------------------------------------------*/
7290 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7291 unsigned char error_code)
7294 PSCCBMgr_tar_info currTar_Info;
7296 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7298 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7300 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7301 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7304 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7306 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7308 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7309 currTar_Info->TarTagQ_Cnt--;
7320 static void FPT_queueAddSccb(PSCCB p_SCCB, unsigned char p_card)
7322 PSCCBMgr_tar_info currTar_Info;
7323 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7325 p_SCCB->Sccb_forwardlink = NULL;
7327 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7329 if (currTar_Info->TarSelQ_Cnt == 0) {
7331 currTar_Info->TarSelQ_Head = p_SCCB;
7336 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7340 currTar_Info->TarSelQ_Tail = p_SCCB;
7341 currTar_Info->TarSelQ_Cnt++;
7345 /*---------------------------------------------------------------------
7347 * Function: Queue Find SCCB
7349 * Description: Search the target select Queue for this SCCB, and
7350 * remove it if found.
7352 *---------------------------------------------------------------------*/
7354 static unsigned char FPT_queueFindSccb(PSCCB p_SCCB, unsigned char p_card)
7357 PSCCBMgr_tar_info currTar_Info;
7359 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7361 q_ptr = currTar_Info->TarSelQ_Head;
7363 while(q_ptr != NULL) {
7365 if (q_ptr == p_SCCB) {
7368 if (currTar_Info->TarSelQ_Head == q_ptr) {
7370 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7373 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7375 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7378 if (q_ptr->Sccb_forwardlink != NULL) {
7379 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7382 if (q_ptr->Sccb_backlink != NULL) {
7383 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7386 currTar_Info->TarSelQ_Cnt--;
7392 q_ptr = q_ptr->Sccb_forwardlink;
7402 /*---------------------------------------------------------------------
7404 * Function: Utility Update Residual Count
7406 * Description: Update the XferCnt to the remaining byte count.
7407 * If we transferred all the data then just write zero.
7408 * If Non-SG transfer then report Total Cnt - Actual Transfer
7409 * Cnt. For SG transfers add the count fields of all
7410 * remaining SG elements, as well as any partial remaining
7413 *---------------------------------------------------------------------*/
7415 static void FPT_utilUpdateResidual(PSCCB p_SCCB)
7417 unsigned long partial_cnt;
7418 unsigned int sg_index;
7419 unsigned long *sg_ptr;
7421 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7423 p_SCCB->DataLength = 0x0000;
7426 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7428 partial_cnt = 0x0000;
7430 sg_index = p_SCCB->Sccb_sgseg;
7432 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
7434 if (p_SCCB->Sccb_SGoffset) {
7436 partial_cnt = p_SCCB->Sccb_SGoffset;
7440 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
7441 p_SCCB->DataLength ) {
7443 partial_cnt += *(sg_ptr+(sg_index * 2));
7447 p_SCCB->DataLength = partial_cnt;
7452 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7457 /*---------------------------------------------------------------------
7459 * Function: Wait 1 Second
7461 * Description: Wait for 1 second.
7463 *---------------------------------------------------------------------*/
7465 static void FPT_Wait1Second(unsigned long p_port)
7469 for(i=0; i < 4; i++) {
7471 FPT_Wait(p_port, TO_250ms);
7473 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7476 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7482 /*---------------------------------------------------------------------
7484 * Function: FPT_Wait
7486 * Description: Wait the desired delay.
7488 *---------------------------------------------------------------------*/
7490 static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
7492 unsigned char old_timer;
7493 unsigned char green_flag;
7495 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7497 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7498 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7500 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7501 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7502 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
7505 WR_HARPOON(p_port+hp_portctrl_0,
7506 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7508 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7510 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7513 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7517 WR_HARPOON(p_port+hp_portctrl_0,
7518 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7520 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7521 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
7523 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7525 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7529 /*---------------------------------------------------------------------
7531 * Function: Enable/Disable Write to EEPROM
7533 * Description: The EEPROM must first be enabled for writes
7534 * A total of 9 clocks are needed.
7536 *---------------------------------------------------------------------*/
7538 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
7540 unsigned char ee_value;
7542 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7546 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7551 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7553 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7554 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7558 /*---------------------------------------------------------------------
7560 * Function: Write EEPROM
7562 * Description: Write a word to the EEPROM at the specified
7565 *---------------------------------------------------------------------*/
7567 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
7570 unsigned char ee_value;
7573 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7578 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7581 ee_value |= (SEE_MS + SEE_CS);
7583 for(i = 0x8000; i != 0; i>>=1) {
7588 ee_value &= ~SEE_DO;
7590 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7591 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7592 ee_value |= SEE_CLK; /* Clock data! */
7593 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7594 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7595 ee_value &= ~SEE_CLK;
7596 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7597 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7599 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7600 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7602 FPT_Wait(p_port, TO_10ms);
7604 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7605 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7606 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7609 /*---------------------------------------------------------------------
7611 * Function: Read EEPROM
7613 * Description: Read a word from the EEPROM at the desired
7616 *---------------------------------------------------------------------*/
7618 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
7620 unsigned short i, ee_data1, ee_data2;
7623 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7626 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7628 if(ee_data1 == ee_data2)
7631 ee_data1 = ee_data2;
7639 /*---------------------------------------------------------------------
7641 * Function: Read EEPROM Original
7643 * Description: Read a word from the EEPROM at the desired
7646 *---------------------------------------------------------------------*/
7648 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
7651 unsigned char ee_value;
7652 unsigned short i, ee_data;
7654 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7658 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7661 ee_value |= (SEE_MS + SEE_CS);
7664 for(i = 1; i <= 16; i++) {
7666 ee_value |= SEE_CLK; /* Clock data! */
7667 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7668 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7669 ee_value &= ~SEE_CLK;
7670 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7671 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7675 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7679 ee_value &= ~(SEE_MS + SEE_CS);
7680 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7681 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7687 /*---------------------------------------------------------------------
7689 * Function: Send EE command and Address to the EEPROM
7691 * Description: Transfers the correct command and sends the address
7694 *---------------------------------------------------------------------*/
7696 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
7698 unsigned char ee_value;
7699 unsigned char narrow_flg;
7704 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7708 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7710 ee_value |= SEE_CS; /* Set CS to EEPROM */
7711 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7714 for(i = 0x04; i != 0; i>>=1) {
7719 ee_value &= ~SEE_DO;
7721 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7722 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7723 ee_value |= SEE_CLK; /* Clock data! */
7724 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7725 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7726 ee_value &= ~SEE_CLK;
7727 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7728 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7744 ee_value &= ~SEE_DO;
7746 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7747 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7748 ee_value |= SEE_CLK; /* Clock data! */
7749 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7750 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7751 ee_value &= ~SEE_CLK;
7752 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7753 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7759 static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7761 unsigned short crc=0;
7764 for (i=0; i < ID_STRING_LENGTH; i++)
7766 ch = (unsigned short) buffer[i];
7767 for(j=0; j < 8; j++)
7770 crc = (crc >> 1) ^ CRCMASK;
7779 static unsigned char FPT_CalcLrc(unsigned char buffer[])
7784 for(i = 0; i < ID_STRING_LENGTH; i++)
7792 The following inline definitions avoid type conflicts.
7795 static inline unsigned char
7796 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7798 return FlashPoint_ProbeHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7802 static inline FlashPoint_CardHandle_T
7803 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7805 return FlashPoint_HardwareResetHostAdapter((PSCCBMGR_INFO) FlashPointInfo);
7809 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7811 FlashPoint_ReleaseHostAdapter(CardHandle);
7816 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7818 FlashPoint_StartCCB(CardHandle, (PSCCB) CCB);
7823 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7825 FlashPoint_AbortCCB(CardHandle, (PSCCB) CCB);
7829 static inline boolean
7830 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7832 return FlashPoint_InterruptPending(CardHandle);
7837 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7839 return FlashPoint_HandleInterrupt(CardHandle);
7843 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7844 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7845 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7846 #define FlashPoint_StartCCB FlashPoint__StartCCB
7847 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7848 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7849 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7852 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7856 Define prototypes for the FlashPoint SCCB Manager Functions.
7859 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7860 extern FlashPoint_CardHandle_T
7861 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7862 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7863 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7864 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7865 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7866 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7869 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */