3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
5 This file contains the FlashPoint SCCB Manager from BusLogic's FlashPoint
6 Driver Developer's Kit, with minor modifications by Leonard N. Zubkoff for
7 Linux compatibility. It was provided by BusLogic in the form of 16 separate
8 source files, which would have unnecessarily cluttered the scsi directory, so
9 the individual files have been combined into this single file.
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
19 #include <linux/config.h>
22 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
36 #define CRCMASK 0xA001
40 #define FAILURE 0xFFFFFFFFL
51 #define BIT(x) ((unsigned char)(1<<(x))) /* single-bit mask in bit position x */
52 #define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
57 typedef void (*CALL_BK_FN)(struct sccb *);
60 struct sccb_mgr_info {
61 unsigned long si_baseaddr;
62 unsigned char si_present;
63 unsigned char si_intvect;
66 unsigned short si_fw_revision;
67 unsigned short si_per_targ_init_sync;
68 unsigned short si_per_targ_fast_nego;
69 unsigned short si_per_targ_ultra_nego;
70 unsigned short si_per_targ_no_disc;
71 unsigned short si_per_targ_wide_nego;
72 unsigned short si_flags;
73 unsigned char si_card_family;
74 unsigned char si_bustype;
75 unsigned char si_card_model[3];
76 unsigned char si_relative_cardnum;
77 unsigned char si_reserved[4];
78 unsigned long si_OS_reserved;
79 unsigned char si_XlatInfo[4];
80 unsigned long si_reserved2[5];
81 unsigned long si_secondary_range;
86 #define SCSI_PARITY_ENA 0x0001
87 #define LOW_BYTE_TERM 0x0010
88 #define HIGH_BYTE_TERM 0x0020
89 #define BUSTYPE_PCI 0x3
91 #define SUPPORT_16TAR_32LUN 0x0002
92 #define SOFT_RESET 0x0004
93 #define EXTENDED_TRANSLATION 0x0008
94 #define POST_ALL_UNDERRRUNS 0x0040
95 #define FLAG_SCAM_ENABLED 0x0080
96 #define FLAG_SCAM_LEVEL2 0x0100
101 #define HARPOON_FAMILY 0x02
105 /* SCCB struct used for both SCCB and UCB manager compiles!
106 * The UCB Manager treats the SCCB as it's 'native hardware structure'
112 unsigned char OperationCode;
113 unsigned char ControlByte;
114 unsigned char CdbLength;
115 unsigned char RequestSenseLength;
116 unsigned long DataLength;
117 unsigned long DataPointer;
118 unsigned char CcbRes[2];
119 unsigned char HostStatus;
120 unsigned char TargetStatus;
121 unsigned char TargID;
123 unsigned char Cdb[12];
124 unsigned char CcbRes1;
125 unsigned char Reserved1;
126 unsigned long Reserved2;
127 unsigned long SensePointer;
130 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
131 unsigned long SccbIOPort; /* Identifies board base port */
132 unsigned char SccbStatus;
133 unsigned char SCCBRes2;
134 unsigned short SccbOSFlags;
137 unsigned long Sccb_XferCnt; /* actual transfer count */
138 unsigned long Sccb_ATC;
139 unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */
140 unsigned long Sccb_res1;
141 unsigned short Sccb_MGRFlags;
142 unsigned short Sccb_sgseg;
143 unsigned char Sccb_scsimsg; /* identify msg for selection */
144 unsigned char Sccb_tag;
145 unsigned char Sccb_scsistat;
146 unsigned char Sccb_idmsg; /* image of last msg in */
147 struct sccb * Sccb_forwardlink;
148 struct sccb * Sccb_backlink;
149 unsigned long Sccb_savedATC;
150 unsigned char Save_Cdb[6];
151 unsigned char Save_CdbLen;
152 unsigned char Sccb_XferState;
153 unsigned long Sccb_SGoffset;
161 #define SCATTER_GATHER_COMMAND 0x02
162 #define RESIDUAL_COMMAND 0x03
163 #define RESIDUAL_SG_COMMAND 0x04
164 #define RESET_COMMAND 0x81
167 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
168 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
169 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
170 #define SCCB_DATA_XFER_IN 0x08 /* Read */
173 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
176 #define BUS_FREE_ST 0
178 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
179 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
180 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
181 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
183 #define DATA_OUT_ST 7
185 #define DISCONNECT_ST 9
189 #define F_HOST_XFER_DIR 0x01
190 #define F_ALL_XFERRED 0x02
191 #define F_SG_XFER 0x04
192 #define F_AUTO_SENSE 0x08
193 #define F_ODD_BALL_CNT 0x10
194 #define F_NO_DATA_YET 0x80
197 #define F_STATUSLOADED 0x01
198 #define F_DEV_SELECTED 0x04
201 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
202 #define SCCB_DATA_UNDER_RUN 0x0C
203 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
204 #define SCCB_DATA_OVER_RUN 0x12
205 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
207 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
208 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
209 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
215 #define SCCB_IN_PROCESS 0x00
216 #define SCCB_SUCCESS 0x01
217 #define SCCB_ABORT 0x02
218 #define SCCB_ERROR 0x04
222 #define ORION_FW_REV 3110
226 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
228 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
231 #define MAX_SCSI_TAR 16
233 #define LUN_MASK 0x1f
235 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
237 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
240 #define RD_HARPOON(ioport) inb((u32)ioport)
241 #define RDW_HARPOON(ioport) inw((u32)ioport)
242 #define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
243 #define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
244 #define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
245 #define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
248 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
249 #define SYNC_TRYING BIT(6)
250 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
252 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
253 #define WIDE_ENABLED BIT(4)
254 #define WIDE_NEGOCIATED BIT(5)
256 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
257 #define TAG_Q_TRYING BIT(2)
258 #define TAG_Q_REJECT BIT(3)
260 #define TAR_ALLOW_DISC BIT(0)
263 #define EE_SYNC_MASK (BIT(0)+BIT(1))
264 #define EE_SYNC_5MB BIT(0)
265 #define EE_SYNC_10MB BIT(1)
266 #define EE_SYNC_20MB (BIT(0)+BIT(1))
268 #define EE_WIDE_SCSI BIT(7)
273 struct sccb_mgr_tar_info {
275 struct sccb * TarSelQ_Head;
276 struct sccb * TarSelQ_Tail;
277 unsigned char TarLUN_CA; /*Contingent Allgiance */
278 unsigned char TarTagQ_Cnt;
279 unsigned char TarSelQ_Cnt;
280 unsigned char TarStatus;
281 unsigned char TarEEValue;
282 unsigned char TarSyncCtrl;
283 unsigned char TarReserved[2]; /* for alignment */
284 unsigned char LunDiscQ_Idx[MAX_LUN];
285 unsigned char TarLUNBusy[MAX_LUN];
289 unsigned char niModel; /* Model No. of card */
290 unsigned char niCardNo; /* Card no. */
291 unsigned long niBaseAddr; /* Port Address of card */
292 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
293 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
294 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
295 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
296 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
297 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
308 struct sccb * currentSCCB;
309 struct sccb_mgr_info * cardInfo;
311 unsigned long ioPort;
313 unsigned short cmdCounter;
314 unsigned char discQCount;
315 unsigned char tagQ_Lst;
316 unsigned char cardIndex;
317 unsigned char scanIndex;
318 unsigned char globalFlags;
320 struct nvram_info * pNvRamInfo;
321 struct sccb * discQ_Tbl[QUEUE_DEPTH];
327 #define F_TAG_STARTED 0x01
328 #define F_CONLUN_IO 0x02
329 #define F_DO_RENEGO 0x04
330 #define F_NO_FILTER 0x08
331 #define F_GREEN_PC 0x10
332 #define F_HOST_XFER_ACT 0x20
333 #define F_NEW_SCCB_CMD 0x40
334 #define F_UPDATE_EEPROM 0x80
337 #define ID_STRING_LENGTH 32
338 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
341 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
343 #define ASSIGN_ID 0x00
344 #define SET_P_FLAG 0x01
345 #define CFG_CMPLT 0x03
346 #define DOM_MSTR 0x0F
347 #define SYNC_PTRN 0x1F
351 #define MISC_CODE 0x14
352 #define CLR_P_FLAG 0x18
356 #define INIT_SELTD 0x01
357 #define LEVEL2_TAR 0x02
360 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
361 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
362 CLR_PRIORITY,NO_ID_AVAIL };
364 typedef struct SCCBscam_info {
366 unsigned char id_string[ID_STRING_LENGTH];
367 enum scam_id_st state;
372 #define SCSI_REQUEST_SENSE 0x03
373 #define SCSI_READ 0x08
374 #define SCSI_WRITE 0x0A
375 #define SCSI_START_STOP_UNIT 0x1B
376 #define SCSI_READ_EXTENDED 0x28
377 #define SCSI_WRITE_EXTENDED 0x2A
378 #define SCSI_WRITE_AND_VERIFY 0x2E
384 #define SSQ_FULL 0x28
389 #define SMCMD_COMP 0x00
391 #define SMSAVE_DATA_PTR 0x02
392 #define SMREST_DATA_PTR 0x03
395 #define SMREJECT 0x07
397 #define SMPARITY 0x09
398 #define SMDEV_RESET 0x0C
399 #define SMABORT_TAG 0x0D
400 #define SMINIT_RECOVERY 0x0F
401 #define SMREL_RECOVERY 0x10
404 #define DISC_PRIV 0x40
411 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
420 #define SIX_BYTE_CMD 0x06
421 #define TWELVE_BYTE_CMD 0x0C
424 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
427 #define EEPROM_WD_CNT 256
429 #define EEPROM_CHECK_SUM 0
430 #define FW_SIGNATURE 2
431 #define MODEL_NUMB_0 4
432 #define MODEL_NUMB_2 6
433 #define MODEL_NUMB_4 8
434 #define SYSTEM_CONFIG 16
435 #define SCSI_CONFIG 17
436 #define BIOS_CONFIG 18
437 #define SCAM_CONFIG 20
438 #define ADAPTER_SCSI_ID 24
441 #define IGNORE_B_SCAN 32
442 #define SEND_START_ENA 34
443 #define DEVICE_ENABLE 36
445 #define SYNC_RATE_TBL 38
446 #define SYNC_RATE_TBL01 38
447 #define SYNC_RATE_TBL23 40
448 #define SYNC_RATE_TBL45 42
449 #define SYNC_RATE_TBL67 44
450 #define SYNC_RATE_TBL89 46
451 #define SYNC_RATE_TBLab 48
452 #define SYNC_RATE_TBLcd 50
453 #define SYNC_RATE_TBLef 52
457 #define EE_SCAMBASE 256
461 #define SCAM_ENABLED BIT(2)
462 #define SCAM_LEVEL2 BIT(3)
465 #define RENEGO_ENA BITW(10)
466 #define CONNIO_ENA BITW(11)
467 #define GREEN_PC_ENA BITW(12)
470 #define AUTO_RATE_00 00
471 #define AUTO_RATE_05 01
472 #define AUTO_RATE_10 02
473 #define AUTO_RATE_20 03
475 #define WIDE_NEGO_BIT BIT(7)
476 #define DISC_ENABLE_BIT BIT(6)
480 #define hp_vendor_id_0 0x00 /* LSB */
481 #define ORION_VEND_0 0x4B
483 #define hp_vendor_id_1 0x01 /* MSB */
484 #define ORION_VEND_1 0x10
486 #define hp_device_id_0 0x02 /* LSB */
487 #define ORION_DEV_0 0x30
489 #define hp_device_id_1 0x03 /* MSB */
490 #define ORION_DEV_1 0x81
492 /* Sub Vendor ID and Sub Device ID only available in
493 Harpoon Version 2 and higher */
495 #define hp_sub_device_id_0 0x06 /* LSB */
499 #define hp_semaphore 0x0C
500 #define SCCB_MGR_ACTIVE BIT(0)
501 #define TICKLE_ME BIT(1)
502 #define SCCB_MGR_PRESENT BIT(3)
503 #define BIOS_IN_USE BIT(4)
507 #define hp_sys_ctrl 0x0F
509 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
510 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
511 #define HALT_MACH BIT(3) /*Halt State Machine */
512 #define HARD_ABORT BIT(4) /*Hard Abort */
522 #define hp_host_blk_cnt 0x13
524 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
526 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
530 #define hp_int_mask 0x17
532 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
533 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
536 #define hp_xfer_cnt_lo 0x18
537 #define hp_xfer_cnt_hi 0x1A
538 #define hp_xfer_cmd 0x1B
540 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
541 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
544 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
546 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
548 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
550 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
551 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
553 #define hp_host_addr_lo 0x1C
554 #define hp_host_addr_hmi 0x1E
556 #define hp_ee_ctrl 0x22
558 #define EXT_ARB_ACK BIT(7)
559 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
560 #define SEE_MS BIT(5)
561 #define SEE_CS BIT(3)
562 #define SEE_CLK BIT(2)
563 #define SEE_DO BIT(1)
564 #define SEE_DI BIT(0)
567 #define EE_WRITE 0x05
569 #define EWEN_ADDR 0x03C0
571 #define EWDS_ADDR 0x0000
579 #define hp_bm_ctrl 0x26
581 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
582 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
583 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
584 #define FAST_SINGLE BIT(6) /*?? */
586 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
589 #define hp_sg_addr 0x28
590 #define hp_page_ctrl 0x29
592 #define SCATTER_EN BIT(0)
593 #define SGRAM_ARAM BIT(1)
594 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
595 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
600 #define hp_pci_stat_cfg 0x2D
602 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
611 #define hp_rev_num 0x33
614 #define hp_stack_data 0x34
615 #define hp_stack_addr 0x35
617 #define hp_ext_status 0x36
619 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
620 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
621 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
622 #define CMD_ABORTED BIT(4) /*Command aborted */
623 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
624 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
625 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
626 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
627 BM_PARITY_ERR | PIO_OVERRUN)
629 #define hp_int_status 0x37
631 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
632 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
633 #define INT_ASSERTED BIT(5) /* */
636 #define hp_fifo_cnt 0x38
641 #define hp_intena 0x40
643 #define RESET BITW(7)
644 #define PROG_HLT BITW(6)
645 #define PARITY BITW(5)
648 #define SCAM_SEL BITW(2)
650 #define TIMEOUT BITW(0)
651 #define BUS_FREE BITW(15)
652 #define XFER_CNT_0 BITW(14)
653 #define PHASE BITW(13)
654 #define IUNKWN BITW(12)
655 #define ICMD_COMP BITW(11)
656 #define ITICKLE BITW(10)
657 #define IDO_STRT BITW(9)
658 #define ITAR_DISC BITW(8)
659 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
660 #define CLR_ALL_INT 0xFFFF
661 #define CLR_ALL_INT_1 0xFF00
663 #define hp_intstat 0x42
665 #define hp_scsisig 0x44
667 #define SCSI_SEL BIT(7)
668 #define SCSI_BSY BIT(6)
669 #define SCSI_REQ BIT(5)
670 #define SCSI_ACK BIT(4)
671 #define SCSI_ATN BIT(3)
672 #define SCSI_CD BIT(2)
673 #define SCSI_MSG BIT(1)
674 #define SCSI_IOBIT BIT(0)
676 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
677 #define S_MSGO_PH (BIT(2)+BIT(1) )
678 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
679 #define S_DATAI_PH ( BIT(0))
680 #define S_DATAO_PH 0x00
681 #define S_ILL_PH ( BIT(1) )
683 #define hp_scsictrl_0 0x45
685 #define SEL_TAR BIT(6)
686 #define ENA_ATN BIT(4)
687 #define ENA_RESEL BIT(2)
688 #define SCSI_RST BIT(1)
689 #define ENA_SCAM_SEL BIT(0)
693 #define hp_portctrl_0 0x46
695 #define SCSI_PORT BIT(7)
696 #define SCSI_INBIT BIT(6)
697 #define DMA_PORT BIT(5)
698 #define DMA_RD BIT(4)
699 #define HOST_PORT BIT(3)
700 #define HOST_WRT BIT(2)
701 #define SCSI_BUS_EN BIT(1)
702 #define START_TO BIT(0)
704 #define hp_scsireset 0x47
706 #define SCSI_INI BIT(6)
707 #define SCAM_EN BIT(5)
708 #define DMA_RESET BIT(3)
709 #define HPSCSI_RESET BIT(2)
710 #define PROG_RESET BIT(1)
711 #define FIFO_CLR BIT(0)
713 #define hp_xfercnt_0 0x48
714 #define hp_xfercnt_2 0x4A
716 #define hp_fifodata_0 0x4C
717 #define hp_addstat 0x4E
719 #define SCAM_TIMER BIT(7)
720 #define SCSI_MODE8 BIT(3)
721 #define SCSI_PAR_ERR BIT(0)
723 #define hp_prgmcnt_0 0x4F
726 #define hp_selfid_0 0x50
727 #define hp_selfid_1 0x51
728 #define hp_arb_id 0x52
731 #define hp_select_id 0x53
734 #define hp_synctarg_base 0x54
735 #define hp_synctarg_12 0x54
736 #define hp_synctarg_13 0x55
737 #define hp_synctarg_14 0x56
738 #define hp_synctarg_15 0x57
740 #define hp_synctarg_8 0x58
741 #define hp_synctarg_9 0x59
742 #define hp_synctarg_10 0x5A
743 #define hp_synctarg_11 0x5B
745 #define hp_synctarg_4 0x5C
746 #define hp_synctarg_5 0x5D
747 #define hp_synctarg_6 0x5E
748 #define hp_synctarg_7 0x5F
750 #define hp_synctarg_0 0x60
751 #define hp_synctarg_1 0x61
752 #define hp_synctarg_2 0x62
753 #define hp_synctarg_3 0x63
755 #define NARROW_SCSI BIT(4)
756 #define DEFAULT_OFFSET 0x0F
758 #define hp_autostart_0 0x64
759 #define hp_autostart_1 0x65
760 #define hp_autostart_3 0x67
764 #define AUTO_IMMED BIT(5)
765 #define SELECT BIT(6)
766 #define END_DATA (BIT(7)+BIT(6))
768 #define hp_gp_reg_0 0x68
769 #define hp_gp_reg_1 0x69
770 #define hp_gp_reg_3 0x6B
772 #define hp_seltimeout 0x6C
775 #define TO_4ms 0x67 /* 3.9959ms */
777 #define TO_5ms 0x03 /* 4.9152ms */
778 #define TO_10ms 0x07 /* 11.xxxms */
779 #define TO_250ms 0x99 /* 250.68ms */
780 #define TO_290ms 0xB1 /* 289.99ms */
782 #define hp_clkctrl_0 0x6D
784 #define PWR_DWN BIT(6)
785 #define ACTdeassert BIT(4)
786 #define CLK_40MHZ (BIT(1) + BIT(0))
788 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
790 #define hp_fiforead 0x6E
791 #define hp_fifowrite 0x6F
793 #define hp_offsetctr 0x70
794 #define hp_xferstat 0x71
796 #define FIFO_EMPTY BIT(6)
798 #define hp_portctrl_1 0x72
800 #define CHK_SCSI_P BIT(3)
801 #define HOST_MODE8 BIT(0)
803 #define hp_xfer_pad 0x73
805 #define ID_UNLOCK BIT(3)
807 #define hp_scsidata_0 0x74
808 #define hp_scsidata_1 0x75
812 #define hp_aramBase 0x80
813 #define BIOS_DATA_OFFSET 0x60
814 #define BIOS_RELATIVE_CARD 0x64
819 #define AR3 (BITW(9) + BITW(8))
820 #define SDATA BITW(10)
823 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
825 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
829 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
831 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
834 #define ADATA_OUT 0x00
835 #define ADATA_IN BITW(8)
836 #define ACOMMAND BITW(10)
837 #define ASTATUS (BITW(10)+BITW(8))
838 #define AMSG_OUT (BITW(10)+BITW(9))
839 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
842 #define BRH_OP BITW(13) /* Branch */
846 #define EQUAL BITW(8)
847 #define NOT_EQ BITW(9)
849 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
852 #define FIFO_0 BITW(10)
855 #define MPM_OP BITW(15) /* Match phase and move data */
858 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
861 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
866 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
876 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
878 #define SSI_OP (BITW(15)+BITW(11))
881 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
882 #define SSI_IDO_STRT (IDO_STRT >> 8)
884 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
885 #define SSI_ITICKLE (ITICKLE >> 8)
887 #define SSI_IUNKWN (IUNKWN >> 8)
888 #define SSI_INO_CC (IUNKWN >> 8)
889 #define SSI_IRFAIL (IUNKWN >> 8)
892 #define NP 0x10 /*Next Phase */
893 #define NTCMD 0x02 /*Non- Tagged Command start */
894 #define CMDPZ 0x04 /*Command phase */
895 #define DINT 0x12 /*Data Out/In interrupt */
896 #define DI 0x13 /*Data Out */
897 #define DC 0x19 /*Disconnect Message */
898 #define ST 0x1D /*Status Phase */
899 #define UNKNWN 0x24 /*Unknown bus action */
900 #define CC 0x25 /*Command Completion failure */
901 #define TICK 0x26 /*New target reselected us. */
902 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
905 #define ID_MSG_STRT hp_aramBase + 0x00
906 #define NON_TAG_ID_MSG hp_aramBase + 0x06
907 #define CMD_STRT hp_aramBase + 0x08
908 #define SYNC_MSGS hp_aramBase + 0x08
914 #define TAG_STRT 0x00
915 #define DISCONNECT_START 0x10/2
916 #define END_DATA_START 0x14/2
917 #define CMD_ONLY_STRT CMDPZ/2
918 #define SELCHK_STRT SELCHK/2
928 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
929 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
931 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
933 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
935 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
936 WR_HARP32(port,hp_xfercnt_0,count),\
937 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
939 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
941 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
942 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
945 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
946 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
950 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
951 WR_HARPOON(port+hp_scsireset, 0x00))
953 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
954 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
956 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
957 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
959 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
960 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
962 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
963 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
968 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
969 static void FPT_ssel(unsigned long port, unsigned char p_card);
970 static void FPT_sres(unsigned long port, unsigned char p_card, struct sccb_card * pCurrCard);
971 static void FPT_shandem(unsigned long port, unsigned char p_card,struct sccb * pCurrSCCB);
972 static void FPT_stsyncn(unsigned long port, unsigned char p_card);
973 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
974 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
975 struct sccb_mgr_tar_info * currTar_Info);
976 static void FPT_sresb(unsigned long port, unsigned char p_card);
977 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
978 static void FPT_schkdd(unsigned long port, unsigned char p_card);
979 static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
980 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
981 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
983 static void FPT_SendMsg(unsigned long port, unsigned char message);
984 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
985 unsigned char error_code);
987 static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card);
988 static void FPT_RNVRamData(struct nvram_info * pNvRamInfo);
990 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
991 static void FPT_stwidn(unsigned long port, unsigned char p_card);
992 static void FPT_siwidr(unsigned long port, unsigned char width);
995 static void FPT_queueSelectFail(struct sccb_card * pCurrCard, unsigned char p_card);
996 static void FPT_queueDisconnect(struct sccb * p_SCCB, unsigned char p_card);
997 static void FPT_queueCmdComplete(struct sccb_card * pCurrCard, struct sccb * p_SCCB,
998 unsigned char p_card);
999 static void FPT_queueSearchSelect(struct sccb_card * pCurrCard, unsigned char p_card);
1000 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1001 static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char card);
1002 static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card);
1003 static void FPT_utilUpdateResidual(struct sccb * p_SCCB);
1004 static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
1005 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
1008 static void FPT_Wait1Second(unsigned long p_port);
1009 static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1010 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1011 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1012 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1013 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1014 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
1018 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1019 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1020 static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1021 static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1022 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1023 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1024 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
1026 static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1027 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1028 static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
1033 static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1034 static void FPT_BusMasterInit(unsigned long p_port);
1035 static void FPT_DiagEEPROM(unsigned long p_port);
1040 static void FPT_dataXferProcessor(unsigned long port, struct sccb_card * pCurrCard);
1041 static void FPT_busMstrSGDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1042 static void FPT_busMstrDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1043 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB);
1044 static void FPT_hostDataXferRestart(struct sccb * currSCCB);
1047 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
1048 struct sccb_card * pCurrCard, unsigned short p_int);
1050 static void FPT_SccbMgrTableInitAll(void);
1051 static void FPT_SccbMgrTableInitCard(struct sccb_card * pCurrCard, unsigned char p_card);
1052 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
1056 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
1058 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1059 static void FPT_scbusf(unsigned long p_port);
1060 static void FPT_scsel(unsigned long p_port);
1061 static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1062 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1063 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1064 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1065 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1066 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
1067 static unsigned char FPT_scvalq(unsigned char p_quintet);
1068 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1069 static void FPT_scwtsel(unsigned long p_port);
1070 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1071 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
1072 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
1075 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1076 static void FPT_autoLoadDefaultMap(unsigned long p_port);
1081 static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1082 static struct sccb_card FPT_BL_Card[MAX_CARDS] = { { 0 } };
1083 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1084 static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1087 static unsigned char FPT_mbCards = 0;
1088 static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1089 ' ', 'B', 'T', '-', '9', '3', '0', \
1090 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1091 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1093 static unsigned short FPT_default_intena = 0;
1096 static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
1099 /*---------------------------------------------------------------------
1101 * Function: FlashPoint_ProbeHostAdapter
1103 * Description: Setup and/or Search for cards and return info to caller.
1105 *---------------------------------------------------------------------*/
1107 static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info * pCardInfo)
1109 static unsigned char first_time = 1;
1111 unsigned char i,j,id,ScamFlg;
1112 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
1113 unsigned long ioport;
1114 struct nvram_info * pCurrNvRam;
1116 ioport = pCardInfo->si_baseaddr;
1119 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1120 return((int)FAILURE);
1122 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1123 return((int)FAILURE);
1125 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1126 return((int)FAILURE);
1128 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1129 return((int)FAILURE);
1132 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1134 /* For new Harpoon then check for sub_device ID LSB
1135 the bits(0-3) must be all ZERO for compatible with
1136 current version of SCCBMgr, else skip this Harpoon
1139 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1140 return((int)FAILURE);
1145 FPT_SccbMgrTableInitAll();
1150 if(FPT_RdStack(ioport, 0) != 0x00) {
1151 if(FPT_ChkIfChipInitialized(ioport) == 0)
1154 WR_HARPOON(ioport+hp_semaphore, 0x00);
1155 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1156 FPT_DiagEEPROM(ioport);
1160 if(FPT_mbCards < MAX_MB_CARDS) {
1161 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1163 pCurrNvRam->niBaseAddr = ioport;
1164 FPT_RNVRamData(pCurrNvRam);
1166 return((int) FAILURE);
1171 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1172 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1175 pCardInfo->si_id = pCurrNvRam->niAdapId;
1177 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1178 (unsigned char)0x0FF);
1180 pCardInfo->si_lun = 0x00;
1181 pCardInfo->si_fw_revision = ORION_FW_REV;
1188 for (id = 0; id < (16/2); id++) {
1191 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1192 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1193 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1195 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1197 for (i = 0; i < 2; temp >>=8,i++) {
1206 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1207 temp6 |= 0x8000; /* Fall through */
1208 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1209 temp5 |= 0x8000; /* Fall through */
1210 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1211 temp2 |= 0x8000; /* Fall through */
1212 case AUTO_RATE_00: /* Asynchronous */
1216 if (temp & DISC_ENABLE_BIT)
1219 if (temp & WIDE_NEGO_BIT)
1225 pCardInfo->si_per_targ_init_sync = temp2;
1226 pCardInfo->si_per_targ_no_disc = temp3;
1227 pCardInfo->si_per_targ_wide_nego = temp4;
1228 pCardInfo->si_per_targ_fast_nego = temp5;
1229 pCardInfo->si_per_targ_ultra_nego = temp6;
1232 i = pCurrNvRam->niSysConf;
1234 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1237 ScamFlg = pCurrNvRam->niScamConf;
1239 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1241 pCardInfo->si_flags = 0x0000;
1244 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1247 pCardInfo->si_flags |= SOFT_RESET;
1250 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1252 if (ScamFlg & SCAM_ENABLED)
1253 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1255 if (ScamFlg & SCAM_LEVEL2)
1256 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1258 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1260 j |= SCSI_TERM_ENA_L;
1262 WR_HARPOON(ioport+hp_bm_ctrl, j );
1264 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1266 j |= SCSI_TERM_ENA_H;
1268 WR_HARPOON(ioport+hp_ee_ctrl, j );
1270 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1272 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1274 pCardInfo->si_card_family = HARPOON_FAMILY;
1275 pCardInfo->si_bustype = BUSTYPE_PCI;
1278 pCardInfo->si_card_model[0] = '9';
1279 switch(pCurrNvRam->niModel & 0x0f){
1281 pCardInfo->si_card_model[1] = '3';
1282 pCardInfo->si_card_model[2] = '0';
1285 pCardInfo->si_card_model[1] = '5';
1286 pCardInfo->si_card_model[2] = '0';
1289 pCardInfo->si_card_model[1] = '3';
1290 pCardInfo->si_card_model[2] = '2';
1293 pCardInfo->si_card_model[1] = '5';
1294 pCardInfo->si_card_model[2] = '2';
1298 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1299 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1300 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1302 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1303 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1306 if (pCardInfo->si_card_model[1] == '3')
1308 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1309 pCardInfo->si_flags |= LOW_BYTE_TERM;
1311 else if (pCardInfo->si_card_model[2] == '0')
1313 temp = RD_HARPOON(ioport+hp_xfer_pad);
1314 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1315 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1316 pCardInfo->si_flags |= LOW_BYTE_TERM;
1317 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1318 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1319 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1320 WR_HARPOON(ioport+hp_xfer_pad, temp);
1324 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1325 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1326 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1327 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1329 for (i = 0; i < 8; i++)
1332 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1334 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1335 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1337 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1338 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1339 if (!(temp3 & BIT(7)))
1340 pCardInfo->si_flags |= LOW_BYTE_TERM;
1341 if (!(temp3 & BIT(6)))
1342 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1346 ARAM_ACCESS(ioport);
1348 for ( i = 0; i < 4; i++ ) {
1350 pCardInfo->si_XlatInfo[i] =
1351 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1354 /* return with -1 if no sort, else return with
1355 logical card number sorted by BIOS (zero-based) */
1357 pCardInfo->si_relative_cardnum =
1358 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1360 SGRAM_ACCESS(ioport);
1362 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1363 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1364 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1365 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1366 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1367 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1368 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1369 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1371 pCardInfo->si_present = 0x01;
1377 /*---------------------------------------------------------------------
1379 * Function: FlashPoint_HardwareResetHostAdapter
1381 * Description: Setup adapter for normal operation (hard reset).
1383 *---------------------------------------------------------------------*/
1385 static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info * pCardInfo)
1387 struct sccb_card * CurrCard = NULL;
1388 struct nvram_info * pCurrNvRam;
1389 unsigned char i,j,thisCard, ScamFlg;
1390 unsigned short temp,sync_bit_map,id;
1391 unsigned long ioport;
1393 ioport = pCardInfo->si_baseaddr;
1395 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1397 if (thisCard == MAX_CARDS) {
1402 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1404 CurrCard = &FPT_BL_Card[thisCard];
1405 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1409 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1411 FPT_BL_Card[thisCard].ioPort = ioport;
1412 CurrCard = &FPT_BL_Card[thisCard];
1415 for(i = 0; i < FPT_mbCards; i++){
1416 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1417 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1419 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1420 CurrCard->cardIndex = thisCard;
1421 CurrCard->cardInfo = pCardInfo;
1427 pCurrNvRam = CurrCard->pNvRamInfo;
1430 ScamFlg = pCurrNvRam->niScamConf;
1433 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1437 FPT_BusMasterInit(ioport);
1438 FPT_XbowInit(ioport, ScamFlg);
1440 FPT_autoLoadDefaultMap(ioport);
1443 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1445 WR_HARPOON(ioport+hp_selfid_0, id);
1446 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1447 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1448 CurrCard->ourId = pCardInfo->si_id;
1450 i = (unsigned char) pCardInfo->si_flags;
1451 if (i & SCSI_PARITY_ENA)
1452 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1454 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1455 if (i & LOW_BYTE_TERM)
1456 j |= SCSI_TERM_ENA_L;
1457 WR_HARPOON(ioport+hp_bm_ctrl, j);
1459 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1460 if (i & HIGH_BYTE_TERM)
1461 j |= SCSI_TERM_ENA_H;
1462 WR_HARPOON(ioport+hp_ee_ctrl, j );
1465 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1467 FPT_sresb(ioport,thisCard);
1469 FPT_scini(thisCard, pCardInfo->si_id, 0);
1474 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1475 CurrCard->globalFlags |= F_NO_FILTER;
1478 if(pCurrNvRam->niSysConf & 0x10)
1479 CurrCard->globalFlags |= F_GREEN_PC;
1482 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1483 CurrCard->globalFlags |= F_GREEN_PC;
1486 /* Set global flag to indicate Re-Negotiation to be done on all
1489 if(pCurrNvRam->niScsiConf & 0x04)
1490 CurrCard->globalFlags |= F_DO_RENEGO;
1493 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1494 CurrCard->globalFlags |= F_DO_RENEGO;
1498 if(pCurrNvRam->niScsiConf & 0x08)
1499 CurrCard->globalFlags |= F_CONLUN_IO;
1502 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1503 CurrCard->globalFlags |= F_CONLUN_IO;
1507 temp = pCardInfo->si_per_targ_no_disc;
1509 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1512 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1515 sync_bit_map = 0x0001;
1517 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1520 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1521 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1522 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1524 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1526 for (i = 0; i < 2; temp >>=8,i++) {
1528 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1530 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
1534 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1535 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1536 (unsigned char)(temp & ~EE_SYNC_MASK);
1539 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1542 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1544 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1548 else { /* NARROW SCSI */
1549 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1560 WR_HARPOON((ioport+hp_semaphore),
1561 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1563 return((unsigned long)CurrCard);
1566 static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
1569 unsigned long portBase;
1570 unsigned long regOffset;
1571 unsigned long scamData;
1572 unsigned long *pScamTbl;
1573 struct nvram_info * pCurrNvRam;
1575 pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
1578 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1579 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1580 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1581 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1582 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1584 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1585 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
1587 portBase = pCurrNvRam->niBaseAddr;
1589 for(i = 0; i < MAX_SCSI_TAR; i++){
1590 regOffset = hp_aramBase + 64 + i*4;
1591 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
1592 scamData = *pScamTbl;
1593 WR_HARP32(portBase, regOffset, scamData);
1597 FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0);
1602 static void FPT_RNVRamData(struct nvram_info * pNvRamInfo)
1605 unsigned long portBase;
1606 unsigned long regOffset;
1607 unsigned long scamData;
1608 unsigned long *pScamTbl;
1610 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1611 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1612 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1613 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1614 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1616 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1617 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
1619 portBase = pNvRamInfo->niBaseAddr;
1621 for(i = 0; i < MAX_SCSI_TAR; i++){
1622 regOffset = hp_aramBase + 64 + i*4;
1623 RD_HARP32(portBase, regOffset, scamData);
1624 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
1625 *pScamTbl = scamData;
1630 static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
1632 WR_HARPOON(portBase + hp_stack_addr, index);
1633 return(RD_HARPOON(portBase + hp_stack_data));
1636 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
1638 WR_HARPOON(portBase + hp_stack_addr, index);
1639 WR_HARPOON(portBase + hp_stack_data, data);
1643 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
1645 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1647 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1650 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1651 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1656 /*---------------------------------------------------------------------
1658 * Function: FlashPoint_StartCCB
1660 * Description: Start a command pointed to by p_Sccb. When the
1661 * command is completed it will be returned via the
1662 * callback function.
1664 *---------------------------------------------------------------------*/
1665 static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
1667 unsigned long ioport;
1668 unsigned char thisCard, lun;
1669 struct sccb * pSaveSccb;
1670 CALL_BK_FN callback;
1672 thisCard = ((struct sccb_card *) pCurrCard)->cardIndex;
1673 ioport = ((struct sccb_card *) pCurrCard)->ioPort;
1675 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1678 p_Sccb->HostStatus = SCCB_COMPLETE;
1679 p_Sccb->SccbStatus = SCCB_ERROR;
1680 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1687 FPT_sinits(p_Sccb,thisCard);
1690 if (!((struct sccb_card *) pCurrCard)->cmdCounter)
1692 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1693 | SCCB_MGR_ACTIVE));
1695 if (((struct sccb_card *) pCurrCard)->globalFlags & F_GREEN_PC)
1697 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1698 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1702 ((struct sccb_card *)pCurrCard)->cmdCounter++;
1704 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1706 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1708 if(p_Sccb->OperationCode == RESET_COMMAND)
1710 pSaveSccb = ((struct sccb_card *) pCurrCard)->currentSCCB;
1711 ((struct sccb_card *) pCurrCard)->currentSCCB = p_Sccb;
1712 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1713 ((struct sccb_card *) pCurrCard)->currentSCCB = pSaveSccb;
1717 FPT_queueAddSccb(p_Sccb,thisCard);
1721 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1723 if(p_Sccb->OperationCode == RESET_COMMAND)
1725 pSaveSccb = ((struct sccb_card *) pCurrCard)->currentSCCB;
1726 ((struct sccb_card *) pCurrCard)->currentSCCB = p_Sccb;
1727 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1728 ((struct sccb_card *) pCurrCard)->currentSCCB = pSaveSccb;
1732 FPT_queueAddSccb(p_Sccb,thisCard);
1738 MDISABLE_INT(ioport);
1740 if((((struct sccb_card *) pCurrCard)->globalFlags & F_CONLUN_IO) &&
1741 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1745 if ((((struct sccb_card *) pCurrCard)->currentSCCB == NULL) &&
1746 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1747 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1750 ((struct sccb_card *) pCurrCard)->currentSCCB = p_Sccb;
1751 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1756 if(p_Sccb->OperationCode == RESET_COMMAND)
1758 pSaveSccb = ((struct sccb_card *) pCurrCard)->currentSCCB;
1759 ((struct sccb_card *) pCurrCard)->currentSCCB = p_Sccb;
1760 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1761 ((struct sccb_card *) pCurrCard)->currentSCCB = pSaveSccb;
1765 FPT_queueAddSccb(p_Sccb,thisCard);
1770 MENABLE_INT(ioport);
1776 /*---------------------------------------------------------------------
1778 * Function: FlashPoint_AbortCCB
1780 * Description: Abort the command pointed to by p_Sccb. When the
1781 * command is completed it will be returned via the
1782 * callback function.
1784 *---------------------------------------------------------------------*/
1785 static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
1787 unsigned long ioport;
1789 unsigned char thisCard;
1790 CALL_BK_FN callback;
1792 struct sccb * pSaveSCCB;
1793 struct sccb_mgr_tar_info * currTar_Info;
1796 ioport = ((struct sccb_card *) pCurrCard)->ioPort;
1798 thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1800 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1803 if (FPT_queueFindSccb(p_Sccb,thisCard))
1806 ((struct sccb_card *)pCurrCard)->cmdCounter--;
1808 if (!((struct sccb_card *)pCurrCard)->cmdCounter)
1809 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1810 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1812 p_Sccb->SccbStatus = SCCB_ABORT;
1813 callback = p_Sccb->SccbCallback;
1821 if (((struct sccb_card *)pCurrCard)->currentSCCB == p_Sccb)
1823 p_Sccb->SccbStatus = SCCB_ABORT;
1831 TID = p_Sccb->TargID;
1834 if(p_Sccb->Sccb_tag)
1836 MDISABLE_INT(ioport);
1837 if (((struct sccb_card *) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1839 p_Sccb->SccbStatus = SCCB_ABORT;
1840 p_Sccb->Sccb_scsistat = ABORT_ST;
1841 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1843 if(((struct sccb_card *) pCurrCard)->currentSCCB == NULL)
1845 ((struct sccb_card *) pCurrCard)->currentSCCB = p_Sccb;
1846 FPT_ssel(ioport, thisCard);
1850 pSaveSCCB = ((struct sccb_card *) pCurrCard)->currentSCCB;
1851 ((struct sccb_card *) pCurrCard)->currentSCCB = p_Sccb;
1852 FPT_queueSelectFail((struct sccb_card *) pCurrCard, thisCard);
1853 ((struct sccb_card *) pCurrCard)->currentSCCB = pSaveSCCB;
1856 MENABLE_INT(ioport);
1861 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1863 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1866 p_Sccb->SccbStatus = SCCB_ABORT;
1877 /*---------------------------------------------------------------------
1879 * Function: FlashPoint_InterruptPending
1881 * Description: Do a quick check to determine if there is a pending
1882 * interrupt for this card and disable the IRQ Pin if so.
1884 *---------------------------------------------------------------------*/
1885 static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
1887 unsigned long ioport;
1889 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1891 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1903 /*---------------------------------------------------------------------
1905 * Function: FlashPoint_HandleInterrupt
1907 * Description: This is our entry point when an interrupt is generated
1908 * by the card and the upper level driver passes it on to
1911 *---------------------------------------------------------------------*/
1912 static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
1914 struct sccb * currSCCB;
1915 unsigned char thisCard,result,bm_status, bm_int_st;
1916 unsigned short hp_int;
1917 unsigned char i, target;
1918 unsigned long ioport;
1920 thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1921 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1923 MDISABLE_INT(ioport);
1925 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1926 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
1930 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1932 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1936 currSCCB = ((struct sccb_card *)pCurrCard)->currentSCCB;
1938 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1939 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((struct sccb_card *)pCurrCard),hp_int);
1940 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1945 MENABLE_INT(ioport);
1951 else if (hp_int & ICMD_COMP) {
1953 if ( !(hp_int & BUS_FREE) ) {
1954 /* Wait for the BusFree before starting a new command. We
1955 must also check for being reselected since the BusFree
1956 may not show up if another device reselects us in 1.5us or
1957 less. SRR Wednesday, 3/8/1995.
1959 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1962 if (((struct sccb_card *)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1964 FPT_phaseChkFifo(ioport, thisCard);
1966 /* WRW_HARPOON((ioport+hp_intstat),
1967 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1970 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1972 FPT_autoCmdCmplt(ioport,thisCard);
1977 else if (hp_int & ITAR_DISC)
1980 if (((struct sccb_card *)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1982 FPT_phaseChkFifo(ioport, thisCard);
1986 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1988 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
1989 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1991 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1994 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1995 FPT_queueDisconnect(currSCCB,thisCard);
1997 /* Wait for the BusFree before starting a new command. We
1998 must also check for being reselected since the BusFree
1999 may not show up if another device reselects us in 1.5us or
2000 less. SRR Wednesday, 3/8/1995.
2002 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2003 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2004 RD_HARPOON((ioport+hp_scsisig)) ==
2005 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2008 The additional loop exit condition above detects a timing problem
2009 with the revision D/E harpoon chips. The caller should reset the
2010 host adapter to recover when 0xFE is returned.
2012 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2014 MENABLE_INT(ioport);
2018 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2021 ((struct sccb_card *)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2026 else if (hp_int & RSEL) {
2028 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2030 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2032 if (((struct sccb_card *)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2034 FPT_phaseChkFifo(ioport, thisCard);
2037 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2039 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2040 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2041 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2044 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2045 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2046 FPT_queueDisconnect(currSCCB,thisCard);
2049 FPT_sres(ioport,thisCard,((struct sccb_card *)pCurrCard));
2050 FPT_phaseDecode(ioport,thisCard);
2055 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2058 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2059 FPT_phaseDecode(ioport,thisCard);
2064 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2066 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2067 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
2069 FPT_phaseDecode(ioport,thisCard);
2073 /* Harpoon problem some SCSI target device respond to selection
2074 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2075 to latch the correct Target ID into reg. x53.
2076 The work around require to correct this reg. But when write to this
2077 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2078 need to read this reg first then restore it later. After update to 0x53 */
2080 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2081 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2082 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2083 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2084 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
2085 WR_HARPOON(ioport+hp_fifowrite, i);
2086 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2090 else if (hp_int & XFER_CNT_0) {
2092 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2094 FPT_schkdd(ioport,thisCard);
2099 else if (hp_int & BUS_FREE) {
2101 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2103 if (((struct sccb_card *)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2105 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
2108 FPT_phaseBusFree(ioport,thisCard);
2112 else if (hp_int & ITICKLE) {
2114 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2115 ((struct sccb_card *)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2120 if (((struct sccb_card *)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2123 ((struct sccb_card *)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2126 if (((struct sccb_card *)pCurrCard)->currentSCCB == NULL) {
2128 FPT_queueSearchSelect(((struct sccb_card *)pCurrCard),thisCard);
2131 if (((struct sccb_card *)pCurrCard)->currentSCCB != NULL) {
2132 ((struct sccb_card *)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2133 FPT_ssel(ioport,thisCard);
2142 MENABLE_INT(ioport);
2147 /*---------------------------------------------------------------------
2149 * Function: Sccb_bad_isr
2151 * Description: Some type of interrupt has occurred which is slightly
2152 * out of the ordinary. We will now decode it fully, in
2153 * this routine. This is broken up in an attempt to save
2156 *---------------------------------------------------------------------*/
2157 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
2158 struct sccb_card * pCurrCard, unsigned short p_int)
2160 unsigned char temp, ScamFlg;
2161 struct sccb_mgr_tar_info * currTar_Info;
2162 struct nvram_info * pCurrNvRam;
2165 if (RD_HARPOON(p_port+hp_ext_status) &
2166 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2169 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2172 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2175 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2178 WR_HARPOON(p_port+hp_pci_stat_cfg,
2179 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2181 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2185 if (pCurrCard->currentSCCB != NULL)
2188 if (!pCurrCard->currentSCCB->HostStatus)
2189 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2191 FPT_sxfrp(p_port,p_card);
2193 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
2194 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2195 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
2196 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2198 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2200 FPT_phaseDecode(p_port,p_card);
2206 else if (p_int & RESET)
2209 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2210 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2211 if (pCurrCard->currentSCCB != NULL) {
2213 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2215 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2219 DISABLE_AUTO(p_port);
2221 FPT_sresb(p_port,p_card);
2223 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2225 pCurrNvRam = pCurrCard->pNvRamInfo;
2227 ScamFlg = pCurrNvRam->niScamConf;
2230 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
2233 FPT_XbowInit(p_port, ScamFlg);
2235 FPT_scini(p_card, pCurrCard->ourId, 0);
2241 else if (p_int & FIFO) {
2243 WRW_HARPOON((p_port+hp_intstat), FIFO);
2245 if (pCurrCard->currentSCCB != NULL)
2246 FPT_sxfrp(p_port,p_card);
2249 else if (p_int & TIMEOUT)
2252 DISABLE_AUTO(p_port);
2254 WRW_HARPOON((p_port+hp_intstat),
2255 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2257 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2260 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2261 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2262 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2263 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
2265 currTar_Info->TarLUNBusy[0] = 0;
2268 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2270 currTar_Info->TarSyncCtrl = 0;
2271 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2274 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2276 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2279 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
2281 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2285 else if (p_int & SCAM_SEL)
2288 FPT_scarb(p_port,LEVEL2_TAR);
2290 FPT_scasid(p_card, p_port);
2294 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2301 /*---------------------------------------------------------------------
2303 * Function: SccbMgrTableInit
2305 * Description: Initialize all Sccb manager data structures.
2307 *---------------------------------------------------------------------*/
2309 static void FPT_SccbMgrTableInitAll()
2311 unsigned char thisCard;
2313 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2315 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
2317 FPT_BL_Card[thisCard].ioPort = 0x00;
2318 FPT_BL_Card[thisCard].cardInfo = NULL;
2319 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2320 FPT_BL_Card[thisCard].ourId = 0x00;
2321 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2326 /*---------------------------------------------------------------------
2328 * Function: SccbMgrTableInit
2330 * Description: Initialize all Sccb manager data structures.
2332 *---------------------------------------------------------------------*/
2334 static void FPT_SccbMgrTableInitCard(struct sccb_card * pCurrCard, unsigned char p_card)
2336 unsigned char scsiID, qtag;
2338 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2340 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2343 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2345 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2346 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2347 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2350 pCurrCard->scanIndex = 0x00;
2351 pCurrCard->currentSCCB = NULL;
2352 pCurrCard->globalFlags = 0x00;
2353 pCurrCard->cmdCounter = 0x00;
2354 pCurrCard->tagQ_Lst = 0x01;
2355 pCurrCard->discQCount = 0;
2361 /*---------------------------------------------------------------------
2363 * Function: SccbMgrTableInit
2365 * Description: Initialize all Sccb manager data structures.
2367 *---------------------------------------------------------------------*/
2369 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
2372 unsigned char lun, qtag;
2373 struct sccb_mgr_tar_info * currTar_Info;
2375 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2377 currTar_Info->TarSelQ_Cnt = 0;
2378 currTar_Info->TarSyncCtrl = 0;
2380 currTar_Info->TarSelQ_Head = NULL;
2381 currTar_Info->TarSelQ_Tail = NULL;
2382 currTar_Info->TarTagQ_Cnt = 0;
2383 currTar_Info->TarLUN_CA = 0;
2386 for (lun = 0; lun < MAX_LUN; lun++)
2388 currTar_Info->TarLUNBusy[lun] = 0;
2389 currTar_Info->LunDiscQ_Idx[lun] = 0;
2392 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2394 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
2396 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
2398 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2399 FPT_BL_Card[p_card].discQCount--;
2406 /*---------------------------------------------------------------------
2410 * Description: Read in a message byte from the SCSI bus, and check
2411 * for a parity error.
2413 *---------------------------------------------------------------------*/
2415 static unsigned char FPT_sfm(unsigned long port, struct sccb * pCurrSCCB)
2417 unsigned char message;
2418 unsigned short TimeOutLoop;
2421 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2422 (TimeOutLoop++ < 20000) ){}
2425 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2427 message = RD_HARPOON(port+hp_scsidata_0);
2429 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2432 if (TimeOutLoop > 20000)
2433 message = 0x00; /* force message byte = 0 if Time Out on Req */
2435 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2436 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2438 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2439 WR_HARPOON(port+hp_xferstat, 0);
2440 WR_HARPOON(port+hp_fiforead, 0);
2441 WR_HARPOON(port+hp_fifowrite, 0);
2442 if (pCurrSCCB != NULL)
2444 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2449 ACCEPT_MSG_ATN(port);
2451 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2452 (TimeOutLoop++ < 20000) ){}
2453 if (TimeOutLoop > 20000)
2455 WRW_HARPOON((port+hp_intstat), PARITY);
2458 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2460 WRW_HARPOON((port+hp_intstat), PARITY);
2463 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2465 RD_HARPOON(port+hp_scsidata_0);
2467 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2472 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2473 WR_HARPOON(port+hp_xferstat, 0);
2474 WR_HARPOON(port+hp_fiforead, 0);
2475 WR_HARPOON(port+hp_fifowrite, 0);
2480 /*---------------------------------------------------------------------
2482 * Function: FPT_ssel
2484 * Description: Load up automation and select target device.
2486 *---------------------------------------------------------------------*/
2488 static void FPT_ssel(unsigned long port, unsigned char p_card)
2491 unsigned char auto_loaded, i, target, *theCCB;
2493 unsigned long cdb_reg;
2494 struct sccb_card * CurrCard;
2495 struct sccb * currSCCB;
2496 struct sccb_mgr_tar_info * currTar_Info;
2497 unsigned char lastTag, lun;
2499 CurrCard = &FPT_BL_Card[p_card];
2500 currSCCB = CurrCard->currentSCCB;
2501 target = currSCCB->TargID;
2502 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2503 lastTag = CurrCard->tagQ_Lst;
2508 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2509 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2511 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2512 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2514 lun = currSCCB->Lun;
2519 if (CurrCard->globalFlags & F_TAG_STARTED)
2521 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2523 if ((currTar_Info->TarLUN_CA == 0)
2524 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2528 if (currTar_Info->TarTagQ_Cnt !=0)
2530 currTar_Info->TarLUNBusy[lun] = 1;
2531 FPT_queueSelectFail(CurrCard,p_card);
2537 currTar_Info->TarLUNBusy[lun] = 1;
2540 } /*End non-tagged */
2543 currTar_Info->TarLUNBusy[lun] = 1;
2546 } /*!Use cmd Q Tagged */
2549 if (currTar_Info->TarLUN_CA == 1)
2551 FPT_queueSelectFail(CurrCard,p_card);
2556 currTar_Info->TarLUNBusy[lun] = 1;
2558 } /*else use cmd Q tagged */
2560 } /*if glob tagged started */
2563 currTar_Info->TarLUNBusy[lun] = 1;
2568 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2569 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2570 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2572 if(CurrCard->discQCount >= QUEUE_DEPTH)
2574 currTar_Info->TarLUNBusy[lun] = 1;
2575 FPT_queueSelectFail(CurrCard,p_card);
2579 for (i = 1; i < QUEUE_DEPTH; i++)
2581 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2582 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2584 CurrCard->tagQ_Lst = lastTag;
2585 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2586 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2587 CurrCard->discQCount++;
2591 if(i == QUEUE_DEPTH)
2593 currTar_Info->TarLUNBusy[lun] = 1;
2594 FPT_queueSelectFail(CurrCard,p_card);
2604 WR_HARPOON(port+hp_select_id, target);
2605 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2607 if (currSCCB->OperationCode == RESET_COMMAND) {
2608 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2609 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2611 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2613 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2615 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2617 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2619 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2621 currTar_Info->TarSyncCtrl = 0;
2622 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2625 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2627 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2630 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2631 FPT_SccbMgrTableInitTarget(p_card, target);
2635 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2637 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2638 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2640 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2642 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2643 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2644 >> 6) | (unsigned char)0x20)));
2645 WRW_HARPOON((port+SYNC_MSGS+2),
2646 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2647 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2649 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2654 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2655 auto_loaded = FPT_siwidn(port,p_card);
2656 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2659 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2660 == SYNC_SUPPORTED)) {
2661 auto_loaded = FPT_sisyncn(port,p_card, 0);
2662 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2669 if (currSCCB->ControlByte & F_USE_CMD_Q)
2672 CurrCard->globalFlags |= F_TAG_STARTED;
2674 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2677 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2679 /* Fix up the start instruction with a jump to
2680 Non-Tag-CMD handling */
2681 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2683 WRW_HARPOON((port+NON_TAG_ID_MSG),
2684 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2686 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2688 /* Setup our STATE so we know what happend when
2689 the wheels fall off. */
2690 currSCCB->Sccb_scsistat = SELECT_ST;
2692 currTar_Info->TarLUNBusy[lun] = 1;
2697 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2699 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2700 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2701 >> 6) | (unsigned char)0x20)));
2703 for (i = 1; i < QUEUE_DEPTH; i++)
2705 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2706 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2708 WRW_HARPOON((port+ID_MSG_STRT+6),
2709 (MPM_OP+AMSG_OUT+lastTag));
2710 CurrCard->tagQ_Lst = lastTag;
2711 currSCCB->Sccb_tag = lastTag;
2712 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2713 CurrCard->discQCount++;
2719 if ( i == QUEUE_DEPTH )
2721 currTar_Info->TarLUNBusy[lun] = 1;
2722 FPT_queueSelectFail(CurrCard,p_card);
2727 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2729 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2736 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2738 WRW_HARPOON((port+NON_TAG_ID_MSG),
2739 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2741 currSCCB->Sccb_scsistat = SELECT_ST;
2743 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2747 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2749 cdb_reg = port + CMD_STRT;
2751 for (i=0; i < currSCCB->CdbLength; i++)
2753 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2758 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2759 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2763 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2764 WR_HARPOON(port+hp_xferstat, 0x00);
2766 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2768 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2771 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2773 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2778 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2779 auto_loaded |= AUTO_IMMED; */
2780 auto_loaded = AUTO_IMMED;
2784 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2791 /*---------------------------------------------------------------------
2793 * Function: FPT_sres
2795 * Description: Hookup the correct CCB and handle the incoming messages.
2797 *---------------------------------------------------------------------*/
2799 static void FPT_sres(unsigned long port, unsigned char p_card, struct sccb_card * pCurrCard)
2802 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2805 struct sccb_mgr_tar_info * currTar_Info;
2806 struct sccb * currSCCB;
2811 if(pCurrCard->currentSCCB != NULL)
2813 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2817 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2820 currSCCB = pCurrCard->currentSCCB;
2821 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2823 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2824 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2826 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2828 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2829 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2831 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2832 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2834 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2835 if(currSCCB->Sccb_scsistat != ABORT_ST)
2837 pCurrCard->discQCount--;
2838 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2844 currTar_Info->TarLUNBusy[0] = 0;
2845 if(currSCCB->Sccb_tag)
2847 if(currSCCB->Sccb_scsistat != ABORT_ST)
2849 pCurrCard->discQCount--;
2850 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2854 if(currSCCB->Sccb_scsistat != ABORT_ST)
2856 pCurrCard->discQCount--;
2857 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2862 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
2865 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2868 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
2869 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2876 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2880 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2882 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2885 WRW_HARPOON((port+hp_intstat), PHASE);
2890 WRW_HARPOON((port+hp_intstat), PHASE);
2891 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2894 message = FPT_sfm(port,pCurrCard->currentSCCB);
2898 if (message <= (0x80 | LUN_MASK))
2900 lun = message & (unsigned char)LUN_MASK;
2902 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2904 if (currTar_Info->TarTagQ_Cnt != 0)
2907 if (!(currTar_Info->TarLUN_CA))
2909 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2912 message = FPT_sfm(port,pCurrCard->currentSCCB);
2923 tag = FPT_sfm(port,pCurrCard->currentSCCB);
2931 } /*End Q cnt != 0 */
2933 } /*End Tag cmds supported! */
2935 } /*End valid ID message. */
2940 ACCEPT_MSG_ATN(port);
2943 } /* End good id message. */
2953 ACCEPT_MSG_ATN(port);
2955 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2956 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2957 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2965 if(msgRetryCount == 1)
2967 FPT_SendMsg(port, SMPARITY);
2971 FPT_SendMsg(port, SMDEV_RESET);
2973 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
2975 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
2978 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
2982 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
2985 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
2989 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
2990 FPT_SccbMgrTableInitTarget(p_card,our_target);
2994 }while(message == 0);
2998 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2999 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3001 currTar_Info->TarLUNBusy[lun] = 1;
3002 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3003 if(pCurrCard->currentSCCB != NULL)
3009 ACCEPT_MSG_ATN(port);
3014 currTar_Info->TarLUNBusy[0] = 1;
3019 if (pCurrCard->discQ_Tbl[tag] != NULL)
3021 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3022 currTar_Info->TarTagQ_Cnt--;
3027 ACCEPT_MSG_ATN(port);
3031 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3032 if(pCurrCard->currentSCCB != NULL)
3038 ACCEPT_MSG_ATN(port);
3043 if(pCurrCard->currentSCCB != NULL)
3045 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3047 /* During Abort Tag command, the target could have got re-selected
3048 and completed the command. Check the select Q and remove the CCB
3049 if it is in the Select Q */
3050 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
3055 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3056 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3057 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3060 static void FPT_SendMsg(unsigned long port, unsigned char message)
3062 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3064 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3067 WRW_HARPOON((port+hp_intstat), PHASE);
3072 WRW_HARPOON((port+hp_intstat), PHASE);
3073 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3075 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3078 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3080 WR_HARPOON(port+hp_scsidata_0,message);
3082 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3086 WR_HARPOON(port+hp_portctrl_0, 0x00);
3088 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3089 (message == SMABORT_TAG) )
3091 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3093 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3095 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3101 /*---------------------------------------------------------------------
3103 * Function: FPT_sdecm
3105 * Description: Determine the proper responce to the message from the
3108 *---------------------------------------------------------------------*/
3109 static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
3111 struct sccb * currSCCB;
3112 struct sccb_card * CurrCard;
3113 struct sccb_mgr_tar_info * currTar_Info;
3115 CurrCard = &FPT_BL_Card[p_card];
3116 currSCCB = CurrCard->currentSCCB;
3118 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3120 if (message == SMREST_DATA_PTR)
3122 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3124 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3126 FPT_hostDataXferRestart(currSCCB);
3130 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3133 else if (message == SMCMD_COMP)
3137 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3139 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3140 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
3147 else if ((message == SMNO_OP) || (message >= SMIDENT)
3148 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3152 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3155 else if (message == SMREJECT)
3158 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3159 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3160 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3161 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3164 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3169 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3170 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3172 if(currSCCB->Lun == 0x00)
3174 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3177 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3179 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3182 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3186 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3187 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3189 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3193 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3195 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3196 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3199 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3200 CurrCard->discQCount--;
3201 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3202 currSCCB->Sccb_tag = 0x00;
3207 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3211 if(currSCCB->Lun == 0x00)
3213 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3214 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3221 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3222 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3223 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
3225 currTar_Info->TarLUNBusy[0] = 1;
3228 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
3230 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3239 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3240 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3242 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3244 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3249 else if (message == SMEXT)
3253 FPT_shandem(port,p_card,currSCCB);
3256 else if (message == SMIGNORWR)
3259 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3261 message = FPT_sfm(port,currSCCB);
3263 if(currSCCB->Sccb_scsimsg != SMPARITY)
3265 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3272 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3273 currSCCB->Sccb_scsimsg = SMREJECT;
3275 ACCEPT_MSG_ATN(port);
3276 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3281 /*---------------------------------------------------------------------
3283 * Function: FPT_shandem
3285 * Description: Decide what to do with the extended message.
3287 *---------------------------------------------------------------------*/
3288 static void FPT_shandem(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
3290 unsigned char length,message;
3292 length = FPT_sfm(port,pCurrSCCB);
3297 message = FPT_sfm(port,pCurrSCCB);
3301 if (message == SMSYNC)
3308 FPT_stsyncn(port,p_card);
3313 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3314 ACCEPT_MSG_ATN(port);
3317 else if (message == SMWDTR)
3324 FPT_stwidn(port,p_card);
3329 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3330 ACCEPT_MSG_ATN(port);
3332 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3338 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3339 ACCEPT_MSG_ATN(port);
3341 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3346 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3348 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3352 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3353 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3358 /*---------------------------------------------------------------------
3360 * Function: FPT_sisyncn
3362 * Description: Read in a message byte from the SCSI bus, and check
3363 * for a parity error.
3365 *---------------------------------------------------------------------*/
3367 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
3369 struct sccb * currSCCB;
3370 struct sccb_mgr_tar_info * currTar_Info;
3372 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3373 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3375 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3378 WRW_HARPOON((port+ID_MSG_STRT),
3379 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3381 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3383 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3384 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3385 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3388 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3390 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3392 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3394 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3396 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3398 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3401 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3404 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3405 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3406 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3411 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3412 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3413 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
3417 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3426 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3427 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3434 /*---------------------------------------------------------------------
3436 * Function: FPT_stsyncn
3438 * Description: The has sent us a Sync Nego message so handle it as
3441 *---------------------------------------------------------------------*/
3442 static void FPT_stsyncn(unsigned long port, unsigned char p_card)
3444 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
3445 struct sccb * currSCCB;
3446 struct sccb_mgr_tar_info * currTar_Info;
3448 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3449 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3451 sync_msg = FPT_sfm(port,currSCCB);
3453 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3455 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3462 offset = FPT_sfm(port,currSCCB);
3464 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3466 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3470 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3472 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3474 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3476 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3478 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3480 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3483 our_sync_msg = 0; /* Message = Async */
3485 if (sync_msg < our_sync_msg) {
3486 sync_msg = our_sync_msg; /*if faster, then set to max. */
3489 if (offset == ASYNC)
3492 if (offset > MAX_OFFSET)
3493 offset = MAX_OFFSET;
3499 sync_reg = 0x20; /* Use 10MB/s */
3503 sync_reg = 0x40; /* Use 6.6MB/s */
3507 sync_reg = 0x60; /* Use 5MB/s */
3511 sync_reg = 0x80; /* Use 4MB/s */
3515 sync_reg = 0xA0; /* Use 3.33MB/s */
3519 sync_reg = 0xC0; /* Use 2.85MB/s */
3523 sync_reg = 0xE0; /* Use 2.5MB/s */
3525 if (sync_msg > 100) {
3527 sync_reg = 0x00; /* Use ASYNC */
3532 if (currTar_Info->TarStatus & WIDE_ENABLED)
3538 sync_reg |= (offset | NARROW_SCSI);
3540 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
3543 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3548 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3549 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3551 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3557 ACCEPT_MSG_ATN(port);
3559 FPT_sisyncr(port,sync_msg,offset);
3561 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3562 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3567 /*---------------------------------------------------------------------
3569 * Function: FPT_sisyncr
3571 * Description: Answer the targets sync message.
3573 *---------------------------------------------------------------------*/
3574 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
3577 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3578 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3579 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3580 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3581 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3582 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3583 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3586 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3587 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3589 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3591 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3596 /*---------------------------------------------------------------------
3598 * Function: FPT_siwidn
3600 * Description: Read in a message byte from the SCSI bus, and check
3601 * for a parity error.
3603 *---------------------------------------------------------------------*/
3605 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
3607 struct sccb * currSCCB;
3608 struct sccb_mgr_tar_info * currTar_Info;
3610 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3611 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3613 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3616 WRW_HARPOON((port+ID_MSG_STRT),
3617 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3619 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3621 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3622 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3623 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3624 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3625 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3626 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3628 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3631 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3632 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
3639 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3640 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3642 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3649 /*---------------------------------------------------------------------
3651 * Function: FPT_stwidn
3653 * Description: The has sent us a Wide Nego message so handle it as
3656 *---------------------------------------------------------------------*/
3657 static void FPT_stwidn(unsigned long port, unsigned char p_card)
3659 unsigned char width;
3660 struct sccb * currSCCB;
3661 struct sccb_mgr_tar_info * currTar_Info;
3663 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3664 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3666 width = FPT_sfm(port,currSCCB);
3668 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3670 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3675 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3679 currTar_Info->TarStatus |= WIDE_ENABLED;
3683 width = NARROW_SCSI;
3684 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3688 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
3691 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3696 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3698 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3700 ACCEPT_MSG_ATN(port);
3702 FPT_sisyncn(port,p_card, 1);
3703 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3709 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3716 ACCEPT_MSG_ATN(port);
3718 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3723 FPT_siwidr(port,width);
3725 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3730 /*---------------------------------------------------------------------
3732 * Function: FPT_siwidr
3734 * Description: Answer the targets Wide nego message.
3736 *---------------------------------------------------------------------*/
3737 static void FPT_siwidr(unsigned long port, unsigned char width)
3740 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3741 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3742 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3743 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3744 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3745 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3748 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3749 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3751 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3753 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3758 /*---------------------------------------------------------------------
3760 * Function: FPT_sssyncv
3762 * Description: Write the desired value to the Sync Register for the
3765 *---------------------------------------------------------------------*/
3766 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
3767 struct sccb_mgr_tar_info * currTar_Info)
3769 unsigned char index;
3776 index = 12; /* hp_synctarg_0 */
3779 index = 13; /* hp_synctarg_1 */
3782 index = 14; /* hp_synctarg_2 */
3785 index = 15; /* hp_synctarg_3 */
3788 index = 8; /* hp_synctarg_4 */
3791 index = 9; /* hp_synctarg_5 */
3794 index = 10; /* hp_synctarg_6 */
3797 index = 11; /* hp_synctarg_7 */
3800 index = 4; /* hp_synctarg_8 */
3803 index = 5; /* hp_synctarg_9 */
3806 index = 6; /* hp_synctarg_10 */
3809 index = 7; /* hp_synctarg_11 */
3812 index = 0; /* hp_synctarg_12 */
3815 index = 1; /* hp_synctarg_13 */
3818 index = 2; /* hp_synctarg_14 */
3821 index = 3; /* hp_synctarg_15 */
3825 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3827 currTar_Info->TarSyncCtrl = p_sync_value;
3831 /*---------------------------------------------------------------------
3833 * Function: FPT_sresb
3835 * Description: Reset the desired card's SCSI bus.
3837 *---------------------------------------------------------------------*/
3838 static void FPT_sresb(unsigned long port, unsigned char p_card)
3840 unsigned char scsiID, i;
3842 struct sccb_mgr_tar_info * currTar_Info;
3844 WR_HARPOON(port+hp_page_ctrl,
3845 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3846 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3848 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3850 scsiID = RD_HARPOON(port+hp_seltimeout);
3851 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3852 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3854 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3856 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3858 WR_HARPOON(port+hp_seltimeout,scsiID);
3860 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3862 FPT_Wait(port, TO_5ms);
3864 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3866 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3868 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3870 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3872 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3874 currTar_Info->TarSyncCtrl = 0;
3875 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3878 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3880 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3883 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
3885 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3888 FPT_BL_Card[p_card].scanIndex = 0x00;
3889 FPT_BL_Card[p_card].currentSCCB = NULL;
3890 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3892 FPT_BL_Card[p_card].cmdCounter = 0x00;
3893 FPT_BL_Card[p_card].discQCount = 0x00;
3894 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3896 for(i = 0; i < QUEUE_DEPTH; i++)
3897 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3899 WR_HARPOON(port+hp_page_ctrl,
3900 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3904 /*---------------------------------------------------------------------
3906 * Function: FPT_ssenss
3908 * Description: Setup for the Auto Sense command.
3910 *---------------------------------------------------------------------*/
3911 static void FPT_ssenss(struct sccb_card * pCurrCard)
3914 struct sccb * currSCCB;
3916 currSCCB = pCurrCard->currentSCCB;
3919 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3921 for (i = 0; i < 6; i++) {
3923 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3926 currSCCB->CdbLength = SIX_BYTE_CMD;
3927 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3928 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3929 currSCCB->Cdb[2] = 0x00;
3930 currSCCB->Cdb[3] = 0x00;
3931 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3932 currSCCB->Cdb[5] = 0x00;
3934 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3936 currSCCB->Sccb_ATC = 0x00;
3938 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3940 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3942 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3944 currSCCB->ControlByte = 0x00;
3946 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3951 /*---------------------------------------------------------------------
3953 * Function: FPT_sxfrp
3955 * Description: Transfer data into the bit bucket until the device
3956 * decides to switch phase.
3958 *---------------------------------------------------------------------*/
3960 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
3962 unsigned char curr_phz;
3965 DISABLE_AUTO(p_port);
3967 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3969 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
3973 /* If the Automation handled the end of the transfer then do not
3974 match the phase or we will get out of sync with the ISR. */
3976 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3979 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3981 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3983 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3986 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3988 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
3989 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
3991 if (curr_phz & (unsigned char)SCSI_IOBIT)
3993 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3995 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
3997 RD_HARPOON(p_port+hp_fifodata_0);
4002 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4003 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4005 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4008 } /* End of While loop for padding data I/O phase */
4010 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4012 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4016 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4017 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4019 RD_HARPOON(p_port+hp_fifodata_0);
4022 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4024 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4025 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4027 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4028 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4033 /*---------------------------------------------------------------------
4035 * Function: FPT_schkdd
4037 * Description: Make sure data has been flushed from both FIFOs and abort
4038 * the operations if necessary.
4040 *---------------------------------------------------------------------*/
4042 static void FPT_schkdd(unsigned long port, unsigned char p_card)
4044 unsigned short TimeOutLoop;
4045 unsigned char sPhase;
4047 struct sccb * currSCCB;
4049 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4052 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4053 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4059 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4062 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4064 currSCCB->Sccb_XferCnt = 1;
4066 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4067 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
4068 WR_HARPOON(port+hp_xferstat, 0x00);
4074 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4076 currSCCB->Sccb_XferCnt = 0;
4079 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4080 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4082 currSCCB->HostStatus = SCCB_PARITY_ERR;
4083 WRW_HARPOON((port+hp_intstat), PARITY);
4087 FPT_hostDataXferAbort(port,p_card,currSCCB);
4090 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4094 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4096 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4099 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
4102 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4105 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4109 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4110 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4111 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
4112 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4113 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4116 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4118 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4120 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4121 FPT_phaseDataIn(port,p_card);
4125 FPT_phaseDataOut(port,p_card);
4130 FPT_sxfrp(port,p_card);
4131 if (!(RDW_HARPOON((port+hp_intstat)) &
4132 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4134 WRW_HARPOON((port+hp_intstat), AUTO_INT);
4135 FPT_phaseDecode(port,p_card);
4142 WR_HARPOON(port+hp_portctrl_0, 0x00);
4147 /*---------------------------------------------------------------------
4149 * Function: FPT_sinits
4151 * Description: Setup SCCB manager fields in this SCCB.
4153 *---------------------------------------------------------------------*/
4155 static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card)
4157 struct sccb_mgr_tar_info * currTar_Info;
4159 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4163 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
4165 p_sccb->Sccb_XferState = 0x00;
4166 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4168 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4169 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4171 p_sccb->Sccb_SGoffset = 0;
4172 p_sccb->Sccb_XferState = F_SG_XFER;
4173 p_sccb->Sccb_XferCnt = 0x00;
4176 if (p_sccb->DataLength == 0x00)
4178 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4180 if (p_sccb->ControlByte & F_USE_CMD_Q)
4182 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4183 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4186 currTar_Info->TarStatus |= TAG_Q_TRYING;
4189 /* For !single SCSI device in system & device allow Disconnect
4190 or command is tag_q type then send Cmd with Disconnect Enable
4191 else send Cmd with Disconnect Disable */
4194 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4195 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4196 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4198 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4199 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4200 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4205 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
4208 p_sccb->HostStatus = 0x00;
4209 p_sccb->TargetStatus = 0x00;
4210 p_sccb->Sccb_tag = 0x00;
4211 p_sccb->Sccb_MGRFlags = 0x00;
4212 p_sccb->Sccb_sgseg = 0x00;
4213 p_sccb->Sccb_ATC = 0x00;
4214 p_sccb->Sccb_savedATC = 0x00;
4216 p_sccb->SccbVirtDataPtr = 0x00;
4217 p_sccb->Sccb_forwardlink = NULL;
4218 p_sccb->Sccb_backlink = NULL;
4220 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4221 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4222 p_sccb->Sccb_scsimsg = SMNO_OP;
4227 /*---------------------------------------------------------------------
4229 * Function: Phase Decode
4231 * Description: Determine the phase and call the appropriate function.
4233 *---------------------------------------------------------------------*/
4235 static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
4237 unsigned char phase_ref;
4238 void (*phase) (unsigned long, unsigned char);
4241 DISABLE_AUTO(p_port);
4243 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4245 phase = FPT_s_PhaseTbl[phase_ref];
4247 (*phase)(p_port, p_card); /* Call the correct phase func */
4252 /*---------------------------------------------------------------------
4254 * Function: Data Out Phase
4256 * Description: Start up both the BusMaster and Xbow.
4258 *---------------------------------------------------------------------*/
4260 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
4263 struct sccb * currSCCB;
4265 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4266 if (currSCCB == NULL)
4268 return; /* Exit if No SCCB record */
4271 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4272 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4274 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4276 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4278 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4280 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4282 if (currSCCB->Sccb_XferCnt == 0) {
4285 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4286 (currSCCB->HostStatus == SCCB_COMPLETE))
4287 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4289 FPT_sxfrp(port,p_card);
4290 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4291 FPT_phaseDecode(port,p_card);
4296 /*---------------------------------------------------------------------
4298 * Function: Data In Phase
4300 * Description: Startup the BusMaster and the XBOW.
4302 *---------------------------------------------------------------------*/
4304 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
4307 struct sccb * currSCCB;
4309 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4311 if (currSCCB == NULL)
4313 return; /* Exit if No SCCB record */
4317 currSCCB->Sccb_scsistat = DATA_IN_ST;
4318 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4319 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4321 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4323 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4325 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4327 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4329 if (currSCCB->Sccb_XferCnt == 0) {
4332 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4333 (currSCCB->HostStatus == SCCB_COMPLETE))
4334 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4336 FPT_sxfrp(port,p_card);
4337 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4338 FPT_phaseDecode(port,p_card);
4343 /*---------------------------------------------------------------------
4345 * Function: Command Phase
4347 * Description: Load the CDB into the automation and start it up.
4349 *---------------------------------------------------------------------*/
4351 static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
4353 struct sccb * currSCCB;
4354 unsigned long cdb_reg;
4357 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4359 if (currSCCB->OperationCode == RESET_COMMAND) {
4361 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4362 currSCCB->CdbLength = SIX_BYTE_CMD;
4365 WR_HARPOON(p_port+hp_scsisig, 0x00);
4367 ARAM_ACCESS(p_port);
4370 cdb_reg = p_port + CMD_STRT;
4372 for (i=0; i < currSCCB->CdbLength; i++) {
4374 if (currSCCB->OperationCode == RESET_COMMAND)
4376 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4379 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4383 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4384 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4386 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4388 currSCCB->Sccb_scsistat = COMMAND_ST;
4390 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4391 SGRAM_ACCESS(p_port);
4395 /*---------------------------------------------------------------------
4397 * Function: Status phase
4399 * Description: Bring in the status and command complete message bytes
4401 *---------------------------------------------------------------------*/
4403 static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
4405 /* Start-up the automation to finish off this command and let the
4406 isr handle the interrupt for command complete when it comes in.
4407 We could wait here for the interrupt to be generated?
4410 WR_HARPOON(port+hp_scsisig, 0x00);
4412 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4416 /*---------------------------------------------------------------------
4418 * Function: Phase Message Out
4420 * Description: Send out our message (if we have one) and handle whatever
4423 *---------------------------------------------------------------------*/
4425 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
4427 unsigned char message,scsiID;
4428 struct sccb * currSCCB;
4429 struct sccb_mgr_tar_info * currTar_Info;
4431 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4433 if (currSCCB != NULL) {
4435 message = currSCCB->Sccb_scsimsg;
4436 scsiID = currSCCB->TargID;
4438 if (message == SMDEV_RESET)
4442 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4443 currTar_Info->TarSyncCtrl = 0;
4444 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
4446 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
4449 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
4453 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
4456 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
4460 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4461 FPT_SccbMgrTableInitTarget(p_card,scsiID);
4463 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4465 currSCCB->HostStatus = SCCB_COMPLETE;
4466 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
4468 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4469 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4474 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4478 if(message == SMNO_OP)
4480 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4482 FPT_ssel(port,p_card);
4490 if (message == SMABORT)
4492 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4501 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4504 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4506 WR_HARPOON(port+hp_scsidata_0,message);
4508 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4512 WR_HARPOON(port+hp_portctrl_0, 0x00);
4514 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4515 (message == SMABORT_TAG) )
4518 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4520 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4522 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4524 if (currSCCB != NULL)
4527 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4528 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4529 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4531 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4533 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
4538 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4545 FPT_sxfrp(port,p_card);
4552 if(message == SMPARITY)
4554 currSCCB->Sccb_scsimsg = SMNO_OP;
4555 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4559 FPT_sxfrp(port,p_card);
4565 /*---------------------------------------------------------------------
4567 * Function: Message In phase
4569 * Description: Bring in the message and determine what to do with it.
4571 *---------------------------------------------------------------------*/
4573 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
4575 unsigned char message;
4576 struct sccb * currSCCB;
4578 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4580 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
4583 FPT_phaseChkFifo(port, p_card);
4586 message = RD_HARPOON(port+hp_scsidata_0);
4587 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4590 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4597 message = FPT_sfm(port,currSCCB);
4602 FPT_sdecm(message,port,p_card);
4607 if(currSCCB->Sccb_scsimsg != SMPARITY)
4609 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4616 /*---------------------------------------------------------------------
4618 * Function: Illegal phase
4620 * Description: Target switched to some illegal phase, so all we can do
4621 * is report an error back to the host (if that is possible)
4622 * and send an ABORT message to the misbehaving target.
4624 *---------------------------------------------------------------------*/
4626 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
4628 struct sccb * currSCCB;
4630 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4632 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4633 if (currSCCB != NULL) {
4635 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4636 currSCCB->Sccb_scsistat = ABORT_ST;
4637 currSCCB->Sccb_scsimsg = SMABORT;
4640 ACCEPT_MSG_ATN(port);
4645 /*---------------------------------------------------------------------
4647 * Function: Phase Check FIFO
4649 * Description: Make sure data has been flushed from both FIFOs and abort
4650 * the operations if necessary.
4652 *---------------------------------------------------------------------*/
4654 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
4656 unsigned long xfercnt;
4657 struct sccb * currSCCB;
4659 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4661 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4664 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4665 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4668 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4670 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4672 currSCCB->Sccb_XferCnt = 0;
4674 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4675 (currSCCB->HostStatus == SCCB_COMPLETE))
4677 currSCCB->HostStatus = SCCB_PARITY_ERR;
4678 WRW_HARPOON((port+hp_intstat), PARITY);
4681 FPT_hostDataXferAbort(port,p_card,currSCCB);
4683 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4685 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4686 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4689 } /*End Data In specific code. */
4693 GET_XFER_CNT(port,xfercnt);
4696 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4699 WR_HARPOON(port+hp_portctrl_0, 0x00);
4701 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4703 currSCCB->Sccb_XferCnt = xfercnt;
4705 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4706 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4708 currSCCB->HostStatus = SCCB_PARITY_ERR;
4709 WRW_HARPOON((port+hp_intstat), PARITY);
4713 FPT_hostDataXferAbort(port,p_card,currSCCB);
4716 WR_HARPOON(port+hp_fifowrite, 0x00);
4717 WR_HARPOON(port+hp_fiforead, 0x00);
4718 WR_HARPOON(port+hp_xferstat, 0x00);
4720 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4724 /*---------------------------------------------------------------------
4726 * Function: Phase Bus Free
4728 * Description: We just went bus free so figure out if it was
4729 * because of command complete or from a disconnect.
4731 *---------------------------------------------------------------------*/
4732 static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
4734 struct sccb * currSCCB;
4736 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4738 if (currSCCB != NULL)
4744 if (currSCCB->OperationCode == RESET_COMMAND)
4747 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4748 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4749 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4751 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4753 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4755 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
4759 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4761 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4762 (unsigned char)SYNC_SUPPORTED;
4763 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4766 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4768 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4769 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4770 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4772 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
4775 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4777 /* Make sure this is not a phony BUS_FREE. If we were
4778 reselected or if BUSY is NOT on then this is a
4779 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4781 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4782 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4784 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4785 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
4797 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4799 if (!currSCCB->HostStatus)
4801 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4804 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4805 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4806 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4808 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4810 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4815 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4817 } /*end if !=null */
4823 /*---------------------------------------------------------------------
4825 * Function: Auto Load Default Map
4827 * Description: Load the Automation RAM with the defualt map values.
4829 *---------------------------------------------------------------------*/
4830 static void FPT_autoLoadDefaultMap(unsigned long p_port)
4832 unsigned long map_addr;
4834 ARAM_ACCESS(p_port);
4835 map_addr = p_port + hp_aramBase;
4837 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4839 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4841 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4843 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4845 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4847 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4849 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4851 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4853 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4855 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4857 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4859 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4861 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4863 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4865 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4867 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4869 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4871 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4872 map_addr +=2; /*This means AYNC DATA IN */
4873 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4875 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4877 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4879 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4881 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4883 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4885 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4887 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4889 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4891 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4893 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4895 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4897 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4899 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4901 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4903 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4905 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4907 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4910 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4912 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4914 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4916 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4917 map_addr +=2; /* DIDN'T GET ONE */
4918 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4920 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4922 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4926 SGRAM_ACCESS(p_port);
4929 /*---------------------------------------------------------------------
4931 * Function: Auto Command Complete
4933 * Description: Post command back to host and find another command
4936 *---------------------------------------------------------------------*/
4938 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
4940 struct sccb * currSCCB;
4941 unsigned char status_byte;
4943 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4945 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4947 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4949 if (status_byte != SSGOOD) {
4951 if (status_byte == SSQ_FULL) {
4954 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4955 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4957 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4958 if(FPT_BL_Card[p_card].discQCount != 0)
4959 FPT_BL_Card[p_card].discQCount--;
4960 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
4964 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
4965 if(currSCCB->Sccb_tag)
4967 if(FPT_BL_Card[p_card].discQCount != 0)
4968 FPT_BL_Card[p_card].discQCount--;
4969 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4972 if(FPT_BL_Card[p_card].discQCount != 0)
4973 FPT_BL_Card[p_card].discQCount--;
4974 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
4978 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4980 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
4985 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4987 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4988 (unsigned char)SYNC_SUPPORTED;
4990 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4991 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4993 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4994 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4996 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4997 if(FPT_BL_Card[p_card].discQCount != 0)
4998 FPT_BL_Card[p_card].discQCount--;
4999 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5003 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5004 if(currSCCB->Sccb_tag)
5006 if(FPT_BL_Card[p_card].discQCount != 0)
5007 FPT_BL_Card[p_card].discQCount--;
5008 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5011 if(FPT_BL_Card[p_card].discQCount != 0)
5012 FPT_BL_Card[p_card].discQCount--;
5013 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5020 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5023 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5024 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
5025 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5027 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5028 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5030 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5031 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5033 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5034 if(FPT_BL_Card[p_card].discQCount != 0)
5035 FPT_BL_Card[p_card].discQCount--;
5036 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5040 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5041 if(currSCCB->Sccb_tag)
5043 if(FPT_BL_Card[p_card].discQCount != 0)
5044 FPT_BL_Card[p_card].discQCount--;
5045 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5048 if(FPT_BL_Card[p_card].discQCount != 0)
5049 FPT_BL_Card[p_card].discQCount--;
5050 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5057 if (status_byte == SSCHECK)
5059 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
5061 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
5063 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
5065 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
5067 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
5072 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5074 currSCCB->SccbStatus = SCCB_ERROR;
5075 currSCCB->TargetStatus = status_byte;
5077 if (status_byte == SSCHECK) {
5079 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5083 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5085 if (currSCCB->RequestSenseLength == 0)
5086 currSCCB->RequestSenseLength = 14;
5088 FPT_ssenss(&FPT_BL_Card[p_card]);
5089 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5091 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5092 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5094 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5095 if(FPT_BL_Card[p_card].discQCount != 0)
5096 FPT_BL_Card[p_card].discQCount--;
5097 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5101 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5102 if(currSCCB->Sccb_tag)
5104 if(FPT_BL_Card[p_card].discQCount != 0)
5105 FPT_BL_Card[p_card].discQCount--;
5106 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5109 if(FPT_BL_Card[p_card].discQCount != 0)
5110 FPT_BL_Card[p_card].discQCount--;
5111 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5121 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5122 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5123 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
5125 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5128 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
5131 #define SHORT_WAIT 0x0000000F
5132 #define LONG_WAIT 0x0000FFFFL
5135 /*---------------------------------------------------------------------
5137 * Function: Data Transfer Processor
5139 * Description: This routine performs two tasks.
5140 * (1) Start data transfer by calling HOST_DATA_XFER_START
5141 * function. Once data transfer is started, (2) Depends
5142 * on the type of data transfer mode Scatter/Gather mode
5143 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5144 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5145 * data transfer done. In Scatter/Gather mode, this routine
5146 * checks bus master command complete and dual rank busy
5147 * bit to keep chaining SC transfer command. Similarly,
5148 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5149 * (F_HOST_XFER_ACT bit) for data transfer done.
5151 *---------------------------------------------------------------------*/
5153 static void FPT_dataXferProcessor(unsigned long port, struct sccb_card * pCurrCard)
5155 struct sccb * currSCCB;
5157 currSCCB = pCurrCard->currentSCCB;
5159 if (currSCCB->Sccb_XferState & F_SG_XFER)
5161 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5164 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
5165 currSCCB->Sccb_SGoffset = 0x00;
5167 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5169 FPT_busMstrSGDataXferStart(port, currSCCB);
5174 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5176 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5178 FPT_busMstrDataXferStart(port, currSCCB);
5184 /*---------------------------------------------------------------------
5186 * Function: BusMaster Scatter Gather Data Transfer Start
5190 *---------------------------------------------------------------------*/
5191 static void FPT_busMstrSGDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
5193 unsigned long count,addr,tmpSGCnt;
5194 unsigned int sg_index;
5195 unsigned char sg_count, i;
5196 unsigned long reg_offset;
5199 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5201 count = ((unsigned long) HOST_RD_CMD)<<24;
5205 count = ((unsigned long) HOST_WRT_CMD)<<24;
5210 sg_index = pcurrSCCB->Sccb_sgseg;
5211 reg_offset = hp_aramBase;
5214 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5217 WR_HARPOON(p_port+hp_page_ctrl, i);
5219 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
5220 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5222 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
5225 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
5228 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
5229 ((sg_index * 2) + 1));
5232 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5234 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5235 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5237 tmpSGCnt = count & 0x00FFFFFFL;
5240 WR_HARP32(p_port,reg_offset,addr);
5243 WR_HARP32(p_port,reg_offset,count);
5246 count &= 0xFF000000L;
5252 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5254 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5256 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5258 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5261 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5262 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5268 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5269 (tmpSGCnt & 0x000000001))
5272 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5277 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5279 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5280 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5284 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
5289 /*---------------------------------------------------------------------
5291 * Function: BusMaster Data Transfer Start
5295 *---------------------------------------------------------------------*/
5296 static void FPT_busMstrDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
5298 unsigned long addr,count;
5300 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5302 count = pcurrSCCB->Sccb_XferCnt;
5304 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5308 addr = pcurrSCCB->SensePointer;
5309 count = pcurrSCCB->RequestSenseLength;
5313 HP_SETUP_ADDR_CNT(p_port,addr,count);
5316 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5318 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5319 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5321 WR_HARPOON(p_port+hp_xfer_cmd,
5322 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5327 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5328 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5330 WR_HARPOON(p_port+hp_xfer_cmd,
5331 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5337 /*---------------------------------------------------------------------
5339 * Function: BusMaster Timeout Handler
5341 * Description: This function is called after a bus master command busy time
5342 * out is detected. This routines issue halt state machine
5343 * with a software time out for command busy. If command busy
5344 * is still asserted at the end of the time out, it issues
5345 * hard abort with another software time out. It hard abort
5346 * command busy is also time out, it'll just give up.
5348 *---------------------------------------------------------------------*/
5349 static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
5351 unsigned long timeout;
5353 timeout = LONG_WAIT;
5355 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5357 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5361 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5362 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5364 timeout = LONG_WAIT;
5365 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5368 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5370 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5380 /*---------------------------------------------------------------------
5382 * Function: Host Data Transfer Abort
5384 * Description: Abort any in progress transfer.
5386 *---------------------------------------------------------------------*/
5387 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
5390 unsigned long timeout;
5391 unsigned long remain_cnt;
5392 unsigned int sg_ptr;
5394 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5396 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5399 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5401 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5402 timeout = LONG_WAIT;
5404 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5406 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5408 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5410 if (FPT_busMstrTimeOut(port)) {
5412 if (pCurrSCCB->HostStatus == 0x00)
5414 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5418 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5420 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5422 if (pCurrSCCB->HostStatus == 0x00)
5425 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5431 else if (pCurrSCCB->Sccb_XferCnt) {
5433 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5436 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5439 WR_HARPOON(port+hp_sg_addr,0x00);
5441 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5443 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5445 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5448 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5450 while (remain_cnt < 0x01000000L) {
5454 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
5455 DataPointer) + (sg_ptr * 2)))) {
5457 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
5458 DataPointer) + (sg_ptr * 2)));
5469 if (remain_cnt < 0x01000000L) {
5472 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5474 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5477 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5478 && (remain_cnt == 0))
5480 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5486 if (pCurrSCCB->HostStatus == 0x00) {
5488 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5494 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5497 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5499 FPT_busMstrTimeOut(port);
5504 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5506 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5508 if (pCurrSCCB->HostStatus == 0x00) {
5510 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5521 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5523 timeout = SHORT_WAIT;
5525 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5526 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5530 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5532 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5535 timeout = LONG_WAIT;
5537 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5540 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5544 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5546 if (pCurrSCCB->HostStatus == 0x00) {
5548 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5551 FPT_busMstrTimeOut(port);
5555 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5557 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5559 if (pCurrSCCB->HostStatus == 0x00) {
5561 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5572 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5574 timeout = LONG_WAIT;
5576 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5578 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5580 if (pCurrSCCB->HostStatus == 0x00) {
5582 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5585 FPT_busMstrTimeOut(port);
5590 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5592 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5594 if (pCurrSCCB->HostStatus == 0x00) {
5596 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5602 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5604 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5607 WR_HARPOON(port+hp_sg_addr,0x00);
5609 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5611 pCurrSCCB->Sccb_SGoffset = 0x00;
5614 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5615 pCurrSCCB->DataLength) {
5617 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5619 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5626 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5628 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5632 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5637 /*---------------------------------------------------------------------
5639 * Function: Host Data Transfer Restart
5641 * Description: Reset the available count due to a restore data
5644 *---------------------------------------------------------------------*/
5645 static void FPT_hostDataXferRestart(struct sccb * currSCCB)
5647 unsigned long data_count;
5648 unsigned int sg_index;
5649 unsigned long *sg_ptr;
5651 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5653 currSCCB->Sccb_XferCnt = 0;
5655 sg_index = 0xffff; /*Index by long words into sg list. */
5656 data_count = 0; /*Running count of SG xfer counts. */
5658 sg_ptr = (unsigned long *)currSCCB->DataPointer;
5660 while (data_count < currSCCB->Sccb_ATC) {
5663 data_count += *(sg_ptr+(sg_index * 2));
5666 if (data_count == currSCCB->Sccb_ATC) {
5668 currSCCB->Sccb_SGoffset = 0;
5673 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5676 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5680 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5686 /*---------------------------------------------------------------------
5688 * Function: FPT_scini
5690 * Description: Setup all data structures necessary for SCAM selection.
5692 *---------------------------------------------------------------------*/
5694 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
5697 unsigned char loser,assigned_id;
5698 unsigned long p_port;
5700 unsigned char i,k,ScamFlg ;
5701 struct sccb_card * currCard;
5702 struct nvram_info * pCurrNvRam;
5704 currCard = &FPT_BL_Card[p_card];
5705 p_port = currCard->ioPort;
5706 pCurrNvRam = currCard->pNvRamInfo;
5710 ScamFlg = pCurrNvRam->niScamConf;
5711 i = pCurrNvRam->niSysConf;
5714 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5715 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
5717 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5720 FPT_inisci(p_card,p_port, p_our_id);
5722 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5723 too slow to return to SCAM selection */
5726 FPT_Wait1Second(p_port);
5728 FPT_Wait(p_port, TO_250ms); */
5730 FPT_Wait1Second(p_port);
5732 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5734 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5739 FPT_scxferc(p_port,SYNC_PTRN);
5740 FPT_scxferc(p_port,DOM_MSTR);
5741 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
5742 } while ( loser == 0xFF );
5746 if ((p_power_up) && (!loser))
5748 FPT_sresb(p_port,p_card);
5749 FPT_Wait(p_port, TO_250ms);
5751 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5756 FPT_scxferc(p_port, SYNC_PTRN);
5757 FPT_scxferc(p_port, DOM_MSTR);
5758 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
5760 } while ( loser == 0xFF );
5775 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5778 if (ScamFlg & SCAM_ENABLED)
5781 for (i=0; i < MAX_SCSI_TAR; i++)
5783 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5784 (FPT_scamInfo[i].state == ID_UNUSED))
5786 if (FPT_scsell(p_port,i))
5788 FPT_scamInfo[i].state = LEGACY;
5789 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5790 (FPT_scamInfo[i].id_string[1] != 0xFA))
5793 FPT_scamInfo[i].id_string[0] = 0xFF;
5794 FPT_scamInfo[i].id_string[1] = 0xFA;
5795 if(pCurrNvRam == NULL)
5796 currCard->globalFlags |= F_UPDATE_EEPROM;
5802 FPT_sresb(p_port,p_card);
5803 FPT_Wait1Second(p_port);
5804 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5806 FPT_scasid(p_card, p_port);
5811 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5813 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5815 FPT_scwtsel(p_port);
5818 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
5820 i = FPT_scxferc(p_port,0x00);
5823 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
5825 i = FPT_scxferc(p_port,0x00);
5828 k = FPT_scxferc(p_port,0x00);
5833 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
5834 FPT_inisci(p_card, p_port, p_our_id);
5835 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5836 FPT_scamInfo[currCard->ourId].id_string[0]
5844 else if (i == SET_P_FLAG)
5846 if (!(FPT_scsendi(p_port,
5847 &FPT_scamInfo[p_our_id].id_string[0])))
5848 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
5850 }while (!assigned_id);
5852 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
5855 if (ScamFlg & SCAM_ENABLED)
5858 if (currCard->globalFlags & F_UPDATE_EEPROM)
5860 FPT_scsavdi(p_card, p_port);
5861 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5867 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5869 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5870 (FPT_scamInfo[i].state == LEGACY))
5875 currCard->globalFlags |= F_SINGLE_DEVICE;
5877 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5882 /*---------------------------------------------------------------------
5884 * Function: FPT_scarb
5886 * Description: Gain control of the bus and wait SCAM select time (250ms)
5888 *---------------------------------------------------------------------*/
5890 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
5892 if (p_sel_type == INIT_SELTD)
5895 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5898 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
5901 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
5904 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5906 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5908 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5914 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5916 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5918 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5919 ~(SCSI_BSY | SCSI_SEL)));
5925 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5927 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5928 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5929 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
5930 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5932 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5934 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5937 FPT_Wait(p_port,TO_250ms);
5943 /*---------------------------------------------------------------------
5945 * Function: FPT_scbusf
5947 * Description: Release the SCSI bus and disable SCAM selection.
5949 *---------------------------------------------------------------------*/
5951 static void FPT_scbusf(unsigned long p_port)
5953 WR_HARPOON(p_port+hp_page_ctrl,
5954 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5957 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5959 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5962 WR_HARPOON(p_port+hp_scsisig, 0x00);
5965 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5968 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5971 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5973 WR_HARPOON(p_port+hp_page_ctrl,
5974 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5979 /*---------------------------------------------------------------------
5981 * Function: FPT_scasid
5983 * Description: Assign an ID to all the SCAM devices.
5985 *---------------------------------------------------------------------*/
5987 static void FPT_scasid(unsigned char p_card, unsigned long p_port)
5989 unsigned char temp_id_string[ID_STRING_LENGTH];
5991 unsigned char i,k,scam_id;
5992 unsigned char crcBytes[3];
5993 struct nvram_info * pCurrNvRam;
5994 unsigned short * pCrcBytes;
5996 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6003 for (k=0; k < ID_STRING_LENGTH; k++)
6005 temp_id_string[k] = (unsigned char) 0x00;
6008 FPT_scxferc(p_port,SYNC_PTRN);
6009 FPT_scxferc(p_port,ASSIGN_ID);
6011 if (!(FPT_sciso(p_port,&temp_id_string[0])))
6014 pCrcBytes = (unsigned short *)&crcBytes[0];
6015 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6016 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
6017 temp_id_string[1] = crcBytes[2];
6018 temp_id_string[2] = crcBytes[0];
6019 temp_id_string[3] = crcBytes[1];
6020 for(k = 4; k < ID_STRING_LENGTH; k++)
6021 temp_id_string[k] = (unsigned char) 0x00;
6023 i = FPT_scmachid(p_card,temp_id_string);
6025 if (i == CLR_PRIORITY)
6027 FPT_scxferc(p_port,MISC_CODE);
6028 FPT_scxferc(p_port,CLR_P_FLAG);
6029 i = 0; /*Not the last ID yet. */
6032 else if (i != NO_ID_AVAIL)
6035 FPT_scxferc(p_port,ID_0_7);
6037 FPT_scxferc(p_port,ID_8_F);
6039 scam_id = (i & (unsigned char) 0x07);
6042 for (k=1; k < 0x08; k <<= 1)
6044 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6046 FPT_scxferc(p_port,scam_id);
6048 i = 0; /*Not the last ID yet. */
6059 FPT_scxferc(p_port,SYNC_PTRN);
6060 FPT_scxferc(p_port,CFG_CMPLT);
6067 /*---------------------------------------------------------------------
6069 * Function: FPT_scsel
6071 * Description: Select all the SCAM devices.
6073 *---------------------------------------------------------------------*/
6075 static void FPT_scsel(unsigned long p_port)
6078 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6079 FPT_scwiros(p_port, SCSI_MSG);
6081 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6084 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6085 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6086 (unsigned char)(BIT(7)+BIT(6))));
6089 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6090 FPT_scwiros(p_port, SCSI_SEL);
6092 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6093 ~(unsigned char)BIT(6)));
6094 FPT_scwirod(p_port, BIT(6));
6096 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6101 /*---------------------------------------------------------------------
6103 * Function: FPT_scxferc
6105 * Description: Handshake the p_data (DB4-0) across the bus.
6107 *---------------------------------------------------------------------*/
6109 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
6111 unsigned char curr_data, ret_data;
6113 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6115 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6117 curr_data &= ~BIT(7);
6119 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6121 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
6122 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6124 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
6126 curr_data |= BIT(6);
6128 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6130 curr_data &= ~BIT(5);
6132 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6134 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
6136 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6137 curr_data |= BIT(7);
6139 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6141 curr_data &= ~BIT(6);
6143 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6145 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
6151 /*---------------------------------------------------------------------
6153 * Function: FPT_scsendi
6155 * Description: Transfer our Identification string to determine if we
6156 * will be the dominant master.
6158 *---------------------------------------------------------------------*/
6160 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
6162 unsigned char ret_data,byte_cnt,bit_cnt,defer;
6166 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6168 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6171 ret_data = FPT_scxferc(p_port,00);
6173 else if (p_id_string[byte_cnt] & bit_cnt)
6175 ret_data = FPT_scxferc(p_port,02);
6179 ret_data = FPT_scxferc(p_port,01);
6184 if ((ret_data & 0x1C) == 0x10)
6185 return(0x00); /*End of isolation stage, we won! */
6187 if (ret_data & 0x1C)
6190 if ((defer) && (!(ret_data & 0x1F)))
6191 return(0x01); /*End of isolation stage, we lost. */
6198 return(0x01); /*We lost */
6200 return(0); /*We WON! Yeeessss! */
6205 /*---------------------------------------------------------------------
6207 * Function: FPT_sciso
6209 * Description: Transfer the Identification string.
6211 *---------------------------------------------------------------------*/
6213 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
6215 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
6219 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6221 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6223 ret_data = FPT_scxferc(p_port,0);
6225 if (ret_data & 0xFC)
6231 if (ret_data & BIT(1)) {
6236 if ((ret_data & 0x1F) == 0)
6239 if(bit_cnt != 0 || bit_cnt != 8)
6243 FPT_scxferc(p_port, SYNC_PTRN);
6244 FPT_scxferc(p_port, ASSIGN_ID);
6256 p_id_string[byte_cnt] = the_data;
6265 /*---------------------------------------------------------------------
6267 * Function: FPT_scwirod
6269 * Description: Sample the SCSI data bus making sure the signal has been
6270 * deasserted for the correct number of consecutive samples.
6272 *---------------------------------------------------------------------*/
6274 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
6279 while ( i < MAX_SCSI_TAR ) {
6281 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6294 /*---------------------------------------------------------------------
6296 * Function: FPT_scwiros
6298 * Description: Sample the SCSI Signal lines making sure the signal has been
6299 * deasserted for the correct number of consecutive samples.
6301 *---------------------------------------------------------------------*/
6303 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
6308 while ( i < MAX_SCSI_TAR ) {
6310 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6322 /*---------------------------------------------------------------------
6324 * Function: FPT_scvalq
6326 * Description: Make sure we received a valid data byte.
6328 *---------------------------------------------------------------------*/
6330 static unsigned char FPT_scvalq(unsigned char p_quintet)
6332 unsigned char count;
6334 for (count=1; count < 0x08; count<<=1) {
6335 if (!(p_quintet & count))
6339 if (p_quintet & 0x18)
6347 /*---------------------------------------------------------------------
6349 * Function: FPT_scsell
6351 * Description: Select the specified device ID using a selection timeout
6352 * less than 4ms. If somebody responds then it is a legacy
6353 * drive and this ID must be marked as such.
6355 *---------------------------------------------------------------------*/
6357 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
6361 WR_HARPOON(p_port+hp_page_ctrl,
6362 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6364 ARAM_ACCESS(p_port);
6366 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6367 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6370 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6371 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6373 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6375 WRW_HARPOON((p_port+hp_intstat),
6376 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6378 WR_HARPOON(p_port+hp_select_id, targ_id);
6380 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6381 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6382 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6385 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6386 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6388 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6389 FPT_Wait(p_port, TO_250ms);
6391 DISABLE_AUTO(p_port);
6393 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6394 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6396 SGRAM_ACCESS(p_port);
6398 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6400 WRW_HARPOON((p_port+hp_intstat),
6401 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6403 WR_HARPOON(p_port+hp_page_ctrl,
6404 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6406 return(0); /*No legacy device */
6411 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6412 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6414 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6419 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6421 WR_HARPOON(p_port+hp_page_ctrl,
6422 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6424 return(1); /*Found one of them oldies! */
6428 /*---------------------------------------------------------------------
6430 * Function: FPT_scwtsel
6432 * Description: Wait to be selected by another SCAM initiator.
6434 *---------------------------------------------------------------------*/
6436 static void FPT_scwtsel(unsigned long p_port)
6438 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6442 /*---------------------------------------------------------------------
6444 * Function: FPT_inisci
6446 * Description: Setup the data Structure with the info from the EEPROM.
6448 *---------------------------------------------------------------------*/
6450 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
6452 unsigned char i,k,max_id;
6453 unsigned short ee_data;
6454 struct nvram_info * pCurrNvRam;
6456 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6458 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6465 for(i = 0; i < max_id; i++){
6467 for(k = 0; k < 4; k++)
6468 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
6469 for(k = 4; k < ID_STRING_LENGTH; k++)
6470 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
6472 if(FPT_scamInfo[i].id_string[0] == 0x00)
6473 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6475 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6479 for (i=0; i < max_id; i++)
6481 for (k=0; k < ID_STRING_LENGTH; k+=2)
6483 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6484 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6485 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
6487 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
6490 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6491 (FPT_scamInfo[i].id_string[0] == 0xFF))
6493 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6496 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6500 for(k = 0; k < ID_STRING_LENGTH; k++)
6501 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6505 /*---------------------------------------------------------------------
6507 * Function: FPT_scmachid
6509 * Description: Match the Device ID string with our values stored in
6512 *---------------------------------------------------------------------*/
6514 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
6517 unsigned char i,k,match;
6520 for (i=0; i < MAX_SCSI_TAR; i++) {
6524 for (k=0; k < ID_STRING_LENGTH; k++)
6526 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6532 FPT_scamInfo[i].state = ID_ASSIGNED;
6540 if (p_id_string[0] & BIT(5))
6545 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6546 match = p_id_string[1] & (unsigned char) 0x1F;
6554 if (FPT_scamInfo[match].state == ID_UNUSED)
6556 for (k=0; k < ID_STRING_LENGTH; k++)
6558 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6561 FPT_scamInfo[match].state = ID_ASSIGNED;
6563 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6564 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6574 if (p_id_string[0] & BIT(5))
6577 match = MAX_SCSI_TAR-1;
6583 if (p_id_string[0] & BIT(7))
6585 return(CLR_PRIORITY);
6589 if (p_id_string[0] & BIT(5))
6594 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6595 match = p_id_string[1] & (unsigned char) 0x1F;
6604 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
6606 for (k=0; k < ID_STRING_LENGTH; k++)
6608 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6611 FPT_scamInfo[match].id_string[0] |= BIT(7);
6612 FPT_scamInfo[match].state = ID_ASSIGNED;
6613 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6614 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6624 if (p_id_string[0] & BIT(5))
6627 match = MAX_SCSI_TAR-1;
6631 return(NO_ID_AVAIL);
6635 /*---------------------------------------------------------------------
6637 * Function: FPT_scsavdi
6639 * Description: Save off the device SCAM ID strings.
6641 *---------------------------------------------------------------------*/
6643 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
6645 unsigned char i,k,max_id;
6646 unsigned short ee_data,sum_data;
6651 for (i = 1; i < EE_SCAMBASE/2; i++)
6653 sum_data += FPT_utilEERead(p_port, i);
6657 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
6659 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6665 for (i=0; i < max_id; i++)
6668 for (k=0; k < ID_STRING_LENGTH; k+=2)
6670 ee_data = FPT_scamInfo[i].id_string[k+1];
6672 ee_data |= FPT_scamInfo[i].id_string[k];
6673 sum_data += ee_data;
6674 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6675 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6680 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6681 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
6684 /*---------------------------------------------------------------------
6686 * Function: FPT_XbowInit
6688 * Description: Setup the Xbow for normal operation.
6690 *---------------------------------------------------------------------*/
6692 static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
6696 i = RD_HARPOON(port+hp_page_ctrl);
6697 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
6699 WR_HARPOON(port+hp_scsireset,0x00);
6700 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6702 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6705 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6707 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6709 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6710 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6712 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6714 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6715 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6717 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6718 FPT_default_intena |= SCAM_SEL;
6720 WRW_HARPOON((port+hp_intena), FPT_default_intena);
6722 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6724 /* Turn on SCSI_MODE8 for narrow cards to fix the
6725 strapping issue with the DUAL CHANNEL card */
6726 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6727 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6729 WR_HARPOON(port+hp_page_ctrl, i);
6734 /*---------------------------------------------------------------------
6736 * Function: FPT_BusMasterInit
6738 * Description: Initialize the BusMaster for normal operations.
6740 *---------------------------------------------------------------------*/
6742 static void FPT_BusMasterInit(unsigned long p_port)
6746 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6747 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6749 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6752 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6754 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6757 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6758 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6759 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6764 /*---------------------------------------------------------------------
6766 * Function: FPT_DiagEEPROM
6768 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6771 *---------------------------------------------------------------------*/
6773 static void FPT_DiagEEPROM(unsigned long p_port)
6775 unsigned short index,temp,max_wd_cnt;
6777 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6778 max_wd_cnt = EEPROM_WD_CNT;
6780 max_wd_cnt = EEPROM_WD_CNT * 2;
6782 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
6784 if (temp == 0x4641) {
6786 for (index = 2; index < max_wd_cnt; index++) {
6788 temp += FPT_utilEERead(p_port, index);
6792 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
6794 return; /*EEPROM is Okay so return now! */
6799 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
6801 for (index = 0; index < max_wd_cnt; index++) {
6803 FPT_utilEEWrite(p_port, 0x0000, index);
6808 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
6810 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
6812 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
6814 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
6816 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
6818 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
6820 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
6822 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
6825 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
6827 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
6829 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
6832 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
6834 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
6836 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
6838 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
6840 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
6842 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
6844 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
6846 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
6850 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
6852 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
6854 FPT_utilEEWrite(p_port, 0x5068, 68/2);
6856 FPT_utilEEWrite(p_port, 0x696F, 70/2);
6858 FPT_utilEEWrite(p_port, 0x746E, 72/2);
6860 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
6862 FPT_utilEEWrite(p_port, 0x2054, 76/2);
6864 FPT_utilEEWrite(p_port, 0x2020, 78/2);
6867 index = ((EE_SCAMBASE/2)+(7*16));
6868 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
6869 temp += (0x0700+TYPE_CODE0);
6871 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6872 temp += 0x5542; /* BUSLOGIC */
6874 FPT_utilEEWrite(p_port, 0x4C53, index);
6877 FPT_utilEEWrite(p_port, 0x474F, index);
6880 FPT_utilEEWrite(p_port, 0x4349, index);
6883 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6884 temp += 0x5442; /* BT- 930 */
6886 FPT_utilEEWrite(p_port, 0x202D, index);
6889 FPT_utilEEWrite(p_port, 0x3339, index);
6891 index++; /*Serial # */
6892 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6895 FPT_utilEEWrite(p_port, 0x5453, index);
6898 FPT_utilEEWrite(p_port, 0x5645, index);
6901 FPT_utilEEWrite(p_port, 0x2045, index);
6904 FPT_utilEEWrite(p_port, 0x202F, index);
6907 FPT_utilEEWrite(p_port, 0x4F4A, index);
6910 FPT_utilEEWrite(p_port, 0x204E, index);
6913 FPT_utilEEWrite(p_port, 0x3539, index);
6918 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
6920 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
6925 /*---------------------------------------------------------------------
6927 * Function: Queue Search Select
6929 * Description: Try to find a new command to execute.
6931 *---------------------------------------------------------------------*/
6933 static void FPT_queueSearchSelect(struct sccb_card * pCurrCard, unsigned char p_card)
6935 unsigned char scan_ptr, lun;
6936 struct sccb_mgr_tar_info * currTar_Info;
6937 struct sccb * pOldSccb;
6939 scan_ptr = pCurrCard->scanIndex;
6942 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6943 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6944 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6946 if (currTar_Info->TarSelQ_Cnt != 0)
6950 if (scan_ptr == MAX_SCSI_TAR)
6953 for(lun=0; lun < MAX_LUN; lun++)
6955 if(currTar_Info->TarLUNBusy[lun] == 0)
6958 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6961 while((pCurrCard->currentSCCB != NULL) &&
6962 (lun != pCurrCard->currentSCCB->Lun))
6964 pOldSccb = pCurrCard->currentSCCB;
6965 pCurrCard->currentSCCB = (struct sccb *)(pCurrCard->currentSCCB)->
6968 if(pCurrCard->currentSCCB == NULL)
6970 if(pOldSccb != NULL)
6972 pOldSccb->Sccb_forwardlink = (struct sccb *)(pCurrCard->currentSCCB)->
6974 pOldSccb->Sccb_backlink = (struct sccb *)(pCurrCard->currentSCCB)->
6976 currTar_Info->TarSelQ_Cnt--;
6980 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6982 if (currTar_Info->TarSelQ_Head == NULL)
6984 currTar_Info->TarSelQ_Tail = NULL;
6985 currTar_Info->TarSelQ_Cnt = 0;
6989 currTar_Info->TarSelQ_Cnt--;
6990 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
6993 pCurrCard->scanIndex = scan_ptr;
6995 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7005 if (scan_ptr == MAX_SCSI_TAR) {
7013 if ((currTar_Info->TarSelQ_Cnt != 0) &&
7014 (currTar_Info->TarLUNBusy[0] == 0))
7017 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7019 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7021 if (currTar_Info->TarSelQ_Head == NULL)
7023 currTar_Info->TarSelQ_Tail = NULL;
7024 currTar_Info->TarSelQ_Cnt = 0;
7028 currTar_Info->TarSelQ_Cnt--;
7029 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
7033 if (scan_ptr == MAX_SCSI_TAR)
7036 pCurrCard->scanIndex = scan_ptr;
7038 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7046 if (scan_ptr == MAX_SCSI_TAR)
7052 } while (scan_ptr != pCurrCard->scanIndex);
7056 /*---------------------------------------------------------------------
7058 * Function: Queue Select Fail
7060 * Description: Add the current SCCB to the head of the Queue.
7062 *---------------------------------------------------------------------*/
7064 static void FPT_queueSelectFail(struct sccb_card * pCurrCard, unsigned char p_card)
7066 unsigned char thisTarg;
7067 struct sccb_mgr_tar_info * currTar_Info;
7069 if (pCurrCard->currentSCCB != NULL)
7071 thisTarg = (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->TargID);
7072 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7074 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
7076 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7078 if (currTar_Info->TarSelQ_Cnt == 0)
7080 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7085 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7089 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7091 pCurrCard->currentSCCB = NULL;
7092 currTar_Info->TarSelQ_Cnt++;
7095 /*---------------------------------------------------------------------
7097 * Function: Queue Command Complete
7099 * Description: Call the callback function with the current SCCB.
7101 *---------------------------------------------------------------------*/
7103 static void FPT_queueCmdComplete(struct sccb_card * pCurrCard, struct sccb * p_sccb,
7104 unsigned char p_card)
7107 unsigned char i, SCSIcmd;
7108 CALL_BK_FN callback;
7109 struct sccb_mgr_tar_info * currTar_Info;
7111 SCSIcmd = p_sccb->Cdb[0];
7114 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7116 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7117 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7118 (p_sccb->TargetStatus != SSCHECK))
7120 if ((SCSIcmd == SCSI_READ) ||
7121 (SCSIcmd == SCSI_WRITE) ||
7122 (SCSIcmd == SCSI_READ_EXTENDED) ||
7123 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7124 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7125 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7126 (pCurrCard->globalFlags & F_NO_FILTER)
7128 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7132 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7134 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7135 p_sccb->SccbStatus = SCCB_ERROR;
7137 p_sccb->SccbStatus = SCCB_SUCCESS;
7140 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7142 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7143 for (i=0; i < 6; i++) {
7144 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7148 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7149 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7151 FPT_utilUpdateResidual(p_sccb);
7154 pCurrCard->cmdCounter--;
7155 if (!pCurrCard->cmdCounter) {
7157 if (pCurrCard->globalFlags & F_GREEN_PC) {
7158 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7159 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7162 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7163 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7167 if(pCurrCard->discQCount != 0)
7169 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7170 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7171 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7173 pCurrCard->discQCount--;
7174 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7178 if(p_sccb->Sccb_tag)
7180 pCurrCard->discQCount--;
7181 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7184 pCurrCard->discQCount--;
7185 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7191 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7193 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7194 pCurrCard->currentSCCB = NULL;
7198 /*---------------------------------------------------------------------
7200 * Function: Queue Disconnect
7202 * Description: Add SCCB to our disconnect array.
7204 *---------------------------------------------------------------------*/
7205 static void FPT_queueDisconnect(struct sccb * p_sccb, unsigned char p_card)
7207 struct sccb_mgr_tar_info * currTar_Info;
7209 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7211 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7212 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7214 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
7218 if (p_sccb->Sccb_tag)
7220 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7221 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7222 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7225 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
7228 FPT_BL_Card[p_card].currentSCCB = NULL;
7232 /*---------------------------------------------------------------------
7234 * Function: Queue Flush SCCB
7236 * Description: Flush all SCCB's back to the host driver for this target.
7238 *---------------------------------------------------------------------*/
7240 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
7242 unsigned char qtag,thisTarg;
7243 struct sccb * currSCCB;
7244 struct sccb_mgr_tar_info * currTar_Info;
7246 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7247 if(currSCCB != NULL)
7249 thisTarg = (unsigned char)currSCCB->TargID;
7250 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7252 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7254 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7255 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7258 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7260 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7262 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7263 currTar_Info->TarTagQ_Cnt--;
7271 /*---------------------------------------------------------------------
7273 * Function: Queue Flush Target SCCB
7275 * Description: Flush all SCCB's back to the host driver for this target.
7277 *---------------------------------------------------------------------*/
7279 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7280 unsigned char error_code)
7283 struct sccb_mgr_tar_info * currTar_Info;
7285 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7287 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7289 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7290 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7293 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7295 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7297 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7298 currTar_Info->TarTagQ_Cnt--;
7309 static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char p_card)
7311 struct sccb_mgr_tar_info * currTar_Info;
7312 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7314 p_SCCB->Sccb_forwardlink = NULL;
7316 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7318 if (currTar_Info->TarSelQ_Cnt == 0) {
7320 currTar_Info->TarSelQ_Head = p_SCCB;
7325 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7329 currTar_Info->TarSelQ_Tail = p_SCCB;
7330 currTar_Info->TarSelQ_Cnt++;
7334 /*---------------------------------------------------------------------
7336 * Function: Queue Find SCCB
7338 * Description: Search the target select Queue for this SCCB, and
7339 * remove it if found.
7341 *---------------------------------------------------------------------*/
7343 static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card)
7345 struct sccb * q_ptr;
7346 struct sccb_mgr_tar_info * currTar_Info;
7348 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7350 q_ptr = currTar_Info->TarSelQ_Head;
7352 while(q_ptr != NULL) {
7354 if (q_ptr == p_SCCB) {
7357 if (currTar_Info->TarSelQ_Head == q_ptr) {
7359 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7362 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7364 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7367 if (q_ptr->Sccb_forwardlink != NULL) {
7368 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7371 if (q_ptr->Sccb_backlink != NULL) {
7372 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7375 currTar_Info->TarSelQ_Cnt--;
7381 q_ptr = q_ptr->Sccb_forwardlink;
7391 /*---------------------------------------------------------------------
7393 * Function: Utility Update Residual Count
7395 * Description: Update the XferCnt to the remaining byte count.
7396 * If we transferred all the data then just write zero.
7397 * If Non-SG transfer then report Total Cnt - Actual Transfer
7398 * Cnt. For SG transfers add the count fields of all
7399 * remaining SG elements, as well as any partial remaining
7402 *---------------------------------------------------------------------*/
7404 static void FPT_utilUpdateResidual(struct sccb * p_SCCB)
7406 unsigned long partial_cnt;
7407 unsigned int sg_index;
7408 unsigned long *sg_ptr;
7410 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7412 p_SCCB->DataLength = 0x0000;
7415 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7417 partial_cnt = 0x0000;
7419 sg_index = p_SCCB->Sccb_sgseg;
7421 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
7423 if (p_SCCB->Sccb_SGoffset) {
7425 partial_cnt = p_SCCB->Sccb_SGoffset;
7429 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
7430 p_SCCB->DataLength ) {
7432 partial_cnt += *(sg_ptr+(sg_index * 2));
7436 p_SCCB->DataLength = partial_cnt;
7441 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7446 /*---------------------------------------------------------------------
7448 * Function: Wait 1 Second
7450 * Description: Wait for 1 second.
7452 *---------------------------------------------------------------------*/
7454 static void FPT_Wait1Second(unsigned long p_port)
7458 for(i=0; i < 4; i++) {
7460 FPT_Wait(p_port, TO_250ms);
7462 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7465 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7471 /*---------------------------------------------------------------------
7473 * Function: FPT_Wait
7475 * Description: Wait the desired delay.
7477 *---------------------------------------------------------------------*/
7479 static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
7481 unsigned char old_timer;
7482 unsigned char green_flag;
7484 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7486 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7487 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7489 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7490 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7491 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
7494 WR_HARPOON(p_port+hp_portctrl_0,
7495 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7497 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7499 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7502 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7506 WR_HARPOON(p_port+hp_portctrl_0,
7507 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7509 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7510 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
7512 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7514 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7518 /*---------------------------------------------------------------------
7520 * Function: Enable/Disable Write to EEPROM
7522 * Description: The EEPROM must first be enabled for writes
7523 * A total of 9 clocks are needed.
7525 *---------------------------------------------------------------------*/
7527 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
7529 unsigned char ee_value;
7531 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7535 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7540 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7542 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7543 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7547 /*---------------------------------------------------------------------
7549 * Function: Write EEPROM
7551 * Description: Write a word to the EEPROM at the specified
7554 *---------------------------------------------------------------------*/
7556 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
7559 unsigned char ee_value;
7562 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7567 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7570 ee_value |= (SEE_MS + SEE_CS);
7572 for(i = 0x8000; i != 0; i>>=1) {
7577 ee_value &= ~SEE_DO;
7579 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7580 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7581 ee_value |= SEE_CLK; /* Clock data! */
7582 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7583 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7584 ee_value &= ~SEE_CLK;
7585 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7586 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7588 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7589 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7591 FPT_Wait(p_port, TO_10ms);
7593 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7594 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7595 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7598 /*---------------------------------------------------------------------
7600 * Function: Read EEPROM
7602 * Description: Read a word from the EEPROM at the desired
7605 *---------------------------------------------------------------------*/
7607 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
7609 unsigned short i, ee_data1, ee_data2;
7612 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7615 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7617 if(ee_data1 == ee_data2)
7620 ee_data1 = ee_data2;
7628 /*---------------------------------------------------------------------
7630 * Function: Read EEPROM Original
7632 * Description: Read a word from the EEPROM at the desired
7635 *---------------------------------------------------------------------*/
7637 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
7640 unsigned char ee_value;
7641 unsigned short i, ee_data;
7643 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7647 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7650 ee_value |= (SEE_MS + SEE_CS);
7653 for(i = 1; i <= 16; i++) {
7655 ee_value |= SEE_CLK; /* Clock data! */
7656 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7657 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7658 ee_value &= ~SEE_CLK;
7659 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7660 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7664 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7668 ee_value &= ~(SEE_MS + SEE_CS);
7669 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7670 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7676 /*---------------------------------------------------------------------
7678 * Function: Send EE command and Address to the EEPROM
7680 * Description: Transfers the correct command and sends the address
7683 *---------------------------------------------------------------------*/
7685 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
7687 unsigned char ee_value;
7688 unsigned char narrow_flg;
7693 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7697 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7699 ee_value |= SEE_CS; /* Set CS to EEPROM */
7700 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7703 for(i = 0x04; i != 0; i>>=1) {
7708 ee_value &= ~SEE_DO;
7710 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7711 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7712 ee_value |= SEE_CLK; /* Clock data! */
7713 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7714 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7715 ee_value &= ~SEE_CLK;
7716 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7717 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7733 ee_value &= ~SEE_DO;
7735 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7736 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7737 ee_value |= SEE_CLK; /* Clock data! */
7738 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7739 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7740 ee_value &= ~SEE_CLK;
7741 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7742 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7748 static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7750 unsigned short crc=0;
7753 for (i=0; i < ID_STRING_LENGTH; i++)
7755 ch = (unsigned short) buffer[i];
7756 for(j=0; j < 8; j++)
7759 crc = (crc >> 1) ^ CRCMASK;
7768 static unsigned char FPT_CalcLrc(unsigned char buffer[])
7773 for(i = 0; i < ID_STRING_LENGTH; i++)
7781 The following inline definitions avoid type conflicts.
7784 static inline unsigned char
7785 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7787 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
7791 static inline FlashPoint_CardHandle_T
7792 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7794 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
7798 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7800 FlashPoint_ReleaseHostAdapter(CardHandle);
7805 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7807 FlashPoint_StartCCB(CardHandle, (struct sccb *) CCB);
7812 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7814 FlashPoint_AbortCCB(CardHandle, (struct sccb *) CCB);
7818 static inline boolean
7819 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7821 return FlashPoint_InterruptPending(CardHandle);
7826 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7828 return FlashPoint_HandleInterrupt(CardHandle);
7832 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7833 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7834 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7835 #define FlashPoint_StartCCB FlashPoint__StartCCB
7836 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7837 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7838 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7841 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7845 Define prototypes for the FlashPoint SCCB Manager Functions.
7848 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7849 extern FlashPoint_CardHandle_T
7850 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7851 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7852 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7853 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7854 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7855 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7858 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */