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 */
307 typedef struct SCCBcard {
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];
325 typedef struct SCCBcard *PSCCBcard;
328 #define F_TAG_STARTED 0x01
329 #define F_CONLUN_IO 0x02
330 #define F_DO_RENEGO 0x04
331 #define F_NO_FILTER 0x08
332 #define F_GREEN_PC 0x10
333 #define F_HOST_XFER_ACT 0x20
334 #define F_NEW_SCCB_CMD 0x40
335 #define F_UPDATE_EEPROM 0x80
338 #define ID_STRING_LENGTH 32
339 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
342 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
344 #define ASSIGN_ID 0x00
345 #define SET_P_FLAG 0x01
346 #define CFG_CMPLT 0x03
347 #define DOM_MSTR 0x0F
348 #define SYNC_PTRN 0x1F
352 #define MISC_CODE 0x14
353 #define CLR_P_FLAG 0x18
357 #define INIT_SELTD 0x01
358 #define LEVEL2_TAR 0x02
361 enum scam_id_st { ID0,ID1,ID2,ID3,ID4,ID5,ID6,ID7,ID8,ID9,ID10,ID11,ID12,
362 ID13,ID14,ID15,ID_UNUSED,ID_UNASSIGNED,ID_ASSIGNED,LEGACY,
363 CLR_PRIORITY,NO_ID_AVAIL };
365 typedef struct SCCBscam_info {
367 unsigned char id_string[ID_STRING_LENGTH];
368 enum scam_id_st state;
373 #define SCSI_REQUEST_SENSE 0x03
374 #define SCSI_READ 0x08
375 #define SCSI_WRITE 0x0A
376 #define SCSI_START_STOP_UNIT 0x1B
377 #define SCSI_READ_EXTENDED 0x28
378 #define SCSI_WRITE_EXTENDED 0x2A
379 #define SCSI_WRITE_AND_VERIFY 0x2E
385 #define SSQ_FULL 0x28
390 #define SMCMD_COMP 0x00
392 #define SMSAVE_DATA_PTR 0x02
393 #define SMREST_DATA_PTR 0x03
396 #define SMREJECT 0x07
398 #define SMPARITY 0x09
399 #define SMDEV_RESET 0x0C
400 #define SMABORT_TAG 0x0D
401 #define SMINIT_RECOVERY 0x0F
402 #define SMREL_RECOVERY 0x10
405 #define DISC_PRIV 0x40
412 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
421 #define SIX_BYTE_CMD 0x06
422 #define TWELVE_BYTE_CMD 0x0C
425 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
428 #define EEPROM_WD_CNT 256
430 #define EEPROM_CHECK_SUM 0
431 #define FW_SIGNATURE 2
432 #define MODEL_NUMB_0 4
433 #define MODEL_NUMB_2 6
434 #define MODEL_NUMB_4 8
435 #define SYSTEM_CONFIG 16
436 #define SCSI_CONFIG 17
437 #define BIOS_CONFIG 18
438 #define SCAM_CONFIG 20
439 #define ADAPTER_SCSI_ID 24
442 #define IGNORE_B_SCAN 32
443 #define SEND_START_ENA 34
444 #define DEVICE_ENABLE 36
446 #define SYNC_RATE_TBL 38
447 #define SYNC_RATE_TBL01 38
448 #define SYNC_RATE_TBL23 40
449 #define SYNC_RATE_TBL45 42
450 #define SYNC_RATE_TBL67 44
451 #define SYNC_RATE_TBL89 46
452 #define SYNC_RATE_TBLab 48
453 #define SYNC_RATE_TBLcd 50
454 #define SYNC_RATE_TBLef 52
458 #define EE_SCAMBASE 256
462 #define SCAM_ENABLED BIT(2)
463 #define SCAM_LEVEL2 BIT(3)
466 #define RENEGO_ENA BITW(10)
467 #define CONNIO_ENA BITW(11)
468 #define GREEN_PC_ENA BITW(12)
471 #define AUTO_RATE_00 00
472 #define AUTO_RATE_05 01
473 #define AUTO_RATE_10 02
474 #define AUTO_RATE_20 03
476 #define WIDE_NEGO_BIT BIT(7)
477 #define DISC_ENABLE_BIT BIT(6)
481 #define hp_vendor_id_0 0x00 /* LSB */
482 #define ORION_VEND_0 0x4B
484 #define hp_vendor_id_1 0x01 /* MSB */
485 #define ORION_VEND_1 0x10
487 #define hp_device_id_0 0x02 /* LSB */
488 #define ORION_DEV_0 0x30
490 #define hp_device_id_1 0x03 /* MSB */
491 #define ORION_DEV_1 0x81
493 /* Sub Vendor ID and Sub Device ID only available in
494 Harpoon Version 2 and higher */
496 #define hp_sub_device_id_0 0x06 /* LSB */
500 #define hp_semaphore 0x0C
501 #define SCCB_MGR_ACTIVE BIT(0)
502 #define TICKLE_ME BIT(1)
503 #define SCCB_MGR_PRESENT BIT(3)
504 #define BIOS_IN_USE BIT(4)
508 #define hp_sys_ctrl 0x0F
510 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
511 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
512 #define HALT_MACH BIT(3) /*Halt State Machine */
513 #define HARD_ABORT BIT(4) /*Hard Abort */
523 #define hp_host_blk_cnt 0x13
525 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block*/
527 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes*/
531 #define hp_int_mask 0x17
533 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
534 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
537 #define hp_xfer_cnt_lo 0x18
538 #define hp_xfer_cnt_hi 0x1A
539 #define hp_xfer_cmd 0x1B
541 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
542 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
545 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
547 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
549 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
551 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
552 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
554 #define hp_host_addr_lo 0x1C
555 #define hp_host_addr_hmi 0x1E
557 #define hp_ee_ctrl 0x22
559 #define EXT_ARB_ACK BIT(7)
560 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
561 #define SEE_MS BIT(5)
562 #define SEE_CS BIT(3)
563 #define SEE_CLK BIT(2)
564 #define SEE_DO BIT(1)
565 #define SEE_DI BIT(0)
568 #define EE_WRITE 0x05
570 #define EWEN_ADDR 0x03C0
572 #define EWDS_ADDR 0x0000
580 #define hp_bm_ctrl 0x26
582 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
583 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
584 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
585 #define FAST_SINGLE BIT(6) /*?? */
587 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
590 #define hp_sg_addr 0x28
591 #define hp_page_ctrl 0x29
593 #define SCATTER_EN BIT(0)
594 #define SGRAM_ARAM BIT(1)
595 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
596 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
601 #define hp_pci_stat_cfg 0x2D
603 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
612 #define hp_rev_num 0x33
615 #define hp_stack_data 0x34
616 #define hp_stack_addr 0x35
618 #define hp_ext_status 0x36
620 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
621 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
622 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
623 #define CMD_ABORTED BIT(4) /*Command aborted */
624 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
625 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
626 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
627 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
628 BM_PARITY_ERR | PIO_OVERRUN)
630 #define hp_int_status 0x37
632 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
633 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
634 #define INT_ASSERTED BIT(5) /* */
637 #define hp_fifo_cnt 0x38
642 #define hp_intena 0x40
644 #define RESET BITW(7)
645 #define PROG_HLT BITW(6)
646 #define PARITY BITW(5)
649 #define SCAM_SEL BITW(2)
651 #define TIMEOUT BITW(0)
652 #define BUS_FREE BITW(15)
653 #define XFER_CNT_0 BITW(14)
654 #define PHASE BITW(13)
655 #define IUNKWN BITW(12)
656 #define ICMD_COMP BITW(11)
657 #define ITICKLE BITW(10)
658 #define IDO_STRT BITW(9)
659 #define ITAR_DISC BITW(8)
660 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
661 #define CLR_ALL_INT 0xFFFF
662 #define CLR_ALL_INT_1 0xFF00
664 #define hp_intstat 0x42
666 #define hp_scsisig 0x44
668 #define SCSI_SEL BIT(7)
669 #define SCSI_BSY BIT(6)
670 #define SCSI_REQ BIT(5)
671 #define SCSI_ACK BIT(4)
672 #define SCSI_ATN BIT(3)
673 #define SCSI_CD BIT(2)
674 #define SCSI_MSG BIT(1)
675 #define SCSI_IOBIT BIT(0)
677 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
678 #define S_MSGO_PH (BIT(2)+BIT(1) )
679 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
680 #define S_DATAI_PH ( BIT(0))
681 #define S_DATAO_PH 0x00
682 #define S_ILL_PH ( BIT(1) )
684 #define hp_scsictrl_0 0x45
686 #define SEL_TAR BIT(6)
687 #define ENA_ATN BIT(4)
688 #define ENA_RESEL BIT(2)
689 #define SCSI_RST BIT(1)
690 #define ENA_SCAM_SEL BIT(0)
694 #define hp_portctrl_0 0x46
696 #define SCSI_PORT BIT(7)
697 #define SCSI_INBIT BIT(6)
698 #define DMA_PORT BIT(5)
699 #define DMA_RD BIT(4)
700 #define HOST_PORT BIT(3)
701 #define HOST_WRT BIT(2)
702 #define SCSI_BUS_EN BIT(1)
703 #define START_TO BIT(0)
705 #define hp_scsireset 0x47
707 #define SCSI_INI BIT(6)
708 #define SCAM_EN BIT(5)
709 #define DMA_RESET BIT(3)
710 #define HPSCSI_RESET BIT(2)
711 #define PROG_RESET BIT(1)
712 #define FIFO_CLR BIT(0)
714 #define hp_xfercnt_0 0x48
715 #define hp_xfercnt_2 0x4A
717 #define hp_fifodata_0 0x4C
718 #define hp_addstat 0x4E
720 #define SCAM_TIMER BIT(7)
721 #define SCSI_MODE8 BIT(3)
722 #define SCSI_PAR_ERR BIT(0)
724 #define hp_prgmcnt_0 0x4F
727 #define hp_selfid_0 0x50
728 #define hp_selfid_1 0x51
729 #define hp_arb_id 0x52
732 #define hp_select_id 0x53
735 #define hp_synctarg_base 0x54
736 #define hp_synctarg_12 0x54
737 #define hp_synctarg_13 0x55
738 #define hp_synctarg_14 0x56
739 #define hp_synctarg_15 0x57
741 #define hp_synctarg_8 0x58
742 #define hp_synctarg_9 0x59
743 #define hp_synctarg_10 0x5A
744 #define hp_synctarg_11 0x5B
746 #define hp_synctarg_4 0x5C
747 #define hp_synctarg_5 0x5D
748 #define hp_synctarg_6 0x5E
749 #define hp_synctarg_7 0x5F
751 #define hp_synctarg_0 0x60
752 #define hp_synctarg_1 0x61
753 #define hp_synctarg_2 0x62
754 #define hp_synctarg_3 0x63
756 #define NARROW_SCSI BIT(4)
757 #define DEFAULT_OFFSET 0x0F
759 #define hp_autostart_0 0x64
760 #define hp_autostart_1 0x65
761 #define hp_autostart_3 0x67
765 #define AUTO_IMMED BIT(5)
766 #define SELECT BIT(6)
767 #define END_DATA (BIT(7)+BIT(6))
769 #define hp_gp_reg_0 0x68
770 #define hp_gp_reg_1 0x69
771 #define hp_gp_reg_3 0x6B
773 #define hp_seltimeout 0x6C
776 #define TO_4ms 0x67 /* 3.9959ms */
778 #define TO_5ms 0x03 /* 4.9152ms */
779 #define TO_10ms 0x07 /* 11.xxxms */
780 #define TO_250ms 0x99 /* 250.68ms */
781 #define TO_290ms 0xB1 /* 289.99ms */
783 #define hp_clkctrl_0 0x6D
785 #define PWR_DWN BIT(6)
786 #define ACTdeassert BIT(4)
787 #define CLK_40MHZ (BIT(1) + BIT(0))
789 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
791 #define hp_fiforead 0x6E
792 #define hp_fifowrite 0x6F
794 #define hp_offsetctr 0x70
795 #define hp_xferstat 0x71
797 #define FIFO_EMPTY BIT(6)
799 #define hp_portctrl_1 0x72
801 #define CHK_SCSI_P BIT(3)
802 #define HOST_MODE8 BIT(0)
804 #define hp_xfer_pad 0x73
806 #define ID_UNLOCK BIT(3)
808 #define hp_scsidata_0 0x74
809 #define hp_scsidata_1 0x75
813 #define hp_aramBase 0x80
814 #define BIOS_DATA_OFFSET 0x60
815 #define BIOS_RELATIVE_CARD 0x64
820 #define AR3 (BITW(9) + BITW(8))
821 #define SDATA BITW(10)
824 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
826 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
830 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
832 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
835 #define ADATA_OUT 0x00
836 #define ADATA_IN BITW(8)
837 #define ACOMMAND BITW(10)
838 #define ASTATUS (BITW(10)+BITW(8))
839 #define AMSG_OUT (BITW(10)+BITW(9))
840 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
843 #define BRH_OP BITW(13) /* Branch */
847 #define EQUAL BITW(8)
848 #define NOT_EQ BITW(9)
850 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
853 #define FIFO_0 BITW(10)
856 #define MPM_OP BITW(15) /* Match phase and move data */
859 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
862 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
867 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
877 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
879 #define SSI_OP (BITW(15)+BITW(11))
882 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
883 #define SSI_IDO_STRT (IDO_STRT >> 8)
885 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
886 #define SSI_ITICKLE (ITICKLE >> 8)
888 #define SSI_IUNKWN (IUNKWN >> 8)
889 #define SSI_INO_CC (IUNKWN >> 8)
890 #define SSI_IRFAIL (IUNKWN >> 8)
893 #define NP 0x10 /*Next Phase */
894 #define NTCMD 0x02 /*Non- Tagged Command start */
895 #define CMDPZ 0x04 /*Command phase */
896 #define DINT 0x12 /*Data Out/In interrupt */
897 #define DI 0x13 /*Data Out */
898 #define DC 0x19 /*Disconnect Message */
899 #define ST 0x1D /*Status Phase */
900 #define UNKNWN 0x24 /*Unknown bus action */
901 #define CC 0x25 /*Command Completion failure */
902 #define TICK 0x26 /*New target reselected us. */
903 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
906 #define ID_MSG_STRT hp_aramBase + 0x00
907 #define NON_TAG_ID_MSG hp_aramBase + 0x06
908 #define CMD_STRT hp_aramBase + 0x08
909 #define SYNC_MSGS hp_aramBase + 0x08
915 #define TAG_STRT 0x00
916 #define DISCONNECT_START 0x10/2
917 #define END_DATA_START 0x14/2
918 #define CMD_ONLY_STRT CMDPZ/2
919 #define SELCHK_STRT SELCHK/2
929 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
930 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
932 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
934 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
936 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
937 WR_HARP32(port,hp_xfercnt_0,count),\
938 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
940 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
942 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
943 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
946 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
947 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
951 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
952 WR_HARPOON(port+hp_scsireset, 0x00))
954 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
955 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
957 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
958 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
960 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
961 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
963 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
964 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
969 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag);
970 static void FPT_ssel(unsigned long port, unsigned char p_card);
971 static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard);
972 static void FPT_shandem(unsigned long port, unsigned char p_card,struct sccb * pCurrSCCB);
973 static void FPT_stsyncn(unsigned long port, unsigned char p_card);
974 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset);
975 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
976 struct sccb_mgr_tar_info * currTar_Info);
977 static void FPT_sresb(unsigned long port, unsigned char p_card);
978 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
979 static void FPT_schkdd(unsigned long port, unsigned char p_card);
980 static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
981 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data);
982 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
984 static void FPT_SendMsg(unsigned long port, unsigned char message);
985 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
986 unsigned char error_code);
988 static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card);
989 static void FPT_RNVRamData(struct nvram_info * pNvRamInfo);
991 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
992 static void FPT_stwidn(unsigned long port, unsigned char p_card);
993 static void FPT_siwidr(unsigned long port, unsigned char width);
996 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card);
997 static void FPT_queueDisconnect(struct sccb * p_SCCB, unsigned char p_card);
998 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_SCCB,
999 unsigned char p_card);
1000 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card);
1001 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
1002 static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char card);
1003 static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card);
1004 static void FPT_utilUpdateResidual(struct sccb * p_SCCB);
1005 static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
1006 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
1009 static void FPT_Wait1Second(unsigned long p_port);
1010 static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
1011 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode);
1012 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr);
1013 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr);
1014 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr);
1015 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr);
1019 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
1020 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
1021 static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
1022 static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
1023 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
1024 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
1025 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
1027 static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
1028 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
1029 static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
1034 static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
1035 static void FPT_BusMasterInit(unsigned long p_port);
1036 static void FPT_DiagEEPROM(unsigned long p_port);
1041 static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard);
1042 static void FPT_busMstrSGDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1043 static void FPT_busMstrDataXferStart(unsigned long port, struct sccb * pCurrSCCB);
1044 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB);
1045 static void FPT_hostDataXferRestart(struct sccb * currSCCB);
1048 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
1049 PSCCBcard pCurrCard, unsigned short p_int);
1051 static void FPT_SccbMgrTableInitAll(void);
1052 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card);
1053 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target);
1057 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up);
1059 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
1060 static void FPT_scbusf(unsigned long p_port);
1061 static void FPT_scsel(unsigned long p_port);
1062 static void FPT_scasid(unsigned char p_card, unsigned long p_port);
1063 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
1064 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[]);
1065 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[]);
1066 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
1067 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
1068 static unsigned char FPT_scvalq(unsigned char p_quintet);
1069 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
1070 static void FPT_scwtsel(unsigned long p_port);
1071 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id);
1072 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
1073 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[]);
1076 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
1077 static void FPT_autoLoadDefaultMap(unsigned long p_port);
1082 static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] = { { { 0 } } };
1083 static SCCBCARD FPT_BL_Card[MAX_CARDS] = { { 0 } };
1084 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { { { 0 } } };
1085 static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { { 0 } };
1088 static unsigned char FPT_mbCards = 0;
1089 static unsigned char FPT_scamHAString[] = {0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C', \
1090 ' ', 'B', 'T', '-', '9', '3', '0', \
1091 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, \
1092 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20};
1094 static unsigned short FPT_default_intena = 0;
1097 static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char)= { 0 };
1100 /*---------------------------------------------------------------------
1102 * Function: FlashPoint_ProbeHostAdapter
1104 * Description: Setup and/or Search for cards and return info to caller.
1106 *---------------------------------------------------------------------*/
1108 static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info * pCardInfo)
1110 static unsigned char first_time = 1;
1112 unsigned char i,j,id,ScamFlg;
1113 unsigned short temp,temp2,temp3,temp4,temp5,temp6;
1114 unsigned long ioport;
1115 struct nvram_info * pCurrNvRam;
1117 ioport = pCardInfo->si_baseaddr;
1120 if (RD_HARPOON(ioport+hp_vendor_id_0) != ORION_VEND_0)
1121 return((int)FAILURE);
1123 if ((RD_HARPOON(ioport+hp_vendor_id_1) != ORION_VEND_1))
1124 return((int)FAILURE);
1126 if ((RD_HARPOON(ioport+hp_device_id_0) != ORION_DEV_0))
1127 return((int)FAILURE);
1129 if ((RD_HARPOON(ioport+hp_device_id_1) != ORION_DEV_1))
1130 return((int)FAILURE);
1133 if (RD_HARPOON(ioport+hp_rev_num) != 0x0f){
1135 /* For new Harpoon then check for sub_device ID LSB
1136 the bits(0-3) must be all ZERO for compatible with
1137 current version of SCCBMgr, else skip this Harpoon
1140 if (RD_HARPOON(ioport+hp_sub_device_id_0) & 0x0f)
1141 return((int)FAILURE);
1146 FPT_SccbMgrTableInitAll();
1151 if(FPT_RdStack(ioport, 0) != 0x00) {
1152 if(FPT_ChkIfChipInitialized(ioport) == 0)
1155 WR_HARPOON(ioport+hp_semaphore, 0x00);
1156 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
1157 FPT_DiagEEPROM(ioport);
1161 if(FPT_mbCards < MAX_MB_CARDS) {
1162 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
1164 pCurrNvRam->niBaseAddr = ioport;
1165 FPT_RNVRamData(pCurrNvRam);
1167 return((int) FAILURE);
1172 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1173 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1176 pCardInfo->si_id = pCurrNvRam->niAdapId;
1178 pCardInfo->si_id = (unsigned char)(FPT_utilEERead(ioport, (ADAPTER_SCSI_ID/2)) &
1179 (unsigned char)0x0FF);
1181 pCardInfo->si_lun = 0x00;
1182 pCardInfo->si_fw_revision = ORION_FW_REV;
1189 for (id = 0; id < (16/2); id++) {
1192 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1193 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1194 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1196 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1198 for (i = 0; i < 2; temp >>=8,i++) {
1207 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1208 temp6 |= 0x8000; /* Fall through */
1209 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1210 temp5 |= 0x8000; /* Fall through */
1211 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1212 temp2 |= 0x8000; /* Fall through */
1213 case AUTO_RATE_00: /* Asynchronous */
1217 if (temp & DISC_ENABLE_BIT)
1220 if (temp & WIDE_NEGO_BIT)
1226 pCardInfo->si_per_targ_init_sync = temp2;
1227 pCardInfo->si_per_targ_no_disc = temp3;
1228 pCardInfo->si_per_targ_wide_nego = temp4;
1229 pCardInfo->si_per_targ_fast_nego = temp5;
1230 pCardInfo->si_per_targ_ultra_nego = temp6;
1233 i = pCurrNvRam->niSysConf;
1235 i = (unsigned char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)));
1238 ScamFlg = pCurrNvRam->niScamConf;
1240 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1242 pCardInfo->si_flags = 0x0000;
1245 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1248 pCardInfo->si_flags |= SOFT_RESET;
1251 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1253 if (ScamFlg & SCAM_ENABLED)
1254 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1256 if (ScamFlg & SCAM_LEVEL2)
1257 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1259 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1261 j |= SCSI_TERM_ENA_L;
1263 WR_HARPOON(ioport+hp_bm_ctrl, j );
1265 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1267 j |= SCSI_TERM_ENA_H;
1269 WR_HARPOON(ioport+hp_ee_ctrl, j );
1271 if (!(RD_HARPOON(ioport+hp_page_ctrl) & NARROW_SCSI_CARD))
1273 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1275 pCardInfo->si_card_family = HARPOON_FAMILY;
1276 pCardInfo->si_bustype = BUSTYPE_PCI;
1279 pCardInfo->si_card_model[0] = '9';
1280 switch(pCurrNvRam->niModel & 0x0f){
1282 pCardInfo->si_card_model[1] = '3';
1283 pCardInfo->si_card_model[2] = '0';
1286 pCardInfo->si_card_model[1] = '5';
1287 pCardInfo->si_card_model[2] = '0';
1290 pCardInfo->si_card_model[1] = '3';
1291 pCardInfo->si_card_model[2] = '2';
1294 pCardInfo->si_card_model[1] = '5';
1295 pCardInfo->si_card_model[2] = '2';
1299 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0/2));
1300 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1301 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2/2));
1303 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1304 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1307 if (pCardInfo->si_card_model[1] == '3')
1309 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1310 pCardInfo->si_flags |= LOW_BYTE_TERM;
1312 else if (pCardInfo->si_card_model[2] == '0')
1314 temp = RD_HARPOON(ioport+hp_xfer_pad);
1315 WR_HARPOON(ioport+hp_xfer_pad, (temp & ~BIT(4)));
1316 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1317 pCardInfo->si_flags |= LOW_BYTE_TERM;
1318 WR_HARPOON(ioport+hp_xfer_pad, (temp | BIT(4)));
1319 if (RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7))
1320 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1321 WR_HARPOON(ioport+hp_xfer_pad, temp);
1325 temp = RD_HARPOON(ioport+hp_ee_ctrl);
1326 temp2 = RD_HARPOON(ioport+hp_xfer_pad);
1327 WR_HARPOON(ioport+hp_ee_ctrl, (temp | SEE_CS));
1328 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1330 for (i = 0; i < 8; i++)
1333 if (!(RD_HARPOON(ioport+hp_ee_ctrl) & BIT(7)))
1335 WR_HARPOON(ioport+hp_xfer_pad, (temp2 & ~BIT(4)));
1336 WR_HARPOON(ioport+hp_xfer_pad, (temp2 | BIT(4)));
1338 WR_HARPOON(ioport+hp_ee_ctrl, temp);
1339 WR_HARPOON(ioport+hp_xfer_pad, temp2);
1340 if (!(temp3 & BIT(7)))
1341 pCardInfo->si_flags |= LOW_BYTE_TERM;
1342 if (!(temp3 & BIT(6)))
1343 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1347 ARAM_ACCESS(ioport);
1349 for ( i = 0; i < 4; i++ ) {
1351 pCardInfo->si_XlatInfo[i] =
1352 RD_HARPOON(ioport+hp_aramBase+BIOS_DATA_OFFSET+i);
1355 /* return with -1 if no sort, else return with
1356 logical card number sorted by BIOS (zero-based) */
1358 pCardInfo->si_relative_cardnum =
1359 (unsigned char)(RD_HARPOON(ioport+hp_aramBase+BIOS_RELATIVE_CARD)-1);
1361 SGRAM_ACCESS(ioport);
1363 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1364 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1365 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1366 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1367 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1368 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1369 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1370 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1372 pCardInfo->si_present = 0x01;
1378 /*---------------------------------------------------------------------
1380 * Function: FlashPoint_HardwareResetHostAdapter
1382 * Description: Setup adapter for normal operation (hard reset).
1384 *---------------------------------------------------------------------*/
1386 static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info * pCardInfo)
1388 PSCCBcard CurrCard = NULL;
1389 struct nvram_info * pCurrNvRam;
1390 unsigned char i,j,thisCard, ScamFlg;
1391 unsigned short temp,sync_bit_map,id;
1392 unsigned long ioport;
1394 ioport = pCardInfo->si_baseaddr;
1396 for(thisCard =0; thisCard <= MAX_CARDS; thisCard++) {
1398 if (thisCard == MAX_CARDS) {
1403 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1405 CurrCard = &FPT_BL_Card[thisCard];
1406 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1410 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1412 FPT_BL_Card[thisCard].ioPort = ioport;
1413 CurrCard = &FPT_BL_Card[thisCard];
1416 for(i = 0; i < FPT_mbCards; i++){
1417 if(CurrCard->ioPort == FPT_nvRamInfo[i].niBaseAddr)
1418 CurrCard->pNvRamInfo = &FPT_nvRamInfo[i];
1420 FPT_SccbMgrTableInitCard(CurrCard,thisCard);
1421 CurrCard->cardIndex = thisCard;
1422 CurrCard->cardInfo = pCardInfo;
1428 pCurrNvRam = CurrCard->pNvRamInfo;
1431 ScamFlg = pCurrNvRam->niScamConf;
1434 ScamFlg = (unsigned char) FPT_utilEERead(ioport, SCAM_CONFIG/2);
1438 FPT_BusMasterInit(ioport);
1439 FPT_XbowInit(ioport, ScamFlg);
1441 FPT_autoLoadDefaultMap(ioport);
1444 for (i = 0,id = 0x01; i != pCardInfo->si_id; i++,id <<= 1){}
1446 WR_HARPOON(ioport+hp_selfid_0, id);
1447 WR_HARPOON(ioport+hp_selfid_1, 0x00);
1448 WR_HARPOON(ioport+hp_arb_id, pCardInfo->si_id);
1449 CurrCard->ourId = pCardInfo->si_id;
1451 i = (unsigned char) pCardInfo->si_flags;
1452 if (i & SCSI_PARITY_ENA)
1453 WR_HARPOON(ioport+hp_portctrl_1,(HOST_MODE8 | CHK_SCSI_P));
1455 j = (RD_HARPOON(ioport+hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1456 if (i & LOW_BYTE_TERM)
1457 j |= SCSI_TERM_ENA_L;
1458 WR_HARPOON(ioport+hp_bm_ctrl, j);
1460 j = (RD_HARPOON(ioport+hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1461 if (i & HIGH_BYTE_TERM)
1462 j |= SCSI_TERM_ENA_H;
1463 WR_HARPOON(ioport+hp_ee_ctrl, j );
1466 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1468 FPT_sresb(ioport,thisCard);
1470 FPT_scini(thisCard, pCardInfo->si_id, 0);
1475 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1476 CurrCard->globalFlags |= F_NO_FILTER;
1479 if(pCurrNvRam->niSysConf & 0x10)
1480 CurrCard->globalFlags |= F_GREEN_PC;
1483 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG/2)) & GREEN_PC_ENA)
1484 CurrCard->globalFlags |= F_GREEN_PC;
1487 /* Set global flag to indicate Re-Negotiation to be done on all
1490 if(pCurrNvRam->niScsiConf & 0x04)
1491 CurrCard->globalFlags |= F_DO_RENEGO;
1494 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & RENEGO_ENA)
1495 CurrCard->globalFlags |= F_DO_RENEGO;
1499 if(pCurrNvRam->niScsiConf & 0x08)
1500 CurrCard->globalFlags |= F_CONLUN_IO;
1503 if (FPT_utilEERead(ioport, (SCSI_CONFIG/2)) & CONNIO_ENA)
1504 CurrCard->globalFlags |= F_CONLUN_IO;
1508 temp = pCardInfo->si_per_targ_no_disc;
1510 for (i = 0,id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1513 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1516 sync_bit_map = 0x0001;
1518 for (id = 0; id < (MAX_SCSI_TAR/2); id++) {
1521 temp = (unsigned short) pCurrNvRam->niSyncTbl[id];
1522 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1523 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1525 temp = FPT_utilEERead(ioport, (unsigned short)((SYNC_RATE_TBL/2)+id));
1527 for (i = 0; i < 2; temp >>=8,i++) {
1529 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1531 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue = (unsigned char)temp;
1535 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= SYNC_SUPPORTED;
1536 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue =
1537 (unsigned char)(temp & ~EE_SYNC_MASK);
1540 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1543 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map){
1545 FPT_sccbMgrTbl[thisCard][id*2+i].TarEEValue |= EE_WIDE_SCSI;
1549 else { /* NARROW SCSI */
1550 FPT_sccbMgrTbl[thisCard][id*2+i].TarStatus |= WIDE_NEGOCIATED;
1561 WR_HARPOON((ioport+hp_semaphore),
1562 (unsigned char)(RD_HARPOON((ioport+hp_semaphore)) | SCCB_MGR_PRESENT));
1564 return((unsigned long)CurrCard);
1567 static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
1570 unsigned long portBase;
1571 unsigned long regOffset;
1572 unsigned long scamData;
1573 unsigned long *pScamTbl;
1574 struct nvram_info * pCurrNvRam;
1576 pCurrNvRam = ((PSCCBcard)pCurrCard)->pNvRamInfo;
1579 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1580 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1581 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1582 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1583 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1585 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1586 FPT_WrStack(pCurrNvRam->niBaseAddr, (unsigned char)(i+5), pCurrNvRam->niSyncTbl[i]);
1588 portBase = pCurrNvRam->niBaseAddr;
1590 for(i = 0; i < MAX_SCSI_TAR; i++){
1591 regOffset = hp_aramBase + 64 + i*4;
1592 pScamTbl = (unsigned long *) &pCurrNvRam->niScamTbl[i];
1593 scamData = *pScamTbl;
1594 WR_HARP32(portBase, regOffset, scamData);
1598 FPT_WrStack(((PSCCBcard)pCurrCard)->ioPort, 0, 0);
1603 static void FPT_RNVRamData(struct nvram_info * pNvRamInfo)
1606 unsigned long portBase;
1607 unsigned long regOffset;
1608 unsigned long scamData;
1609 unsigned long *pScamTbl;
1611 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1612 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1613 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1614 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1615 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1617 for(i = 0; i < MAX_SCSI_TAR / 2; i++)
1618 pNvRamInfo->niSyncTbl[i] = FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i+5));
1620 portBase = pNvRamInfo->niBaseAddr;
1622 for(i = 0; i < MAX_SCSI_TAR; i++){
1623 regOffset = hp_aramBase + 64 + i*4;
1624 RD_HARP32(portBase, regOffset, scamData);
1625 pScamTbl = (unsigned long *) &pNvRamInfo->niScamTbl[i];
1626 *pScamTbl = scamData;
1631 static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
1633 WR_HARPOON(portBase + hp_stack_addr, index);
1634 return(RD_HARPOON(portBase + hp_stack_data));
1637 static void FPT_WrStack(unsigned long portBase, unsigned char index, unsigned char data)
1639 WR_HARPOON(portBase + hp_stack_addr, index);
1640 WR_HARPOON(portBase + hp_stack_data, data);
1644 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
1646 if((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1648 if((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1651 if((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1652 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1657 /*---------------------------------------------------------------------
1659 * Function: FlashPoint_StartCCB
1661 * Description: Start a command pointed to by p_Sccb. When the
1662 * command is completed it will be returned via the
1663 * callback function.
1665 *---------------------------------------------------------------------*/
1666 static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
1668 unsigned long ioport;
1669 unsigned char thisCard, lun;
1670 struct sccb * pSaveSccb;
1671 CALL_BK_FN callback;
1673 thisCard = ((PSCCBcard) pCurrCard)->cardIndex;
1674 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1676 if((p_Sccb->TargID > MAX_SCSI_TAR) || (p_Sccb->Lun > MAX_LUN))
1679 p_Sccb->HostStatus = SCCB_COMPLETE;
1680 p_Sccb->SccbStatus = SCCB_ERROR;
1681 callback = (CALL_BK_FN)p_Sccb->SccbCallback;
1688 FPT_sinits(p_Sccb,thisCard);
1691 if (!((PSCCBcard) pCurrCard)->cmdCounter)
1693 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1694 | SCCB_MGR_ACTIVE));
1696 if (((PSCCBcard) pCurrCard)->globalFlags & F_GREEN_PC)
1698 WR_HARPOON(ioport+hp_clkctrl_0, CLKCTRL_DEFAULT);
1699 WR_HARPOON(ioport+hp_sys_ctrl, 0x00);
1703 ((PSCCBcard)pCurrCard)->cmdCounter++;
1705 if (RD_HARPOON(ioport+hp_semaphore) & BIOS_IN_USE) {
1707 WR_HARPOON(ioport+hp_semaphore, (RD_HARPOON(ioport+hp_semaphore)
1709 if(p_Sccb->OperationCode == RESET_COMMAND)
1711 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1712 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1713 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1714 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1718 FPT_queueAddSccb(p_Sccb,thisCard);
1722 else if ((RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE)) {
1724 if(p_Sccb->OperationCode == RESET_COMMAND)
1726 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1727 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1728 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1729 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1733 FPT_queueAddSccb(p_Sccb,thisCard);
1739 MDISABLE_INT(ioport);
1741 if((((PSCCBcard) pCurrCard)->globalFlags & F_CONLUN_IO) &&
1742 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1746 if ((((PSCCBcard) pCurrCard)->currentSCCB == NULL) &&
1747 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0) &&
1748 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1751 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1752 FPT_ssel(p_Sccb->SccbIOPort,thisCard);
1757 if(p_Sccb->OperationCode == RESET_COMMAND)
1759 pSaveSccb = ((PSCCBcard) pCurrCard)->currentSCCB;
1760 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1761 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1762 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSccb;
1766 FPT_queueAddSccb(p_Sccb,thisCard);
1771 MENABLE_INT(ioport);
1777 /*---------------------------------------------------------------------
1779 * Function: FlashPoint_AbortCCB
1781 * Description: Abort the command pointed to by p_Sccb. When the
1782 * command is completed it will be returned via the
1783 * callback function.
1785 *---------------------------------------------------------------------*/
1786 static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb * p_Sccb)
1788 unsigned long ioport;
1790 unsigned char thisCard;
1791 CALL_BK_FN callback;
1793 struct sccb * pSaveSCCB;
1794 struct sccb_mgr_tar_info * currTar_Info;
1797 ioport = ((PSCCBcard) pCurrCard)->ioPort;
1799 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1801 if (!(RD_HARPOON(ioport+hp_page_ctrl) & G_INT_DISABLE))
1804 if (FPT_queueFindSccb(p_Sccb,thisCard))
1807 ((PSCCBcard)pCurrCard)->cmdCounter--;
1809 if (!((PSCCBcard)pCurrCard)->cmdCounter)
1810 WR_HARPOON(ioport+hp_semaphore,(RD_HARPOON(ioport+hp_semaphore)
1811 & (unsigned char)(~(SCCB_MGR_ACTIVE | TICKLE_ME)) ));
1813 p_Sccb->SccbStatus = SCCB_ABORT;
1814 callback = p_Sccb->SccbCallback;
1822 if (((PSCCBcard)pCurrCard)->currentSCCB == p_Sccb)
1824 p_Sccb->SccbStatus = SCCB_ABORT;
1832 TID = p_Sccb->TargID;
1835 if(p_Sccb->Sccb_tag)
1837 MDISABLE_INT(ioport);
1838 if (((PSCCBcard) pCurrCard)->discQ_Tbl[p_Sccb->Sccb_tag]==p_Sccb)
1840 p_Sccb->SccbStatus = SCCB_ABORT;
1841 p_Sccb->Sccb_scsistat = ABORT_ST;
1842 p_Sccb->Sccb_scsimsg = SMABORT_TAG;
1844 if(((PSCCBcard) pCurrCard)->currentSCCB == NULL)
1846 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1847 FPT_ssel(ioport, thisCard);
1851 pSaveSCCB = ((PSCCBcard) pCurrCard)->currentSCCB;
1852 ((PSCCBcard) pCurrCard)->currentSCCB = p_Sccb;
1853 FPT_queueSelectFail((PSCCBcard) pCurrCard, thisCard);
1854 ((PSCCBcard) pCurrCard)->currentSCCB = pSaveSCCB;
1857 MENABLE_INT(ioport);
1862 currTar_Info = &FPT_sccbMgrTbl[thisCard][p_Sccb->TargID];
1864 if(FPT_BL_Card[thisCard].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_Sccb->Lun]]
1867 p_Sccb->SccbStatus = SCCB_ABORT;
1878 /*---------------------------------------------------------------------
1880 * Function: FlashPoint_InterruptPending
1882 * Description: Do a quick check to determine if there is a pending
1883 * interrupt for this card and disable the IRQ Pin if so.
1885 *---------------------------------------------------------------------*/
1886 static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
1888 unsigned long ioport;
1890 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1892 if (RD_HARPOON(ioport+hp_int_status) & INT_ASSERTED)
1904 /*---------------------------------------------------------------------
1906 * Function: FlashPoint_HandleInterrupt
1908 * Description: This is our entry point when an interrupt is generated
1909 * by the card and the upper level driver passes it on to
1912 *---------------------------------------------------------------------*/
1913 static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
1915 struct sccb * currSCCB;
1916 unsigned char thisCard,result,bm_status, bm_int_st;
1917 unsigned short hp_int;
1918 unsigned char i, target;
1919 unsigned long ioport;
1921 thisCard = ((PSCCBcard)pCurrCard)->cardIndex;
1922 ioport = ((PSCCBcard)pCurrCard)->ioPort;
1924 MDISABLE_INT(ioport);
1926 if ((bm_int_st=RD_HARPOON(ioport+hp_int_status)) & EXT_STATUS_ON)
1927 bm_status = RD_HARPOON(ioport+hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
1931 WR_HARPOON(ioport+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1933 while ((hp_int = RDW_HARPOON((ioport+hp_intstat)) & FPT_default_intena) |
1937 currSCCB = ((PSCCBcard)pCurrCard)->currentSCCB;
1939 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1940 result = FPT_SccbMgr_bad_isr(ioport,thisCard,((PSCCBcard)pCurrCard),hp_int);
1941 WRW_HARPOON((ioport+hp_intstat), (FIFO | TIMEOUT | RESET | SCAM_SEL));
1946 MENABLE_INT(ioport);
1952 else if (hp_int & ICMD_COMP) {
1954 if ( !(hp_int & BUS_FREE) ) {
1955 /* Wait for the BusFree before starting a new command. We
1956 must also check for being reselected since the BusFree
1957 may not show up if another device reselects us in 1.5us or
1958 less. SRR Wednesday, 3/8/1995.
1960 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL))) ;
1963 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
1965 FPT_phaseChkFifo(ioport, thisCard);
1967 /* WRW_HARPOON((ioport+hp_intstat),
1968 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1971 WRW_HARPOON((ioport+hp_intstat), CLR_ALL_INT_1);
1973 FPT_autoCmdCmplt(ioport,thisCard);
1978 else if (hp_int & ITAR_DISC)
1981 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
1983 FPT_phaseChkFifo(ioport, thisCard);
1987 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1989 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
1990 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1992 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1995 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1996 FPT_queueDisconnect(currSCCB,thisCard);
1998 /* Wait for the BusFree before starting a new command. We
1999 must also check for being reselected since the BusFree
2000 may not show up if another device reselects us in 1.5us or
2001 less. SRR Wednesday, 3/8/1995.
2003 while (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)) &&
2004 !((RDW_HARPOON((ioport+hp_intstat)) & PHASE) &&
2005 RD_HARPOON((ioport+hp_scsisig)) ==
2006 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG | SCSI_IOBIT))) ;
2009 The additional loop exit condition above detects a timing problem
2010 with the revision D/E harpoon chips. The caller should reset the
2011 host adapter to recover when 0xFE is returned.
2013 if (!(RDW_HARPOON((ioport+hp_intstat)) & (BUS_FREE | RSEL)))
2015 MENABLE_INT(ioport);
2019 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2022 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2027 else if (hp_int & RSEL) {
2029 WRW_HARPOON((ioport+hp_intstat), (PROG_HLT | RSEL | PHASE | BUS_FREE));
2031 if (RDW_HARPOON((ioport+hp_intstat)) & ITAR_DISC)
2033 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT)
2035 FPT_phaseChkFifo(ioport, thisCard);
2038 if (RD_HARPOON(ioport+hp_gp_reg_1) == SMSAVE_DATA_PTR)
2040 WR_HARPOON(ioport+hp_gp_reg_1, 0x00);
2041 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
2042 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
2045 WRW_HARPOON((ioport+hp_intstat), (BUS_FREE | ITAR_DISC));
2046 currSCCB->Sccb_scsistat = DISCONNECT_ST;
2047 FPT_queueDisconnect(currSCCB,thisCard);
2050 FPT_sres(ioport,thisCard,((PSCCBcard)pCurrCard));
2051 FPT_phaseDecode(ioport,thisCard);
2056 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE)))
2059 WRW_HARPOON((ioport+hp_intstat), (IDO_STRT | XFER_CNT_0));
2060 FPT_phaseDecode(ioport,thisCard);
2065 else if ( (hp_int & IUNKWN) || (hp_int & PROG_HLT) )
2067 WRW_HARPOON((ioport+hp_intstat), (PHASE | IUNKWN | PROG_HLT));
2068 if ((RD_HARPOON(ioport+hp_prgmcnt_0) & (unsigned char)0x3f)< (unsigned char)SELCHK)
2070 FPT_phaseDecode(ioport,thisCard);
2074 /* Harpoon problem some SCSI target device respond to selection
2075 with short BUSY pulse (<400ns) this will make the Harpoon is not able
2076 to latch the correct Target ID into reg. x53.
2077 The work around require to correct this reg. But when write to this
2078 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
2079 need to read this reg first then restore it later. After update to 0x53 */
2081 i = (unsigned char)(RD_HARPOON(ioport+hp_fifowrite));
2082 target = (unsigned char)(RD_HARPOON(ioport+hp_gp_reg_3));
2083 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) ID_UNLOCK);
2084 WR_HARPOON(ioport+hp_select_id, (unsigned char)(target | target<<4));
2085 WR_HARPOON(ioport+hp_xfer_pad, (unsigned char) 0x00);
2086 WR_HARPOON(ioport+hp_fifowrite, i);
2087 WR_HARPOON(ioport+hp_autostart_3, (AUTO_IMMED+TAG_STRT));
2091 else if (hp_int & XFER_CNT_0) {
2093 WRW_HARPOON((ioport+hp_intstat), XFER_CNT_0);
2095 FPT_schkdd(ioport,thisCard);
2100 else if (hp_int & BUS_FREE) {
2102 WRW_HARPOON((ioport+hp_intstat), BUS_FREE);
2104 if (((PSCCBcard)pCurrCard)->globalFlags & F_HOST_XFER_ACT) {
2106 FPT_hostDataXferAbort(ioport,thisCard,currSCCB);
2109 FPT_phaseBusFree(ioport,thisCard);
2113 else if (hp_int & ITICKLE) {
2115 WRW_HARPOON((ioport+hp_intstat), ITICKLE);
2116 ((PSCCBcard)pCurrCard)->globalFlags |= F_NEW_SCCB_CMD;
2121 if (((PSCCBcard)pCurrCard)->globalFlags & F_NEW_SCCB_CMD) {
2124 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2127 if (((PSCCBcard)pCurrCard)->currentSCCB == NULL) {
2129 FPT_queueSearchSelect(((PSCCBcard)pCurrCard),thisCard);
2132 if (((PSCCBcard)pCurrCard)->currentSCCB != NULL) {
2133 ((PSCCBcard)pCurrCard)->globalFlags &= ~F_NEW_SCCB_CMD;
2134 FPT_ssel(ioport,thisCard);
2143 MENABLE_INT(ioport);
2148 /*---------------------------------------------------------------------
2150 * Function: Sccb_bad_isr
2152 * Description: Some type of interrupt has occurred which is slightly
2153 * out of the ordinary. We will now decode it fully, in
2154 * this routine. This is broken up in an attempt to save
2157 *---------------------------------------------------------------------*/
2158 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port, unsigned char p_card,
2159 PSCCBcard pCurrCard, unsigned short p_int)
2161 unsigned char temp, ScamFlg;
2162 struct sccb_mgr_tar_info * currTar_Info;
2163 struct nvram_info * pCurrNvRam;
2166 if (RD_HARPOON(p_port+hp_ext_status) &
2167 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN) )
2170 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2173 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2176 if (RD_HARPOON(p_port+hp_pci_stat_cfg) & REC_MASTER_ABORT)
2179 WR_HARPOON(p_port+hp_pci_stat_cfg,
2180 (RD_HARPOON(p_port+hp_pci_stat_cfg) & ~REC_MASTER_ABORT));
2182 WR_HARPOON(p_port+hp_host_blk_cnt, 0x00);
2186 if (pCurrCard->currentSCCB != NULL)
2189 if (!pCurrCard->currentSCCB->HostStatus)
2190 pCurrCard->currentSCCB->HostStatus = SCCB_BM_ERR;
2192 FPT_sxfrp(p_port,p_card);
2194 temp = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) &
2195 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2196 WR_HARPOON(p_port+hp_ee_ctrl, ((unsigned char)temp | SEE_MS | SEE_CS));
2197 WR_HARPOON(p_port+hp_ee_ctrl, temp);
2199 if (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
2201 FPT_phaseDecode(p_port,p_card);
2207 else if (p_int & RESET)
2210 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
2211 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
2212 if (pCurrCard->currentSCCB != NULL) {
2214 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2216 FPT_hostDataXferAbort(p_port,p_card, pCurrCard->currentSCCB);
2220 DISABLE_AUTO(p_port);
2222 FPT_sresb(p_port,p_card);
2224 while(RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST) {}
2226 pCurrNvRam = pCurrCard->pNvRamInfo;
2228 ScamFlg = pCurrNvRam->niScamConf;
2231 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
2234 FPT_XbowInit(p_port, ScamFlg);
2236 FPT_scini(p_card, pCurrCard->ourId, 0);
2242 else if (p_int & FIFO) {
2244 WRW_HARPOON((p_port+hp_intstat), FIFO);
2246 if (pCurrCard->currentSCCB != NULL)
2247 FPT_sxfrp(p_port,p_card);
2250 else if (p_int & TIMEOUT)
2253 DISABLE_AUTO(p_port);
2255 WRW_HARPOON((p_port+hp_intstat),
2256 (PROG_HLT | TIMEOUT | SEL |BUS_FREE | PHASE | IUNKWN));
2258 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2261 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2262 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
2263 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2264 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] = 0;
2266 currTar_Info->TarLUNBusy[0] = 0;
2269 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2271 currTar_Info->TarSyncCtrl = 0;
2272 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2275 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2277 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2280 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,currTar_Info);
2282 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2286 else if (p_int & SCAM_SEL)
2289 FPT_scarb(p_port,LEVEL2_TAR);
2291 FPT_scasid(p_card, p_port);
2295 WRW_HARPOON((p_port+hp_intstat), SCAM_SEL);
2302 /*---------------------------------------------------------------------
2304 * Function: SccbMgrTableInit
2306 * Description: Initialize all Sccb manager data structures.
2308 *---------------------------------------------------------------------*/
2310 static void FPT_SccbMgrTableInitAll()
2312 unsigned char thisCard;
2314 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++)
2316 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard],thisCard);
2318 FPT_BL_Card[thisCard].ioPort = 0x00;
2319 FPT_BL_Card[thisCard].cardInfo = NULL;
2320 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2321 FPT_BL_Card[thisCard].ourId = 0x00;
2322 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2327 /*---------------------------------------------------------------------
2329 * Function: SccbMgrTableInit
2331 * Description: Initialize all Sccb manager data structures.
2333 *---------------------------------------------------------------------*/
2335 static void FPT_SccbMgrTableInitCard(PSCCBcard pCurrCard, unsigned char p_card)
2337 unsigned char scsiID, qtag;
2339 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2341 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2344 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
2346 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2347 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2348 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2351 pCurrCard->scanIndex = 0x00;
2352 pCurrCard->currentSCCB = NULL;
2353 pCurrCard->globalFlags = 0x00;
2354 pCurrCard->cmdCounter = 0x00;
2355 pCurrCard->tagQ_Lst = 0x01;
2356 pCurrCard->discQCount = 0;
2362 /*---------------------------------------------------------------------
2364 * Function: SccbMgrTableInit
2366 * Description: Initialize all Sccb manager data structures.
2368 *---------------------------------------------------------------------*/
2370 static void FPT_SccbMgrTableInitTarget(unsigned char p_card, unsigned char target)
2373 unsigned char lun, qtag;
2374 struct sccb_mgr_tar_info * currTar_Info;
2376 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2378 currTar_Info->TarSelQ_Cnt = 0;
2379 currTar_Info->TarSyncCtrl = 0;
2381 currTar_Info->TarSelQ_Head = NULL;
2382 currTar_Info->TarSelQ_Tail = NULL;
2383 currTar_Info->TarTagQ_Cnt = 0;
2384 currTar_Info->TarLUN_CA = 0;
2387 for (lun = 0; lun < MAX_LUN; lun++)
2389 currTar_Info->TarLUNBusy[lun] = 0;
2390 currTar_Info->LunDiscQ_Idx[lun] = 0;
2393 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++)
2395 if(FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL)
2397 if(FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == target)
2399 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2400 FPT_BL_Card[p_card].discQCount--;
2407 /*---------------------------------------------------------------------
2411 * Description: Read in a message byte from the SCSI bus, and check
2412 * for a parity error.
2414 *---------------------------------------------------------------------*/
2416 static unsigned char FPT_sfm(unsigned long port, struct sccb * pCurrSCCB)
2418 unsigned char message;
2419 unsigned short TimeOutLoop;
2422 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2423 (TimeOutLoop++ < 20000) ){}
2426 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2428 message = RD_HARPOON(port+hp_scsidata_0);
2430 WR_HARPOON(port+hp_scsisig, SCSI_ACK + S_MSGI_PH);
2433 if (TimeOutLoop > 20000)
2434 message = 0x00; /* force message byte = 0 if Time Out on Req */
2436 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
2437 (RD_HARPOON(port+hp_addstat) & SCSI_PAR_ERR))
2439 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2440 WR_HARPOON(port+hp_xferstat, 0);
2441 WR_HARPOON(port+hp_fiforead, 0);
2442 WR_HARPOON(port+hp_fifowrite, 0);
2443 if (pCurrSCCB != NULL)
2445 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2450 ACCEPT_MSG_ATN(port);
2452 while( (!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
2453 (TimeOutLoop++ < 20000) ){}
2454 if (TimeOutLoop > 20000)
2456 WRW_HARPOON((port+hp_intstat), PARITY);
2459 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) != S_MSGI_PH)
2461 WRW_HARPOON((port+hp_intstat), PARITY);
2464 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
2466 RD_HARPOON(port+hp_scsidata_0);
2468 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2473 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
2474 WR_HARPOON(port+hp_xferstat, 0);
2475 WR_HARPOON(port+hp_fiforead, 0);
2476 WR_HARPOON(port+hp_fifowrite, 0);
2481 /*---------------------------------------------------------------------
2483 * Function: FPT_ssel
2485 * Description: Load up automation and select target device.
2487 *---------------------------------------------------------------------*/
2489 static void FPT_ssel(unsigned long port, unsigned char p_card)
2492 unsigned char auto_loaded, i, target, *theCCB;
2494 unsigned long cdb_reg;
2496 struct sccb * currSCCB;
2497 struct sccb_mgr_tar_info * currTar_Info;
2498 unsigned char lastTag, lun;
2500 CurrCard = &FPT_BL_Card[p_card];
2501 currSCCB = CurrCard->currentSCCB;
2502 target = currSCCB->TargID;
2503 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2504 lastTag = CurrCard->tagQ_Lst;
2509 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2510 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2512 if(((CurrCard->globalFlags & F_CONLUN_IO) &&
2513 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2515 lun = currSCCB->Lun;
2520 if (CurrCard->globalFlags & F_TAG_STARTED)
2522 if (!(currSCCB->ControlByte & F_USE_CMD_Q))
2524 if ((currTar_Info->TarLUN_CA == 0)
2525 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2529 if (currTar_Info->TarTagQ_Cnt !=0)
2531 currTar_Info->TarLUNBusy[lun] = 1;
2532 FPT_queueSelectFail(CurrCard,p_card);
2538 currTar_Info->TarLUNBusy[lun] = 1;
2541 } /*End non-tagged */
2544 currTar_Info->TarLUNBusy[lun] = 1;
2547 } /*!Use cmd Q Tagged */
2550 if (currTar_Info->TarLUN_CA == 1)
2552 FPT_queueSelectFail(CurrCard,p_card);
2557 currTar_Info->TarLUNBusy[lun] = 1;
2559 } /*else use cmd Q tagged */
2561 } /*if glob tagged started */
2564 currTar_Info->TarLUNBusy[lun] = 1;
2569 if((((CurrCard->globalFlags & F_CONLUN_IO) &&
2570 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2571 || (!(currSCCB->ControlByte & F_USE_CMD_Q))))
2573 if(CurrCard->discQCount >= QUEUE_DEPTH)
2575 currTar_Info->TarLUNBusy[lun] = 1;
2576 FPT_queueSelectFail(CurrCard,p_card);
2580 for (i = 1; i < QUEUE_DEPTH; i++)
2582 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2583 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2585 CurrCard->tagQ_Lst = lastTag;
2586 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2587 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2588 CurrCard->discQCount++;
2592 if(i == QUEUE_DEPTH)
2594 currTar_Info->TarLUNBusy[lun] = 1;
2595 FPT_queueSelectFail(CurrCard,p_card);
2605 WR_HARPOON(port+hp_select_id, target);
2606 WR_HARPOON(port+hp_gp_reg_3, target); /* Use by new automation logic */
2608 if (currSCCB->OperationCode == RESET_COMMAND) {
2609 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2610 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2612 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+NP);
2614 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2616 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2618 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2620 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
2622 currTar_Info->TarSyncCtrl = 0;
2623 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2626 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
2628 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2631 FPT_sssyncv(port, target, NARROW_SCSI,currTar_Info);
2632 FPT_SccbMgrTableInitTarget(p_card, target);
2636 else if(currSCCB->Sccb_scsistat == ABORT_ST)
2638 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+
2639 (currSCCB->Sccb_idmsg & ~DISC_PRIV)));
2641 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
2643 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+
2644 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2645 >> 6) | (unsigned char)0x20)));
2646 WRW_HARPOON((port+SYNC_MSGS+2),
2647 (MPM_OP+AMSG_OUT+currSCCB->Sccb_tag));
2648 WRW_HARPOON((port+SYNC_MSGS+4), (BRH_OP+ALWAYS+NP ));
2650 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2655 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2656 auto_loaded = FPT_siwidn(port,p_card);
2657 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2660 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2661 == SYNC_SUPPORTED)) {
2662 auto_loaded = FPT_sisyncn(port,p_card, 0);
2663 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2670 if (currSCCB->ControlByte & F_USE_CMD_Q)
2673 CurrCard->globalFlags |= F_TAG_STARTED;
2675 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2678 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2680 /* Fix up the start instruction with a jump to
2681 Non-Tag-CMD handling */
2682 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2684 WRW_HARPOON((port+NON_TAG_ID_MSG),
2685 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2687 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2689 /* Setup our STATE so we know what happend when
2690 the wheels fall off. */
2691 currSCCB->Sccb_scsistat = SELECT_ST;
2693 currTar_Info->TarLUNBusy[lun] = 1;
2698 WRW_HARPOON((port+ID_MSG_STRT), (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2700 WRW_HARPOON((port+ID_MSG_STRT+2), (MPM_OP+AMSG_OUT+
2701 (((unsigned char)(currSCCB->ControlByte & TAG_TYPE_MASK)
2702 >> 6) | (unsigned char)0x20)));
2704 for (i = 1; i < QUEUE_DEPTH; i++)
2706 if (++lastTag >= QUEUE_DEPTH) lastTag = 1;
2707 if (CurrCard->discQ_Tbl[lastTag] == NULL)
2709 WRW_HARPOON((port+ID_MSG_STRT+6),
2710 (MPM_OP+AMSG_OUT+lastTag));
2711 CurrCard->tagQ_Lst = lastTag;
2712 currSCCB->Sccb_tag = lastTag;
2713 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2714 CurrCard->discQCount++;
2720 if ( i == QUEUE_DEPTH )
2722 currTar_Info->TarLUNBusy[lun] = 1;
2723 FPT_queueSelectFail(CurrCard,p_card);
2728 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2730 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2737 WRW_HARPOON((port+ID_MSG_STRT),BRH_OP+ALWAYS+NTCMD);
2739 WRW_HARPOON((port+NON_TAG_ID_MSG),
2740 (MPM_OP+AMSG_OUT+currSCCB->Sccb_idmsg));
2742 currSCCB->Sccb_scsistat = SELECT_ST;
2744 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
2748 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2750 cdb_reg = port + CMD_STRT;
2752 for (i=0; i < currSCCB->CdbLength; i++)
2754 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2759 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2760 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
2764 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2765 WR_HARPOON(port+hp_xferstat, 0x00);
2767 WRW_HARPOON((port+hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2769 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT));
2772 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED))
2774 WR_HARPOON(port+hp_scsictrl_0, (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2779 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2780 auto_loaded |= AUTO_IMMED; */
2781 auto_loaded = AUTO_IMMED;
2785 WR_HARPOON(port+hp_autostart_3, auto_loaded);
2792 /*---------------------------------------------------------------------
2794 * Function: FPT_sres
2796 * Description: Hookup the correct CCB and handle the incoming messages.
2798 *---------------------------------------------------------------------*/
2800 static void FPT_sres(unsigned long port, unsigned char p_card, PSCCBcard pCurrCard)
2803 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2806 struct sccb_mgr_tar_info * currTar_Info;
2807 struct sccb * currSCCB;
2812 if(pCurrCard->currentSCCB != NULL)
2814 currTar_Info = &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2818 WR_HARPOON((port+hp_scsictrl_0),(ENA_RESEL | ENA_SCAM_SEL));
2821 currSCCB = pCurrCard->currentSCCB;
2822 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
2824 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2825 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2827 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
2829 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2830 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2832 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
2833 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2835 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2836 if(currSCCB->Sccb_scsistat != ABORT_ST)
2838 pCurrCard->discQCount--;
2839 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[currSCCB->Lun]]
2845 currTar_Info->TarLUNBusy[0] = 0;
2846 if(currSCCB->Sccb_tag)
2848 if(currSCCB->Sccb_scsistat != ABORT_ST)
2850 pCurrCard->discQCount--;
2851 pCurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
2855 if(currSCCB->Sccb_scsistat != ABORT_ST)
2857 pCurrCard->discQCount--;
2858 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
2863 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
2866 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
2869 our_target = (unsigned char)(RD_HARPOON(port+hp_select_id) >> 4);
2870 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2877 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2881 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
2883 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
2886 WRW_HARPOON((port+hp_intstat), PHASE);
2891 WRW_HARPOON((port+hp_intstat), PHASE);
2892 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH)
2895 message = FPT_sfm(port,pCurrCard->currentSCCB);
2899 if (message <= (0x80 | LUN_MASK))
2901 lun = message & (unsigned char)LUN_MASK;
2903 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING)
2905 if (currTar_Info->TarTagQ_Cnt != 0)
2908 if (!(currTar_Info->TarLUN_CA))
2910 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2913 message = FPT_sfm(port,pCurrCard->currentSCCB);
2924 tag = FPT_sfm(port,pCurrCard->currentSCCB);
2932 } /*End Q cnt != 0 */
2934 } /*End Tag cmds supported! */
2936 } /*End valid ID message. */
2941 ACCEPT_MSG_ATN(port);
2944 } /* End good id message. */
2954 ACCEPT_MSG_ATN(port);
2956 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
2957 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
2958 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
2966 if(msgRetryCount == 1)
2968 FPT_SendMsg(port, SMPARITY);
2972 FPT_SendMsg(port, SMDEV_RESET);
2974 FPT_sssyncv(port, our_target, NARROW_SCSI,currTar_Info);
2976 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_SYNC_MASK)
2979 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_SYNC_MASK;
2983 if (FPT_sccbMgrTbl[p_card][our_target].TarEEValue & EE_WIDE_SCSI)
2986 FPT_sccbMgrTbl[p_card][our_target].TarStatus &= ~TAR_WIDE_MASK;
2990 FPT_queueFlushTargSccb(p_card, our_target, SCCB_COMPLETE);
2991 FPT_SccbMgrTableInitTarget(p_card,our_target);
2995 }while(message == 0);
2999 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
3000 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
3002 currTar_Info->TarLUNBusy[lun] = 1;
3003 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
3004 if(pCurrCard->currentSCCB != NULL)
3010 ACCEPT_MSG_ATN(port);
3015 currTar_Info->TarLUNBusy[0] = 1;
3020 if (pCurrCard->discQ_Tbl[tag] != NULL)
3022 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[tag];
3023 currTar_Info->TarTagQ_Cnt--;
3028 ACCEPT_MSG_ATN(port);
3032 pCurrCard->currentSCCB = pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
3033 if(pCurrCard->currentSCCB != NULL)
3039 ACCEPT_MSG_ATN(port);
3044 if(pCurrCard->currentSCCB != NULL)
3046 if(pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST)
3048 /* During Abort Tag command, the target could have got re-selected
3049 and completed the command. Check the select Q and remove the CCB
3050 if it is in the Select Q */
3051 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
3056 while (!(RDW_HARPOON((port+hp_intstat)) & (PHASE | RESET)) &&
3057 !(RD_HARPOON(port+hp_scsisig) & SCSI_REQ) &&
3058 (RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ;
3061 static void FPT_SendMsg(unsigned long port, unsigned char message)
3063 while(!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ))
3065 if (! (RD_HARPOON(port+hp_scsisig) & SCSI_BSY))
3068 WRW_HARPOON((port+hp_intstat), PHASE);
3073 WRW_HARPOON((port+hp_intstat), PHASE);
3074 if ((RD_HARPOON(port+hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH)
3076 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
3079 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
3081 WR_HARPOON(port+hp_scsidata_0,message);
3083 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
3087 WR_HARPOON(port+hp_portctrl_0, 0x00);
3089 if ((message == SMABORT) || (message == SMDEV_RESET) ||
3090 (message == SMABORT_TAG) )
3092 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
3094 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3096 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3102 /*---------------------------------------------------------------------
3104 * Function: FPT_sdecm
3106 * Description: Determine the proper responce to the message from the
3109 *---------------------------------------------------------------------*/
3110 static void FPT_sdecm(unsigned char message, unsigned long port, unsigned char p_card)
3112 struct sccb * currSCCB;
3114 struct sccb_mgr_tar_info * currTar_Info;
3116 CurrCard = &FPT_BL_Card[p_card];
3117 currSCCB = CurrCard->currentSCCB;
3119 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3121 if (message == SMREST_DATA_PTR)
3123 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET))
3125 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
3127 FPT_hostDataXferRestart(currSCCB);
3131 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3134 else if (message == SMCMD_COMP)
3138 if (currSCCB->Sccb_scsistat == SELECT_Q_ST)
3140 currTar_Info->TarStatus &= ~(unsigned char)TAR_TAG_Q_MASK;
3141 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
3148 else if ((message == SMNO_OP) || (message >= SMIDENT)
3149 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY))
3153 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3156 else if (message == SMREJECT)
3159 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
3160 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
3161 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING ) ||
3162 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING ) )
3165 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3170 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3171 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3173 if(currSCCB->Lun == 0x00)
3175 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST))
3178 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3180 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3183 else if ((currSCCB->Sccb_scsistat == SELECT_WN_ST))
3187 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3188 ~WIDE_ENABLED) | WIDE_NEGOCIATED;
3190 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3194 else if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_TRYING )
3196 currTar_Info->TarStatus = (currTar_Info->TarStatus &
3197 ~(unsigned char)TAR_TAG_Q_MASK) | TAG_Q_REJECT;
3200 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3201 CurrCard->discQCount--;
3202 CurrCard->discQ_Tbl[currSCCB->Sccb_tag] = NULL;
3203 currSCCB->Sccb_tag = 0x00;
3208 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
3212 if(currSCCB->Lun == 0x00)
3214 WRW_HARPOON((port+hp_intstat), BUS_FREE);
3215 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3222 if((CurrCard->globalFlags & F_CONLUN_IO) &&
3223 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
3224 currTar_Info->TarLUNBusy[currSCCB->Lun] = 1;
3226 currTar_Info->TarLUNBusy[0] = 1;
3229 currSCCB->ControlByte &= ~(unsigned char)F_USE_CMD_Q;
3231 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3240 while ((!(RD_HARPOON(port+hp_scsisig) & SCSI_REQ)) &&
3241 (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))) {}
3243 if (!(RDW_HARPOON((port+hp_intstat)) & BUS_FREE))
3245 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3250 else if (message == SMEXT)
3254 FPT_shandem(port,p_card,currSCCB);
3257 else if (message == SMIGNORWR)
3260 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3262 message = FPT_sfm(port,currSCCB);
3264 if(currSCCB->Sccb_scsimsg != SMPARITY)
3266 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3273 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3274 currSCCB->Sccb_scsimsg = SMREJECT;
3276 ACCEPT_MSG_ATN(port);
3277 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3282 /*---------------------------------------------------------------------
3284 * Function: FPT_shandem
3286 * Description: Decide what to do with the extended message.
3288 *---------------------------------------------------------------------*/
3289 static void FPT_shandem(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
3291 unsigned char length,message;
3293 length = FPT_sfm(port,pCurrSCCB);
3298 message = FPT_sfm(port,pCurrSCCB);
3302 if (message == SMSYNC)
3309 FPT_stsyncn(port,p_card);
3314 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3315 ACCEPT_MSG_ATN(port);
3318 else if (message == SMWDTR)
3325 FPT_stwidn(port,p_card);
3330 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3331 ACCEPT_MSG_ATN(port);
3333 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3339 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3340 ACCEPT_MSG_ATN(port);
3342 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3347 if(pCurrSCCB->Sccb_scsimsg != SMPARITY)
3349 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3353 if(pCurrSCCB->Sccb_scsimsg == SMPARITY)
3354 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3359 /*---------------------------------------------------------------------
3361 * Function: FPT_sisyncn
3363 * Description: Read in a message byte from the SCSI bus, and check
3364 * for a parity error.
3366 *---------------------------------------------------------------------*/
3368 static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card, unsigned char syncFlag)
3370 struct sccb * currSCCB;
3371 struct sccb_mgr_tar_info * currTar_Info;
3373 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3374 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3376 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3379 WRW_HARPOON((port+ID_MSG_STRT),
3380 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3382 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3384 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3385 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3386 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3389 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3391 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 12));
3393 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3395 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 25));
3397 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3399 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 50));
3402 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+ 00));
3405 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3406 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+DEFAULT_OFFSET));
3407 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3412 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3413 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3414 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_TRYING);
3418 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3427 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3428 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3435 /*---------------------------------------------------------------------
3437 * Function: FPT_stsyncn
3439 * Description: The has sent us a Sync Nego message so handle it as
3442 *---------------------------------------------------------------------*/
3443 static void FPT_stsyncn(unsigned long port, unsigned char p_card)
3445 unsigned char sync_msg,offset,sync_reg,our_sync_msg;
3446 struct sccb * currSCCB;
3447 struct sccb_mgr_tar_info * currTar_Info;
3449 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3450 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3452 sync_msg = FPT_sfm(port,currSCCB);
3454 if((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3456 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3463 offset = FPT_sfm(port,currSCCB);
3465 if((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3467 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3471 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3473 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3475 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3477 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3479 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3481 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3484 our_sync_msg = 0; /* Message = Async */
3486 if (sync_msg < our_sync_msg) {
3487 sync_msg = our_sync_msg; /*if faster, then set to max. */
3490 if (offset == ASYNC)
3493 if (offset > MAX_OFFSET)
3494 offset = MAX_OFFSET;
3500 sync_reg = 0x20; /* Use 10MB/s */
3504 sync_reg = 0x40; /* Use 6.6MB/s */
3508 sync_reg = 0x60; /* Use 5MB/s */
3512 sync_reg = 0x80; /* Use 4MB/s */
3516 sync_reg = 0xA0; /* Use 3.33MB/s */
3520 sync_reg = 0xC0; /* Use 2.85MB/s */
3524 sync_reg = 0xE0; /* Use 2.5MB/s */
3526 if (sync_msg > 100) {
3528 sync_reg = 0x00; /* Use ASYNC */
3533 if (currTar_Info->TarStatus & WIDE_ENABLED)
3539 sync_reg |= (offset | NARROW_SCSI);
3541 FPT_sssyncv(port,currSCCB->TargID,sync_reg,currTar_Info);
3544 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3549 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3550 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3552 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3558 ACCEPT_MSG_ATN(port);
3560 FPT_sisyncr(port,sync_msg,offset);
3562 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3563 ~(unsigned char)TAR_SYNC_MASK) | (unsigned char)SYNC_SUPPORTED);
3568 /*---------------------------------------------------------------------
3570 * Function: FPT_sisyncr
3572 * Description: Answer the targets sync message.
3574 *---------------------------------------------------------------------*/
3575 static void FPT_sisyncr(unsigned long port,unsigned char sync_pulse, unsigned char offset)
3578 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3579 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x03 ));
3580 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMSYNC));
3581 WRW_HARPOON((port+SYNC_MSGS+6), (MPM_OP+AMSG_OUT+sync_pulse));
3582 WRW_HARPOON((port+SYNC_MSGS+8), (RAT_OP ));
3583 WRW_HARPOON((port+SYNC_MSGS+10),(MPM_OP+AMSG_OUT+offset));
3584 WRW_HARPOON((port+SYNC_MSGS+12),(BRH_OP+ALWAYS+NP ));
3587 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3588 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3590 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3592 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3597 /*---------------------------------------------------------------------
3599 * Function: FPT_siwidn
3601 * Description: Read in a message byte from the SCSI bus, and check
3602 * for a parity error.
3604 *---------------------------------------------------------------------*/
3606 static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
3608 struct sccb * currSCCB;
3609 struct sccb_mgr_tar_info * currTar_Info;
3611 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3612 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3614 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3617 WRW_HARPOON((port+ID_MSG_STRT),
3618 (MPM_OP+AMSG_OUT+(currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3620 WRW_HARPOON((port+ID_MSG_STRT+2),BRH_OP+ALWAYS+CMDPZ);
3622 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3623 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3624 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3625 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3626 WRW_HARPOON((port+SYNC_MSGS+8), (MPM_OP+AMSG_OUT+ SM16BIT));
3627 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3629 WR_HARPOON(port+hp_autostart_3, (SELECT+SELCHK_STRT));
3632 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3633 ~(unsigned char)TAR_WIDE_MASK) | (unsigned char)WIDE_ENABLED);
3640 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3641 ~(unsigned char)TAR_WIDE_MASK) | WIDE_NEGOCIATED);
3643 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3650 /*---------------------------------------------------------------------
3652 * Function: FPT_stwidn
3654 * Description: The has sent us a Wide Nego message so handle it as
3657 *---------------------------------------------------------------------*/
3658 static void FPT_stwidn(unsigned long port, unsigned char p_card)
3660 unsigned char width;
3661 struct sccb * currSCCB;
3662 struct sccb_mgr_tar_info * currTar_Info;
3664 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3665 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3667 width = FPT_sfm(port,currSCCB);
3669 if((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY))
3671 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3676 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3680 currTar_Info->TarStatus |= WIDE_ENABLED;
3684 width = NARROW_SCSI;
3685 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3689 FPT_sssyncv(port,currSCCB->TargID,width,currTar_Info);
3692 if (currSCCB->Sccb_scsistat == SELECT_WN_ST)
3697 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3699 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_SUPPORTED))
3701 ACCEPT_MSG_ATN(port);
3703 FPT_sisyncn(port,p_card, 1);
3704 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3710 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
3717 ACCEPT_MSG_ATN(port);
3719 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3724 FPT_siwidr(port,width);
3726 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3731 /*---------------------------------------------------------------------
3733 * Function: FPT_siwidr
3735 * Description: Answer the targets Wide nego message.
3737 *---------------------------------------------------------------------*/
3738 static void FPT_siwidr(unsigned long port, unsigned char width)
3741 WRW_HARPOON((port+SYNC_MSGS+0), (MPM_OP+AMSG_OUT+SMEXT ));
3742 WRW_HARPOON((port+SYNC_MSGS+2), (MPM_OP+AMSG_OUT+0x02 ));
3743 WRW_HARPOON((port+SYNC_MSGS+4), (MPM_OP+AMSG_OUT+SMWDTR));
3744 WRW_HARPOON((port+SYNC_MSGS+6), (RAT_OP ));
3745 WRW_HARPOON((port+SYNC_MSGS+8),(MPM_OP+AMSG_OUT+width));
3746 WRW_HARPOON((port+SYNC_MSGS+10),(BRH_OP+ALWAYS+NP ));
3749 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
3750 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT_1);
3752 WR_HARPOON(port+hp_autostart_3, (AUTO_IMMED+CMD_ONLY_STRT));
3754 while (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | AUTO_INT))) {}
3759 /*---------------------------------------------------------------------
3761 * Function: FPT_sssyncv
3763 * Description: Write the desired value to the Sync Register for the
3766 *---------------------------------------------------------------------*/
3767 static void FPT_sssyncv(unsigned long p_port, unsigned char p_id, unsigned char p_sync_value,
3768 struct sccb_mgr_tar_info * currTar_Info)
3770 unsigned char index;
3777 index = 12; /* hp_synctarg_0 */
3780 index = 13; /* hp_synctarg_1 */
3783 index = 14; /* hp_synctarg_2 */
3786 index = 15; /* hp_synctarg_3 */
3789 index = 8; /* hp_synctarg_4 */
3792 index = 9; /* hp_synctarg_5 */
3795 index = 10; /* hp_synctarg_6 */
3798 index = 11; /* hp_synctarg_7 */
3801 index = 4; /* hp_synctarg_8 */
3804 index = 5; /* hp_synctarg_9 */
3807 index = 6; /* hp_synctarg_10 */
3810 index = 7; /* hp_synctarg_11 */
3813 index = 0; /* hp_synctarg_12 */
3816 index = 1; /* hp_synctarg_13 */
3819 index = 2; /* hp_synctarg_14 */
3822 index = 3; /* hp_synctarg_15 */
3826 WR_HARPOON(p_port+hp_synctarg_base+index, p_sync_value);
3828 currTar_Info->TarSyncCtrl = p_sync_value;
3832 /*---------------------------------------------------------------------
3834 * Function: FPT_sresb
3836 * Description: Reset the desired card's SCSI bus.
3838 *---------------------------------------------------------------------*/
3839 static void FPT_sresb(unsigned long port, unsigned char p_card)
3841 unsigned char scsiID, i;
3843 struct sccb_mgr_tar_info * currTar_Info;
3845 WR_HARPOON(port+hp_page_ctrl,
3846 (RD_HARPOON(port+hp_page_ctrl) | G_INT_DISABLE));
3847 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3849 WR_HARPOON(port+hp_scsictrl_0, SCSI_RST);
3851 scsiID = RD_HARPOON(port+hp_seltimeout);
3852 WR_HARPOON(port+hp_seltimeout,TO_5ms);
3853 WRW_HARPOON((port+hp_intstat), TIMEOUT);
3855 WR_HARPOON(port+hp_portctrl_0,(SCSI_PORT | START_TO));
3857 while (!(RDW_HARPOON((port+hp_intstat)) & TIMEOUT)) {}
3859 WR_HARPOON(port+hp_seltimeout,scsiID);
3861 WR_HARPOON(port+hp_scsictrl_0, ENA_SCAM_SEL);
3863 FPT_Wait(port, TO_5ms);
3865 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
3867 WR_HARPOON(port+hp_int_mask, (RD_HARPOON(port+hp_int_mask) | 0x00));
3869 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++)
3871 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3873 if (currTar_Info->TarEEValue & EE_SYNC_MASK)
3875 currTar_Info->TarSyncCtrl = 0;
3876 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3879 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3881 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3884 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
3886 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3889 FPT_BL_Card[p_card].scanIndex = 0x00;
3890 FPT_BL_Card[p_card].currentSCCB = NULL;
3891 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3893 FPT_BL_Card[p_card].cmdCounter = 0x00;
3894 FPT_BL_Card[p_card].discQCount = 0x00;
3895 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3897 for(i = 0; i < QUEUE_DEPTH; i++)
3898 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3900 WR_HARPOON(port+hp_page_ctrl,
3901 (RD_HARPOON(port+hp_page_ctrl) & ~G_INT_DISABLE));
3905 /*---------------------------------------------------------------------
3907 * Function: FPT_ssenss
3909 * Description: Setup for the Auto Sense command.
3911 *---------------------------------------------------------------------*/
3912 static void FPT_ssenss(PSCCBcard pCurrCard)
3915 struct sccb * currSCCB;
3917 currSCCB = pCurrCard->currentSCCB;
3920 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3922 for (i = 0; i < 6; i++) {
3924 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3927 currSCCB->CdbLength = SIX_BYTE_CMD;
3928 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3929 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3930 currSCCB->Cdb[2] = 0x00;
3931 currSCCB->Cdb[3] = 0x00;
3932 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3933 currSCCB->Cdb[5] = 0x00;
3935 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3937 currSCCB->Sccb_ATC = 0x00;
3939 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3941 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3943 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3945 currSCCB->ControlByte = 0x00;
3947 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3952 /*---------------------------------------------------------------------
3954 * Function: FPT_sxfrp
3956 * Description: Transfer data into the bit bucket until the device
3957 * decides to switch phase.
3959 *---------------------------------------------------------------------*/
3961 static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
3963 unsigned char curr_phz;
3966 DISABLE_AUTO(p_port);
3968 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3970 FPT_hostDataXferAbort(p_port,p_card,FPT_BL_Card[p_card].currentSCCB);
3974 /* If the Automation handled the end of the transfer then do not
3975 match the phase or we will get out of sync with the ISR. */
3977 if (RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3980 WR_HARPOON(p_port+hp_xfercnt_0, 0x00);
3982 curr_phz = RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3984 WRW_HARPOON((p_port+hp_intstat), XFER_CNT_0);
3987 WR_HARPOON(p_port+hp_scsisig, curr_phz);
3989 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)) &&
3990 (curr_phz == (RD_HARPOON(p_port+hp_scsisig) & (unsigned char)S_SCSI_PHZ)) )
3992 if (curr_phz & (unsigned char)SCSI_IOBIT)
3994 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3996 if (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
3998 RD_HARPOON(p_port+hp_fifodata_0);
4003 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | HOST_WRT));
4004 if (RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY)
4006 WR_HARPOON(p_port+hp_fifodata_0,0xFA);
4009 } /* End of While loop for padding data I/O phase */
4011 while ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4013 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
4017 WR_HARPOON(p_port+hp_portctrl_0, (SCSI_PORT | HOST_PORT | SCSI_INBIT));
4018 while (!(RD_HARPOON(p_port+hp_xferstat) & FIFO_EMPTY))
4020 RD_HARPOON(p_port+hp_fifodata_0);
4023 if ( !(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RESET)))
4025 WR_HARPOON(p_port+hp_autostart_0, (AUTO_IMMED+DISCONNECT_START));
4026 while (!(RDW_HARPOON((p_port+hp_intstat)) & AUTO_INT)) {}
4028 if (RDW_HARPOON((p_port+hp_intstat)) & (ICMD_COMP | ITAR_DISC))
4029 while (!(RDW_HARPOON((p_port+hp_intstat)) & (BUS_FREE | RSEL))) ;
4034 /*---------------------------------------------------------------------
4036 * Function: FPT_schkdd
4038 * Description: Make sure data has been flushed from both FIFOs and abort
4039 * the operations if necessary.
4041 *---------------------------------------------------------------------*/
4043 static void FPT_schkdd(unsigned long port, unsigned char p_card)
4045 unsigned short TimeOutLoop;
4046 unsigned char sPhase;
4048 struct sccb * currSCCB;
4050 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4053 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
4054 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
4060 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT)
4063 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt-1);
4065 currSCCB->Sccb_XferCnt = 1;
4067 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
4068 WRW_HARPOON((port+hp_fiforead), (unsigned short) 0x00);
4069 WR_HARPOON(port+hp_xferstat, 0x00);
4075 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4077 currSCCB->Sccb_XferCnt = 0;
4080 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4081 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4083 currSCCB->HostStatus = SCCB_PARITY_ERR;
4084 WRW_HARPOON((port+hp_intstat), PARITY);
4088 FPT_hostDataXferAbort(port,p_card,currSCCB);
4091 while (RD_HARPOON(port+hp_scsisig) & SCSI_ACK) {}
4095 while(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)
4097 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE) {
4100 if (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) {
4103 if (RDW_HARPOON((port+hp_intstat)) & RESET) {
4106 if ((RD_HARPOON(port+hp_scsisig) & SCSI_REQ) || (TimeOutLoop++>0x3000) )
4110 sPhase = RD_HARPOON(port+hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
4111 if ((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) ||
4112 (RD_HARPOON(port+hp_offsetctr) & (unsigned char)0x1F) ||
4113 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
4114 (sPhase == (SCSI_BSY | S_DATAI_PH)))
4117 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4119 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED))
4121 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4122 FPT_phaseDataIn(port,p_card);
4126 FPT_phaseDataOut(port,p_card);
4131 FPT_sxfrp(port,p_card);
4132 if (!(RDW_HARPOON((port+hp_intstat)) &
4133 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET)))
4135 WRW_HARPOON((port+hp_intstat), AUTO_INT);
4136 FPT_phaseDecode(port,p_card);
4143 WR_HARPOON(port+hp_portctrl_0, 0x00);
4148 /*---------------------------------------------------------------------
4150 * Function: FPT_sinits
4152 * Description: Setup SCCB manager fields in this SCCB.
4154 *---------------------------------------------------------------------*/
4156 static void FPT_sinits(struct sccb * p_sccb, unsigned char p_card)
4158 struct sccb_mgr_tar_info * currTar_Info;
4160 if((p_sccb->TargID > MAX_SCSI_TAR) || (p_sccb->Lun > MAX_LUN))
4164 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
4166 p_sccb->Sccb_XferState = 0x00;
4167 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
4169 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
4170 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
4172 p_sccb->Sccb_SGoffset = 0;
4173 p_sccb->Sccb_XferState = F_SG_XFER;
4174 p_sccb->Sccb_XferCnt = 0x00;
4177 if (p_sccb->DataLength == 0x00)
4179 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
4181 if (p_sccb->ControlByte & F_USE_CMD_Q)
4183 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
4184 p_sccb->ControlByte &= ~F_USE_CMD_Q;
4187 currTar_Info->TarStatus |= TAG_Q_TRYING;
4190 /* For !single SCSI device in system & device allow Disconnect
4191 or command is tag_q type then send Cmd with Disconnect Enable
4192 else send Cmd with Disconnect Disable */
4195 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
4196 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
4197 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4199 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
4200 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
4201 p_sccb->Sccb_idmsg = (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
4206 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
4209 p_sccb->HostStatus = 0x00;
4210 p_sccb->TargetStatus = 0x00;
4211 p_sccb->Sccb_tag = 0x00;
4212 p_sccb->Sccb_MGRFlags = 0x00;
4213 p_sccb->Sccb_sgseg = 0x00;
4214 p_sccb->Sccb_ATC = 0x00;
4215 p_sccb->Sccb_savedATC = 0x00;
4217 p_sccb->SccbVirtDataPtr = 0x00;
4218 p_sccb->Sccb_forwardlink = NULL;
4219 p_sccb->Sccb_backlink = NULL;
4221 p_sccb->Sccb_scsistat = BUS_FREE_ST;
4222 p_sccb->SccbStatus = SCCB_IN_PROCESS;
4223 p_sccb->Sccb_scsimsg = SMNO_OP;
4228 /*---------------------------------------------------------------------
4230 * Function: Phase Decode
4232 * Description: Determine the phase and call the appropriate function.
4234 *---------------------------------------------------------------------*/
4236 static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
4238 unsigned char phase_ref;
4239 void (*phase) (unsigned long, unsigned char);
4242 DISABLE_AUTO(p_port);
4244 phase_ref = (unsigned char) (RD_HARPOON(p_port+hp_scsisig) & S_SCSI_PHZ);
4246 phase = FPT_s_PhaseTbl[phase_ref];
4248 (*phase)(p_port, p_card); /* Call the correct phase func */
4253 /*---------------------------------------------------------------------
4255 * Function: Data Out Phase
4257 * Description: Start up both the BusMaster and Xbow.
4259 *---------------------------------------------------------------------*/
4261 static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
4264 struct sccb * currSCCB;
4266 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4267 if (currSCCB == NULL)
4269 return; /* Exit if No SCCB record */
4272 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4273 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4275 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4277 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4279 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4281 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4283 if (currSCCB->Sccb_XferCnt == 0) {
4286 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4287 (currSCCB->HostStatus == SCCB_COMPLETE))
4288 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4290 FPT_sxfrp(port,p_card);
4291 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4292 FPT_phaseDecode(port,p_card);
4297 /*---------------------------------------------------------------------
4299 * Function: Data In Phase
4301 * Description: Startup the BusMaster and the XBOW.
4303 *---------------------------------------------------------------------*/
4305 static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
4308 struct sccb * currSCCB;
4310 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4312 if (currSCCB == NULL)
4314 return; /* Exit if No SCCB record */
4318 currSCCB->Sccb_scsistat = DATA_IN_ST;
4319 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4320 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4322 WR_HARPOON(port+hp_portctrl_0, SCSI_PORT);
4324 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4326 WR_HARPOON(port+hp_autostart_0, (END_DATA+END_DATA_START));
4328 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4330 if (currSCCB->Sccb_XferCnt == 0) {
4333 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4334 (currSCCB->HostStatus == SCCB_COMPLETE))
4335 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4337 FPT_sxfrp(port,p_card);
4338 if (!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | RESET)))
4339 FPT_phaseDecode(port,p_card);
4344 /*---------------------------------------------------------------------
4346 * Function: Command Phase
4348 * Description: Load the CDB into the automation and start it up.
4350 *---------------------------------------------------------------------*/
4352 static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
4354 struct sccb * currSCCB;
4355 unsigned long cdb_reg;
4358 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4360 if (currSCCB->OperationCode == RESET_COMMAND) {
4362 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4363 currSCCB->CdbLength = SIX_BYTE_CMD;
4366 WR_HARPOON(p_port+hp_scsisig, 0x00);
4368 ARAM_ACCESS(p_port);
4371 cdb_reg = p_port + CMD_STRT;
4373 for (i=0; i < currSCCB->CdbLength; i++) {
4375 if (currSCCB->OperationCode == RESET_COMMAND)
4377 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4380 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4384 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4385 WRW_HARPOON(cdb_reg, (BRH_OP+ALWAYS+ NP));
4387 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT));
4389 currSCCB->Sccb_scsistat = COMMAND_ST;
4391 WR_HARPOON(p_port+hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4392 SGRAM_ACCESS(p_port);
4396 /*---------------------------------------------------------------------
4398 * Function: Status phase
4400 * Description: Bring in the status and command complete message bytes
4402 *---------------------------------------------------------------------*/
4404 static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
4406 /* Start-up the automation to finish off this command and let the
4407 isr handle the interrupt for command complete when it comes in.
4408 We could wait here for the interrupt to be generated?
4411 WR_HARPOON(port+hp_scsisig, 0x00);
4413 WR_HARPOON(port+hp_autostart_0, (AUTO_IMMED+END_DATA_START));
4417 /*---------------------------------------------------------------------
4419 * Function: Phase Message Out
4421 * Description: Send out our message (if we have one) and handle whatever
4424 *---------------------------------------------------------------------*/
4426 static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
4428 unsigned char message,scsiID;
4429 struct sccb * currSCCB;
4430 struct sccb_mgr_tar_info * currTar_Info;
4432 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4434 if (currSCCB != NULL) {
4436 message = currSCCB->Sccb_scsimsg;
4437 scsiID = currSCCB->TargID;
4439 if (message == SMDEV_RESET)
4443 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4444 currTar_Info->TarSyncCtrl = 0;
4445 FPT_sssyncv(port, scsiID, NARROW_SCSI,currTar_Info);
4447 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_SYNC_MASK)
4450 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_SYNC_MASK;
4454 if (FPT_sccbMgrTbl[p_card][scsiID].TarEEValue & EE_WIDE_SCSI)
4457 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &= ~TAR_WIDE_MASK;
4461 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4462 FPT_SccbMgrTableInitTarget(p_card,scsiID);
4464 else if (currSCCB->Sccb_scsistat == ABORT_ST)
4466 currSCCB->HostStatus = SCCB_COMPLETE;
4467 if(FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] != NULL)
4469 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4470 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4475 else if (currSCCB->Sccb_scsistat < COMMAND_ST)
4479 if(message == SMNO_OP)
4481 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4483 FPT_ssel(port,p_card);
4491 if (message == SMABORT)
4493 FPT_queueFlushSccb(p_card,SCCB_COMPLETE);
4502 WRW_HARPOON((port+hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4505 WR_HARPOON(port+hp_portctrl_0, SCSI_BUS_EN);
4507 WR_HARPOON(port+hp_scsidata_0,message);
4509 WR_HARPOON(port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
4513 WR_HARPOON(port+hp_portctrl_0, 0x00);
4515 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4516 (message == SMABORT_TAG) )
4519 while(!(RDW_HARPOON((port+hp_intstat)) & (BUS_FREE | PHASE))) {}
4521 if (RDW_HARPOON((port+hp_intstat)) & BUS_FREE)
4523 WRW_HARPOON((port+hp_intstat), BUS_FREE);
4525 if (currSCCB != NULL)
4528 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4529 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4530 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4532 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4534 FPT_queueCmdComplete(&FPT_BL_Card[p_card],currSCCB, p_card);
4539 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4546 FPT_sxfrp(port,p_card);
4553 if(message == SMPARITY)
4555 currSCCB->Sccb_scsimsg = SMNO_OP;
4556 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4560 FPT_sxfrp(port,p_card);
4566 /*---------------------------------------------------------------------
4568 * Function: Message In phase
4570 * Description: Bring in the message and determine what to do with it.
4572 *---------------------------------------------------------------------*/
4574 static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
4576 unsigned char message;
4577 struct sccb * currSCCB;
4579 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4581 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT)
4584 FPT_phaseChkFifo(port, p_card);
4587 message = RD_HARPOON(port+hp_scsidata_0);
4588 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR))
4591 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+END_DATA_START));
4598 message = FPT_sfm(port,currSCCB);
4603 FPT_sdecm(message,port,p_card);
4608 if(currSCCB->Sccb_scsimsg != SMPARITY)
4610 WR_HARPOON(port+hp_autostart_1, (AUTO_IMMED+DISCONNECT_START));
4617 /*---------------------------------------------------------------------
4619 * Function: Illegal phase
4621 * Description: Target switched to some illegal phase, so all we can do
4622 * is report an error back to the host (if that is possible)
4623 * and send an ABORT message to the misbehaving target.
4625 *---------------------------------------------------------------------*/
4627 static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
4629 struct sccb * currSCCB;
4631 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4633 WR_HARPOON(port+hp_scsisig, RD_HARPOON(port+hp_scsisig));
4634 if (currSCCB != NULL) {
4636 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4637 currSCCB->Sccb_scsistat = ABORT_ST;
4638 currSCCB->Sccb_scsimsg = SMABORT;
4641 ACCEPT_MSG_ATN(port);
4646 /*---------------------------------------------------------------------
4648 * Function: Phase Check FIFO
4650 * Description: Make sure data has been flushed from both FIFOs and abort
4651 * the operations if necessary.
4653 *---------------------------------------------------------------------*/
4655 static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
4657 unsigned long xfercnt;
4658 struct sccb * currSCCB;
4660 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4662 if (currSCCB->Sccb_scsistat == DATA_IN_ST)
4665 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4666 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4669 if (!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY))
4671 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4673 currSCCB->Sccb_XferCnt = 0;
4675 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4676 (currSCCB->HostStatus == SCCB_COMPLETE))
4678 currSCCB->HostStatus = SCCB_PARITY_ERR;
4679 WRW_HARPOON((port+hp_intstat), PARITY);
4682 FPT_hostDataXferAbort(port,p_card,currSCCB);
4684 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4686 while((!(RD_HARPOON(port+hp_xferstat) & FIFO_EMPTY)) &&
4687 (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY)) {}
4690 } /*End Data In specific code. */
4694 GET_XFER_CNT(port,xfercnt);
4697 WR_HARPOON(port+hp_xfercnt_0, 0x00);
4700 WR_HARPOON(port+hp_portctrl_0, 0x00);
4702 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4704 currSCCB->Sccb_XferCnt = xfercnt;
4706 if ((RDW_HARPOON((port+hp_intstat)) & PARITY) &&
4707 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4709 currSCCB->HostStatus = SCCB_PARITY_ERR;
4710 WRW_HARPOON((port+hp_intstat), PARITY);
4714 FPT_hostDataXferAbort(port,p_card,currSCCB);
4717 WR_HARPOON(port+hp_fifowrite, 0x00);
4718 WR_HARPOON(port+hp_fiforead, 0x00);
4719 WR_HARPOON(port+hp_xferstat, 0x00);
4721 WRW_HARPOON((port+hp_intstat), XFER_CNT_0);
4725 /*---------------------------------------------------------------------
4727 * Function: Phase Bus Free
4729 * Description: We just went bus free so figure out if it was
4730 * because of command complete or from a disconnect.
4732 *---------------------------------------------------------------------*/
4733 static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
4735 struct sccb * currSCCB;
4737 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4739 if (currSCCB != NULL)
4745 if (currSCCB->OperationCode == RESET_COMMAND)
4748 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4749 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4750 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4752 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4754 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4756 FPT_queueSearchSelect(&FPT_BL_Card[p_card],p_card);
4760 else if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4762 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4763 (unsigned char)SYNC_SUPPORTED;
4764 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4767 else if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
4769 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4770 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4771 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4773 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
4776 else if(currSCCB->Sccb_scsistat == SELECT_Q_ST)
4778 /* Make sure this is not a phony BUS_FREE. If we were
4779 reselected or if BUSY is NOT on then this is a
4780 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4782 if ((!(RD_HARPOON(port+hp_scsisig) & SCSI_BSY)) ||
4783 (RDW_HARPOON((port+hp_intstat)) & RSEL))
4785 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_TAG_Q_MASK;
4786 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |= TAG_Q_REJECT;
4798 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4800 if (!currSCCB->HostStatus)
4802 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4805 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4806 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4807 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
4809 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4811 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4816 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4818 } /*end if !=null */
4824 /*---------------------------------------------------------------------
4826 * Function: Auto Load Default Map
4828 * Description: Load the Automation RAM with the defualt map values.
4830 *---------------------------------------------------------------------*/
4831 static void FPT_autoLoadDefaultMap(unsigned long p_port)
4833 unsigned long map_addr;
4835 ARAM_ACCESS(p_port);
4836 map_addr = p_port + hp_aramBase;
4838 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0xC0)); /*ID MESSAGE */
4840 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4842 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4844 WRW_HARPOON(map_addr, (MPM_OP+AMSG_OUT+ 0x00)); /*TAG ID MSG */
4846 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 0 */
4848 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 1 */
4850 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 2 */
4852 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 3 */
4854 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 4 */
4856 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 5 */
4858 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 6 */
4860 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 7 */
4862 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 8 */
4864 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 9 */
4866 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 10 */
4868 WRW_HARPOON(map_addr, (MPM_OP+ACOMMAND+ 0x00)); /*CDB BYTE 11 */
4870 WRW_HARPOON(map_addr, (CPE_OP+ADATA_OUT+ DINT)); /*JUMP IF DATA OUT */
4872 WRW_HARPOON(map_addr, (TCB_OP+FIFO_0+ DI)); /*JUMP IF NO DATA IN FIFO */
4873 map_addr +=2; /*This means AYNC DATA IN */
4874 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4876 WRW_HARPOON(map_addr, (CPE_OP+ADATA_IN+DINT)); /*JUMP IF NOT DATA IN PHZ */
4878 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4880 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x02)); /*SAVE DATA PTR MSG? */
4882 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ DC)); /*GO CHECK FOR DISCONNECT MSG */
4884 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR1)); /*SAVE DATA PTRS MSG */
4886 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ ST)); /*IF NOT MSG IN CHECK DATA IN */
4888 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x04)); /*DISCONNECT MSG? */
4890 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ UNKNWN));/*UKNKNOWN MSG */
4892 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*XFER DISCONNECT MSG */
4894 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITAR_DISC));/*STOP AND INTERRUPT */
4896 WRW_HARPOON(map_addr, (CPN_OP+ASTATUS+ UNKNWN));/*JUMP IF NOT STATUS PHZ. */
4898 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_AR0)); /*GET STATUS BYTE */
4900 WRW_HARPOON(map_addr, (CPN_OP+AMSG_IN+ CC)); /*ERROR IF NOT MSG IN PHZ */
4902 WRW_HARPOON(map_addr, (CRD_OP+SDATA+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4904 WRW_HARPOON(map_addr, (BRH_OP+NOT_EQ+ CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4906 WRW_HARPOON(map_addr, (MRR_OP+SDATA+ D_BUCKET));/*GET CMD COMPLETE MSG */
4908 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ICMD_COMP));/*END OF COMMAND */
4911 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4913 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4915 WRW_HARPOON(map_addr, (SSI_OP+ SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4917 WRW_HARPOON(map_addr, (SSI_OP+ SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4918 map_addr +=2; /* DIDN'T GET ONE */
4919 WRW_HARPOON(map_addr, (CRR_OP+AR3+ S_IDREG)); /* comp SCSI SEL ID & AR3*/
4921 WRW_HARPOON(map_addr, (BRH_OP+EQUAL+ 0x00)); /*SEL ID OK then Conti. */
4923 WRW_HARPOON(map_addr, (SSI_OP+ SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4927 SGRAM_ACCESS(p_port);
4930 /*---------------------------------------------------------------------
4932 * Function: Auto Command Complete
4934 * Description: Post command back to host and find another command
4937 *---------------------------------------------------------------------*/
4939 static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
4941 struct sccb * currSCCB;
4942 unsigned char status_byte;
4944 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4946 status_byte = RD_HARPOON(p_port+hp_gp_reg_0);
4948 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4950 if (status_byte != SSGOOD) {
4952 if (status_byte == SSQ_FULL) {
4955 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4956 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4958 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4959 if(FPT_BL_Card[p_card].discQCount != 0)
4960 FPT_BL_Card[p_card].discQCount--;
4961 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
4965 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
4966 if(currSCCB->Sccb_tag)
4968 if(FPT_BL_Card[p_card].discQCount != 0)
4969 FPT_BL_Card[p_card].discQCount--;
4970 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
4973 if(FPT_BL_Card[p_card].discQCount != 0)
4974 FPT_BL_Card[p_card].discQCount--;
4975 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
4979 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4981 FPT_queueSelectFail(&FPT_BL_Card[p_card],p_card);
4986 if(currSCCB->Sccb_scsistat == SELECT_SN_ST)
4988 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4989 (unsigned char)SYNC_SUPPORTED;
4991 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_SYNC_MASK;
4992 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4994 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4995 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
4997 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
4998 if(FPT_BL_Card[p_card].discQCount != 0)
4999 FPT_BL_Card[p_card].discQCount--;
5000 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5004 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5005 if(currSCCB->Sccb_tag)
5007 if(FPT_BL_Card[p_card].discQCount != 0)
5008 FPT_BL_Card[p_card].discQCount--;
5009 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5012 if(FPT_BL_Card[p_card].discQCount != 0)
5013 FPT_BL_Card[p_card].discQCount--;
5014 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5021 if(currSCCB->Sccb_scsistat == SELECT_WN_ST)
5024 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
5025 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
5026 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
5028 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &= ~EE_WIDE_SCSI;
5029 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5031 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5032 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5034 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5035 if(FPT_BL_Card[p_card].discQCount != 0)
5036 FPT_BL_Card[p_card].discQCount--;
5037 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5041 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5042 if(currSCCB->Sccb_tag)
5044 if(FPT_BL_Card[p_card].discQCount != 0)
5045 FPT_BL_Card[p_card].discQCount--;
5046 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5049 if(FPT_BL_Card[p_card].discQCount != 0)
5050 FPT_BL_Card[p_card].discQCount--;
5051 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5058 if (status_byte == SSCHECK)
5060 if(FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO)
5062 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_SYNC_MASK)
5064 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_SYNC_MASK;
5066 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue & EE_WIDE_SCSI)
5068 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus &= ~TAR_WIDE_MASK;
5073 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5075 currSCCB->SccbStatus = SCCB_ERROR;
5076 currSCCB->TargetStatus = status_byte;
5078 if (status_byte == SSCHECK) {
5080 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA
5084 if (currSCCB->RequestSenseLength != NO_AUTO_REQUEST_SENSE) {
5086 if (currSCCB->RequestSenseLength == 0)
5087 currSCCB->RequestSenseLength = 14;
5089 FPT_ssenss(&FPT_BL_Card[p_card]);
5090 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
5092 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5093 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
5095 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 1;
5096 if(FPT_BL_Card[p_card].discQCount != 0)
5097 FPT_BL_Card[p_card].discQCount--;
5098 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[currSCCB->Lun]] = NULL;
5102 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 1;
5103 if(currSCCB->Sccb_tag)
5105 if(FPT_BL_Card[p_card].discQCount != 0)
5106 FPT_BL_Card[p_card].discQCount--;
5107 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] = NULL;
5110 if(FPT_BL_Card[p_card].discQCount != 0)
5111 FPT_BL_Card[p_card].discQCount--;
5112 FPT_BL_Card[p_card].discQ_Tbl[FPT_sccbMgrTbl[p_card][currSCCB->TargID].LunDiscQ_Idx[0]] = NULL;
5122 if((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
5123 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
5124 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->Lun] = 0;
5126 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
5129 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
5132 #define SHORT_WAIT 0x0000000F
5133 #define LONG_WAIT 0x0000FFFFL
5136 /*---------------------------------------------------------------------
5138 * Function: Data Transfer Processor
5140 * Description: This routine performs two tasks.
5141 * (1) Start data transfer by calling HOST_DATA_XFER_START
5142 * function. Once data transfer is started, (2) Depends
5143 * on the type of data transfer mode Scatter/Gather mode
5144 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
5145 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
5146 * data transfer done. In Scatter/Gather mode, this routine
5147 * checks bus master command complete and dual rank busy
5148 * bit to keep chaining SC transfer command. Similarly,
5149 * in Scatter/Gather mode, it checks Sccb_MGRFlag
5150 * (F_HOST_XFER_ACT bit) for data transfer done.
5152 *---------------------------------------------------------------------*/
5154 static void FPT_dataXferProcessor(unsigned long port, PSCCBcard pCurrCard)
5156 struct sccb * currSCCB;
5158 currSCCB = pCurrCard->currentSCCB;
5160 if (currSCCB->Sccb_XferState & F_SG_XFER)
5162 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
5165 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
5166 currSCCB->Sccb_SGoffset = 0x00;
5168 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5170 FPT_busMstrSGDataXferStart(port, currSCCB);
5175 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT))
5177 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
5179 FPT_busMstrDataXferStart(port, currSCCB);
5185 /*---------------------------------------------------------------------
5187 * Function: BusMaster Scatter Gather Data Transfer Start
5191 *---------------------------------------------------------------------*/
5192 static void FPT_busMstrSGDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
5194 unsigned long count,addr,tmpSGCnt;
5195 unsigned int sg_index;
5196 unsigned char sg_count, i;
5197 unsigned long reg_offset;
5200 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5202 count = ((unsigned long) HOST_RD_CMD)<<24;
5206 count = ((unsigned long) HOST_WRT_CMD)<<24;
5211 sg_index = pcurrSCCB->Sccb_sgseg;
5212 reg_offset = hp_aramBase;
5215 i = (unsigned char) (RD_HARPOON(p_port+hp_page_ctrl) & ~(SGRAM_ARAM|SCATTER_EN));
5218 WR_HARPOON(p_port+hp_page_ctrl, i);
5220 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
5221 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) < pcurrSCCB->DataLength) ) {
5223 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer)+
5226 count |= *(((unsigned long *)pcurrSCCB->DataPointer)+
5229 addr = *(((unsigned long *)pcurrSCCB->DataPointer)+
5230 ((sg_index * 2) + 1));
5233 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5235 addr += ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5236 count = (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5238 tmpSGCnt = count & 0x00FFFFFFL;
5241 WR_HARP32(p_port,reg_offset,addr);
5244 WR_HARP32(p_port,reg_offset,count);
5247 count &= 0xFF000000L;
5253 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5255 WR_HARPOON(p_port+hp_sg_addr,(sg_count<<4));
5257 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5259 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5262 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5263 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5269 if ((!(RD_HARPOON(p_port+hp_synctarg_0) & NARROW_SCSI)) &&
5270 (tmpSGCnt & 0x000000001))
5273 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5278 WR_HARP32(p_port,hp_xfercnt_0,tmpSGCnt);
5280 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5281 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5285 WR_HARPOON(p_port+hp_page_ctrl, (unsigned char) (i | SCATTER_EN));
5290 /*---------------------------------------------------------------------
5292 * Function: BusMaster Data Transfer Start
5296 *---------------------------------------------------------------------*/
5297 static void FPT_busMstrDataXferStart(unsigned long p_port, struct sccb * pcurrSCCB)
5299 unsigned long addr,count;
5301 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5303 count = pcurrSCCB->Sccb_XferCnt;
5305 addr = (unsigned long) pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5309 addr = pcurrSCCB->SensePointer;
5310 count = pcurrSCCB->RequestSenseLength;
5314 HP_SETUP_ADDR_CNT(p_port,addr,count);
5317 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5319 WR_HARPOON(p_port+hp_portctrl_0,(DMA_PORT | SCSI_PORT | SCSI_INBIT));
5320 WR_HARPOON(p_port+hp_scsisig, S_DATAI_PH);
5322 WR_HARPOON(p_port+hp_xfer_cmd,
5323 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5328 WR_HARPOON(p_port+hp_portctrl_0,(SCSI_PORT | DMA_PORT | DMA_RD));
5329 WR_HARPOON(p_port+hp_scsisig, S_DATAO_PH);
5331 WR_HARPOON(p_port+hp_xfer_cmd,
5332 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5338 /*---------------------------------------------------------------------
5340 * Function: BusMaster Timeout Handler
5342 * Description: This function is called after a bus master command busy time
5343 * out is detected. This routines issue halt state machine
5344 * with a software time out for command busy. If command busy
5345 * is still asserted at the end of the time out, it issues
5346 * hard abort with another software time out. It hard abort
5347 * command busy is also time out, it'll just give up.
5349 *---------------------------------------------------------------------*/
5350 static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
5352 unsigned long timeout;
5354 timeout = LONG_WAIT;
5356 WR_HARPOON(p_port+hp_sys_ctrl, HALT_MACH);
5358 while ((!(RD_HARPOON(p_port+hp_ext_status) & CMD_ABORTED)) && timeout--) {}
5362 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5363 WR_HARPOON(p_port+hp_sys_ctrl, HARD_ABORT);
5365 timeout = LONG_WAIT;
5366 while ((RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5369 RD_HARPOON(p_port+hp_int_status); /*Clear command complete */
5371 if (RD_HARPOON(p_port+hp_ext_status) & BM_CMD_BUSY) {
5381 /*---------------------------------------------------------------------
5383 * Function: Host Data Transfer Abort
5385 * Description: Abort any in progress transfer.
5387 *---------------------------------------------------------------------*/
5388 static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card, struct sccb * pCurrSCCB)
5391 unsigned long timeout;
5392 unsigned long remain_cnt;
5393 unsigned int sg_ptr;
5395 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5397 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5400 if (!(RD_HARPOON(port+hp_int_status) & INT_CMD_COMPL)) {
5402 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) | FLUSH_XFER_CNTR));
5403 timeout = LONG_WAIT;
5405 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5407 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) & ~FLUSH_XFER_CNTR));
5409 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5411 if (FPT_busMstrTimeOut(port)) {
5413 if (pCurrSCCB->HostStatus == 0x00)
5415 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5419 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS)
5421 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS)
5423 if (pCurrSCCB->HostStatus == 0x00)
5426 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5432 else if (pCurrSCCB->Sccb_XferCnt) {
5434 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5437 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5440 WR_HARPOON(port+hp_sg_addr,0x00);
5442 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5444 if (sg_ptr > (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE)) {
5446 sg_ptr = (unsigned int)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5449 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5451 while (remain_cnt < 0x01000000L) {
5455 if (remain_cnt > (unsigned long)(*(((unsigned long *)pCurrSCCB->
5456 DataPointer) + (sg_ptr * 2)))) {
5458 remain_cnt -= (unsigned long)(*(((unsigned long *)pCurrSCCB->
5459 DataPointer) + (sg_ptr * 2)));
5470 if (remain_cnt < 0x01000000L) {
5473 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5475 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5478 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) == pCurrSCCB->DataLength
5479 && (remain_cnt == 0))
5481 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5487 if (pCurrSCCB->HostStatus == 0x00) {
5489 pCurrSCCB->HostStatus = SCCB_GROSS_FW_ERR;
5495 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5498 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5500 FPT_busMstrTimeOut(port);
5505 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5507 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5509 if (pCurrSCCB->HostStatus == 0x00) {
5511 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5522 if ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) {
5524 timeout = SHORT_WAIT;
5526 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5527 ((RD_HARPOON(port+hp_fifo_cnt)) >= BM_THRESHOLD) &&
5531 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5533 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) |
5536 timeout = LONG_WAIT;
5538 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) &&
5541 WR_HARPOON(port+hp_bm_ctrl, (RD_HARPOON(port+hp_bm_ctrl) &
5545 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5547 if (pCurrSCCB->HostStatus == 0x00) {
5549 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5552 FPT_busMstrTimeOut(port);
5556 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5558 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5560 if (pCurrSCCB->HostStatus == 0x00) {
5562 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5573 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5575 timeout = LONG_WAIT;
5577 while ((RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) && timeout--) {}
5579 if (RD_HARPOON(port+hp_ext_status) & BM_CMD_BUSY) {
5581 if (pCurrSCCB->HostStatus == 0x00) {
5583 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5586 FPT_busMstrTimeOut(port);
5591 if (RD_HARPOON(port+hp_int_status) & INT_EXT_STATUS) {
5593 if (RD_HARPOON(port+hp_ext_status) & BAD_EXT_STATUS) {
5595 if (pCurrSCCB->HostStatus == 0x00) {
5597 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5603 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5605 WR_HARPOON(port+hp_page_ctrl, (RD_HARPOON(port+hp_page_ctrl) &
5608 WR_HARPOON(port+hp_sg_addr,0x00);
5610 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5612 pCurrSCCB->Sccb_SGoffset = 0x00;
5615 if ((unsigned long)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5616 pCurrSCCB->DataLength) {
5618 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5620 pCurrSCCB->Sccb_sgseg = (unsigned short)(pCurrSCCB->DataLength / SG_ELEMENT_SIZE);
5627 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5629 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5633 WR_HARPOON(port+hp_int_mask,(INT_CMD_COMPL | SCSI_INTERRUPT));
5638 /*---------------------------------------------------------------------
5640 * Function: Host Data Transfer Restart
5642 * Description: Reset the available count due to a restore data
5645 *---------------------------------------------------------------------*/
5646 static void FPT_hostDataXferRestart(struct sccb * currSCCB)
5648 unsigned long data_count;
5649 unsigned int sg_index;
5650 unsigned long *sg_ptr;
5652 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5654 currSCCB->Sccb_XferCnt = 0;
5656 sg_index = 0xffff; /*Index by long words into sg list. */
5657 data_count = 0; /*Running count of SG xfer counts. */
5659 sg_ptr = (unsigned long *)currSCCB->DataPointer;
5661 while (data_count < currSCCB->Sccb_ATC) {
5664 data_count += *(sg_ptr+(sg_index * 2));
5667 if (data_count == currSCCB->Sccb_ATC) {
5669 currSCCB->Sccb_SGoffset = 0;
5674 currSCCB->Sccb_SGoffset = data_count - currSCCB->Sccb_ATC;
5677 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5681 currSCCB->Sccb_XferCnt = currSCCB->DataLength - currSCCB->Sccb_ATC;
5687 /*---------------------------------------------------------------------
5689 * Function: FPT_scini
5691 * Description: Setup all data structures necessary for SCAM selection.
5693 *---------------------------------------------------------------------*/
5695 static void FPT_scini(unsigned char p_card, unsigned char p_our_id, unsigned char p_power_up)
5698 unsigned char loser,assigned_id;
5699 unsigned long p_port;
5701 unsigned char i,k,ScamFlg ;
5703 struct nvram_info * pCurrNvRam;
5705 currCard = &FPT_BL_Card[p_card];
5706 p_port = currCard->ioPort;
5707 pCurrNvRam = currCard->pNvRamInfo;
5711 ScamFlg = pCurrNvRam->niScamConf;
5712 i = pCurrNvRam->niSysConf;
5715 ScamFlg = (unsigned char) FPT_utilEERead(p_port, SCAM_CONFIG/2);
5716 i = (unsigned char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG/2)));
5718 if(!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5721 FPT_inisci(p_card,p_port, p_our_id);
5723 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5724 too slow to return to SCAM selection */
5727 FPT_Wait1Second(p_port);
5729 FPT_Wait(p_port, TO_250ms); */
5731 FPT_Wait1Second(p_port);
5733 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
5735 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5740 FPT_scxferc(p_port,SYNC_PTRN);
5741 FPT_scxferc(p_port,DOM_MSTR);
5742 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0]);
5743 } while ( loser == 0xFF );
5747 if ((p_power_up) && (!loser))
5749 FPT_sresb(p_port,p_card);
5750 FPT_Wait(p_port, TO_250ms);
5752 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5757 FPT_scxferc(p_port, SYNC_PTRN);
5758 FPT_scxferc(p_port, DOM_MSTR);
5759 loser = FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].
5761 } while ( loser == 0xFF );
5776 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5779 if (ScamFlg & SCAM_ENABLED)
5782 for (i=0; i < MAX_SCSI_TAR; i++)
5784 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5785 (FPT_scamInfo[i].state == ID_UNUSED))
5787 if (FPT_scsell(p_port,i))
5789 FPT_scamInfo[i].state = LEGACY;
5790 if ((FPT_scamInfo[i].id_string[0] != 0xFF) ||
5791 (FPT_scamInfo[i].id_string[1] != 0xFA))
5794 FPT_scamInfo[i].id_string[0] = 0xFF;
5795 FPT_scamInfo[i].id_string[1] = 0xFA;
5796 if(pCurrNvRam == NULL)
5797 currCard->globalFlags |= F_UPDATE_EEPROM;
5803 FPT_sresb(p_port,p_card);
5804 FPT_Wait1Second(p_port);
5805 while (!(FPT_scarb(p_port,INIT_SELTD))) {}
5807 FPT_scasid(p_card, p_port);
5812 else if ((loser) && (ScamFlg & SCAM_ENABLED))
5814 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5816 FPT_scwtsel(p_port);
5819 while (FPT_scxferc(p_port,0x00) != SYNC_PTRN) {}
5821 i = FPT_scxferc(p_port,0x00);
5824 if (!(FPT_scsendi(p_port,&FPT_scamInfo[p_our_id].id_string[0])))
5826 i = FPT_scxferc(p_port,0x00);
5829 k = FPT_scxferc(p_port,0x00);
5834 ((unsigned char)(i<<3)+(k & (unsigned char)7)) & (unsigned char) 0x3F;
5835 FPT_inisci(p_card, p_port, p_our_id);
5836 FPT_scamInfo[currCard->ourId].state = ID_ASSIGNED;
5837 FPT_scamInfo[currCard->ourId].id_string[0]
5845 else if (i == SET_P_FLAG)
5847 if (!(FPT_scsendi(p_port,
5848 &FPT_scamInfo[p_our_id].id_string[0])))
5849 FPT_scamInfo[p_our_id].id_string[0] |= 0x80;
5851 }while (!assigned_id);
5853 while (FPT_scxferc(p_port,0x00) != CFG_CMPLT) {}
5856 if (ScamFlg & SCAM_ENABLED)
5859 if (currCard->globalFlags & F_UPDATE_EEPROM)
5861 FPT_scsavdi(p_card, p_port);
5862 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5868 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5870 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5871 (FPT_scamInfo[i].state == LEGACY))
5876 currCard->globalFlags |= F_SINGLE_DEVICE;
5878 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5883 /*---------------------------------------------------------------------
5885 * Function: FPT_scarb
5887 * Description: Gain control of the bus and wait SCAM select time (250ms)
5889 *---------------------------------------------------------------------*/
5891 static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
5893 if (p_sel_type == INIT_SELTD)
5896 while (RD_HARPOON(p_port+hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {}
5899 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL)
5902 if (RD_HARPOON(p_port+hp_scsidata_0) != 00)
5905 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_BSY));
5907 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_SEL) {
5909 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5915 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_SEL));
5917 if (RD_HARPOON(p_port+hp_scsidata_0) != 00) {
5919 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) &
5920 ~(SCSI_BSY | SCSI_SEL)));
5926 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5928 WR_HARPOON(p_port+hp_scsireset, SCAM_EN);
5929 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5930 WR_HARPOON(p_port+hp_scsidata_1, 0x00);
5931 WR_HARPOON(p_port+hp_portctrl_0, SCSI_BUS_EN);
5933 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig) | SCSI_MSG));
5935 WR_HARPOON(p_port+hp_scsisig, (RD_HARPOON(p_port+hp_scsisig)
5938 FPT_Wait(p_port,TO_250ms);
5944 /*---------------------------------------------------------------------
5946 * Function: FPT_scbusf
5948 * Description: Release the SCSI bus and disable SCAM selection.
5950 *---------------------------------------------------------------------*/
5952 static void FPT_scbusf(unsigned long p_port)
5954 WR_HARPOON(p_port+hp_page_ctrl,
5955 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
5958 WR_HARPOON(p_port+hp_scsidata_0, 0x00);
5960 WR_HARPOON(p_port+hp_portctrl_0, (RD_HARPOON(p_port+hp_portctrl_0)
5963 WR_HARPOON(p_port+hp_scsisig, 0x00);
5966 WR_HARPOON(p_port+hp_scsireset, (RD_HARPOON(p_port+hp_scsireset)
5969 WR_HARPOON(p_port+hp_clkctrl_0, (RD_HARPOON(p_port+hp_clkctrl_0)
5972 WRW_HARPOON((p_port+hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5974 WR_HARPOON(p_port+hp_page_ctrl,
5975 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
5980 /*---------------------------------------------------------------------
5982 * Function: FPT_scasid
5984 * Description: Assign an ID to all the SCAM devices.
5986 *---------------------------------------------------------------------*/
5988 static void FPT_scasid(unsigned char p_card, unsigned long p_port)
5990 unsigned char temp_id_string[ID_STRING_LENGTH];
5992 unsigned char i,k,scam_id;
5993 unsigned char crcBytes[3];
5994 struct nvram_info * pCurrNvRam;
5995 unsigned short * pCrcBytes;
5997 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6004 for (k=0; k < ID_STRING_LENGTH; k++)
6006 temp_id_string[k] = (unsigned char) 0x00;
6009 FPT_scxferc(p_port,SYNC_PTRN);
6010 FPT_scxferc(p_port,ASSIGN_ID);
6012 if (!(FPT_sciso(p_port,&temp_id_string[0])))
6015 pCrcBytes = (unsigned short *)&crcBytes[0];
6016 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
6017 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
6018 temp_id_string[1] = crcBytes[2];
6019 temp_id_string[2] = crcBytes[0];
6020 temp_id_string[3] = crcBytes[1];
6021 for(k = 4; k < ID_STRING_LENGTH; k++)
6022 temp_id_string[k] = (unsigned char) 0x00;
6024 i = FPT_scmachid(p_card,temp_id_string);
6026 if (i == CLR_PRIORITY)
6028 FPT_scxferc(p_port,MISC_CODE);
6029 FPT_scxferc(p_port,CLR_P_FLAG);
6030 i = 0; /*Not the last ID yet. */
6033 else if (i != NO_ID_AVAIL)
6036 FPT_scxferc(p_port,ID_0_7);
6038 FPT_scxferc(p_port,ID_8_F);
6040 scam_id = (i & (unsigned char) 0x07);
6043 for (k=1; k < 0x08; k <<= 1)
6045 scam_id += 0x08; /*Count number of zeros in DB0-3. */
6047 FPT_scxferc(p_port,scam_id);
6049 i = 0; /*Not the last ID yet. */
6060 FPT_scxferc(p_port,SYNC_PTRN);
6061 FPT_scxferc(p_port,CFG_CMPLT);
6068 /*---------------------------------------------------------------------
6070 * Function: FPT_scsel
6072 * Description: Select all the SCAM devices.
6074 *---------------------------------------------------------------------*/
6076 static void FPT_scsel(unsigned long p_port)
6079 WR_HARPOON(p_port+hp_scsisig, SCSI_SEL);
6080 FPT_scwiros(p_port, SCSI_MSG);
6082 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY));
6085 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6086 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) |
6087 (unsigned char)(BIT(7)+BIT(6))));
6090 WR_HARPOON(p_port+hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6091 FPT_scwiros(p_port, SCSI_SEL);
6093 WR_HARPOON(p_port+hp_scsidata_0, (unsigned char)(RD_HARPOON(p_port+hp_scsidata_0) &
6094 ~(unsigned char)BIT(6)));
6095 FPT_scwirod(p_port, BIT(6));
6097 WR_HARPOON(p_port+hp_scsisig, (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
6102 /*---------------------------------------------------------------------
6104 * Function: FPT_scxferc
6106 * Description: Handshake the p_data (DB4-0) across the bus.
6108 *---------------------------------------------------------------------*/
6110 static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
6112 unsigned char curr_data, ret_data;
6114 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
6116 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6118 curr_data &= ~BIT(7);
6120 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6122 FPT_scwirod(p_port,BIT(7)); /*Wait for DB7 to be released. */
6123 while (!(RD_HARPOON(p_port+hp_scsidata_0) & BIT(5)));
6125 ret_data = (RD_HARPOON(p_port+hp_scsidata_0) & (unsigned char) 0x1F);
6127 curr_data |= BIT(6);
6129 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6131 curr_data &= ~BIT(5);
6133 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6135 FPT_scwirod(p_port,BIT(5)); /*Wait for DB5 to be released. */
6137 curr_data &= ~(BIT(4)|BIT(3)|BIT(2)|BIT(1)|BIT(0)); /*Release data bits */
6138 curr_data |= BIT(7);
6140 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6142 curr_data &= ~BIT(6);
6144 WR_HARPOON(p_port+hp_scsidata_0, curr_data);
6146 FPT_scwirod(p_port,BIT(6)); /*Wait for DB6 to be released. */
6152 /*---------------------------------------------------------------------
6154 * Function: FPT_scsendi
6156 * Description: Transfer our Identification string to determine if we
6157 * will be the dominant master.
6159 *---------------------------------------------------------------------*/
6161 static unsigned char FPT_scsendi(unsigned long p_port, unsigned char p_id_string[])
6163 unsigned char ret_data,byte_cnt,bit_cnt,defer;
6167 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6169 for (bit_cnt = 0x80; bit_cnt != 0 ; bit_cnt >>= 1) {
6172 ret_data = FPT_scxferc(p_port,00);
6174 else if (p_id_string[byte_cnt] & bit_cnt)
6176 ret_data = FPT_scxferc(p_port,02);
6180 ret_data = FPT_scxferc(p_port,01);
6185 if ((ret_data & 0x1C) == 0x10)
6186 return(0x00); /*End of isolation stage, we won! */
6188 if (ret_data & 0x1C)
6191 if ((defer) && (!(ret_data & 0x1F)))
6192 return(0x01); /*End of isolation stage, we lost. */
6199 return(0x01); /*We lost */
6201 return(0); /*We WON! Yeeessss! */
6206 /*---------------------------------------------------------------------
6208 * Function: FPT_sciso
6210 * Description: Transfer the Identification string.
6212 *---------------------------------------------------------------------*/
6214 static unsigned char FPT_sciso(unsigned long p_port, unsigned char p_id_string[])
6216 unsigned char ret_data,the_data,byte_cnt,bit_cnt;
6220 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6222 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6224 ret_data = FPT_scxferc(p_port,0);
6226 if (ret_data & 0xFC)
6232 if (ret_data & BIT(1)) {
6237 if ((ret_data & 0x1F) == 0)
6240 if(bit_cnt != 0 || bit_cnt != 8)
6244 FPT_scxferc(p_port, SYNC_PTRN);
6245 FPT_scxferc(p_port, ASSIGN_ID);
6257 p_id_string[byte_cnt] = the_data;
6266 /*---------------------------------------------------------------------
6268 * Function: FPT_scwirod
6270 * Description: Sample the SCSI data bus making sure the signal has been
6271 * deasserted for the correct number of consecutive samples.
6273 *---------------------------------------------------------------------*/
6275 static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
6280 while ( i < MAX_SCSI_TAR ) {
6282 if (RD_HARPOON(p_port+hp_scsidata_0) & p_data_bit)
6295 /*---------------------------------------------------------------------
6297 * Function: FPT_scwiros
6299 * Description: Sample the SCSI Signal lines making sure the signal has been
6300 * deasserted for the correct number of consecutive samples.
6302 *---------------------------------------------------------------------*/
6304 static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
6309 while ( i < MAX_SCSI_TAR ) {
6311 if (RD_HARPOON(p_port+hp_scsisig) & p_data_bit)
6323 /*---------------------------------------------------------------------
6325 * Function: FPT_scvalq
6327 * Description: Make sure we received a valid data byte.
6329 *---------------------------------------------------------------------*/
6331 static unsigned char FPT_scvalq(unsigned char p_quintet)
6333 unsigned char count;
6335 for (count=1; count < 0x08; count<<=1) {
6336 if (!(p_quintet & count))
6340 if (p_quintet & 0x18)
6348 /*---------------------------------------------------------------------
6350 * Function: FPT_scsell
6352 * Description: Select the specified device ID using a selection timeout
6353 * less than 4ms. If somebody responds then it is a legacy
6354 * drive and this ID must be marked as such.
6356 *---------------------------------------------------------------------*/
6358 static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
6362 WR_HARPOON(p_port+hp_page_ctrl,
6363 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE));
6365 ARAM_ACCESS(p_port);
6367 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) | SCAM_TIMER));
6368 WR_HARPOON(p_port+hp_seltimeout,TO_4ms);
6371 for (i = p_port+CMD_STRT; i < p_port+CMD_STRT+12; i+=2) {
6372 WRW_HARPOON(i, (MPM_OP+ACOMMAND));
6374 WRW_HARPOON(i, (BRH_OP+ALWAYS+ NP));
6376 WRW_HARPOON((p_port+hp_intstat),
6377 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6379 WR_HARPOON(p_port+hp_select_id, targ_id);
6381 WR_HARPOON(p_port+hp_portctrl_0, SCSI_PORT);
6382 WR_HARPOON(p_port+hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6383 WR_HARPOON(p_port+hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6386 while (!(RDW_HARPOON((p_port+hp_intstat)) &
6387 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {}
6389 if (RDW_HARPOON((p_port+hp_intstat)) & RESET)
6390 FPT_Wait(p_port, TO_250ms);
6392 DISABLE_AUTO(p_port);
6394 WR_HARPOON(p_port+hp_addstat,(RD_HARPOON(p_port+hp_addstat) & ~SCAM_TIMER));
6395 WR_HARPOON(p_port+hp_seltimeout,TO_290ms);
6397 SGRAM_ACCESS(p_port);
6399 if (RDW_HARPOON((p_port+hp_intstat)) & (RESET | TIMEOUT) ) {
6401 WRW_HARPOON((p_port+hp_intstat),
6402 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6404 WR_HARPOON(p_port+hp_page_ctrl,
6405 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6407 return(0); /*No legacy device */
6412 while(!(RDW_HARPOON((p_port+hp_intstat)) & BUS_FREE)) {
6413 if (RD_HARPOON(p_port+hp_scsisig) & SCSI_REQ)
6415 WR_HARPOON(p_port+hp_scsisig, (SCSI_ACK + S_ILL_PH));
6420 WRW_HARPOON((p_port+hp_intstat), CLR_ALL_INT_1);
6422 WR_HARPOON(p_port+hp_page_ctrl,
6423 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE));
6425 return(1); /*Found one of them oldies! */
6429 /*---------------------------------------------------------------------
6431 * Function: FPT_scwtsel
6433 * Description: Wait to be selected by another SCAM initiator.
6435 *---------------------------------------------------------------------*/
6437 static void FPT_scwtsel(unsigned long p_port)
6439 while(!(RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL)) {}
6443 /*---------------------------------------------------------------------
6445 * Function: FPT_inisci
6447 * Description: Setup the data Structure with the info from the EEPROM.
6449 *---------------------------------------------------------------------*/
6451 static void FPT_inisci(unsigned char p_card, unsigned long p_port, unsigned char p_our_id)
6453 unsigned char i,k,max_id;
6454 unsigned short ee_data;
6455 struct nvram_info * pCurrNvRam;
6457 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6459 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6466 for(i = 0; i < max_id; i++){
6468 for(k = 0; k < 4; k++)
6469 FPT_scamInfo[i].id_string[k] = pCurrNvRam->niScamTbl[i][k];
6470 for(k = 4; k < ID_STRING_LENGTH; k++)
6471 FPT_scamInfo[i].id_string[k] = (unsigned char) 0x00;
6473 if(FPT_scamInfo[i].id_string[0] == 0x00)
6474 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6476 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6480 for (i=0; i < max_id; i++)
6482 for (k=0; k < ID_STRING_LENGTH; k+=2)
6484 ee_data = FPT_utilEERead(p_port, (unsigned short)((EE_SCAMBASE/2) +
6485 (unsigned short) (i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6486 FPT_scamInfo[i].id_string[k] = (unsigned char) ee_data;
6488 FPT_scamInfo[i].id_string[k+1] = (unsigned char) ee_data;
6491 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6492 (FPT_scamInfo[i].id_string[0] == 0xFF))
6494 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6497 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6501 for(k = 0; k < ID_STRING_LENGTH; k++)
6502 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6506 /*---------------------------------------------------------------------
6508 * Function: FPT_scmachid
6510 * Description: Match the Device ID string with our values stored in
6513 *---------------------------------------------------------------------*/
6515 static unsigned char FPT_scmachid(unsigned char p_card, unsigned char p_id_string[])
6518 unsigned char i,k,match;
6521 for (i=0; i < MAX_SCSI_TAR; i++) {
6525 for (k=0; k < ID_STRING_LENGTH; k++)
6527 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6533 FPT_scamInfo[i].state = ID_ASSIGNED;
6541 if (p_id_string[0] & BIT(5))
6546 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6547 match = p_id_string[1] & (unsigned char) 0x1F;
6555 if (FPT_scamInfo[match].state == ID_UNUSED)
6557 for (k=0; k < ID_STRING_LENGTH; k++)
6559 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6562 FPT_scamInfo[match].state = ID_ASSIGNED;
6564 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6565 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6575 if (p_id_string[0] & BIT(5))
6578 match = MAX_SCSI_TAR-1;
6584 if (p_id_string[0] & BIT(7))
6586 return(CLR_PRIORITY);
6590 if (p_id_string[0] & BIT(5))
6595 if (((p_id_string[0] & 0x06) == 0x02) || ((p_id_string[0] & 0x06) == 0x04))
6596 match = p_id_string[1] & (unsigned char) 0x1F;
6605 if (FPT_scamInfo[match].state == ID_UNASSIGNED)
6607 for (k=0; k < ID_STRING_LENGTH; k++)
6609 FPT_scamInfo[match].id_string[k] = p_id_string[k];
6612 FPT_scamInfo[match].id_string[0] |= BIT(7);
6613 FPT_scamInfo[match].state = ID_ASSIGNED;
6614 if(FPT_BL_Card[p_card].pNvRamInfo == NULL)
6615 FPT_BL_Card[p_card].globalFlags |= F_UPDATE_EEPROM;
6625 if (p_id_string[0] & BIT(5))
6628 match = MAX_SCSI_TAR-1;
6632 return(NO_ID_AVAIL);
6636 /*---------------------------------------------------------------------
6638 * Function: FPT_scsavdi
6640 * Description: Save off the device SCAM ID strings.
6642 *---------------------------------------------------------------------*/
6644 static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
6646 unsigned char i,k,max_id;
6647 unsigned short ee_data,sum_data;
6652 for (i = 1; i < EE_SCAMBASE/2; i++)
6654 sum_data += FPT_utilEERead(p_port, i);
6658 FPT_utilEEWriteOnOff(p_port,1); /* Enable write access to the EEPROM */
6660 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6666 for (i=0; i < max_id; i++)
6669 for (k=0; k < ID_STRING_LENGTH; k+=2)
6671 ee_data = FPT_scamInfo[i].id_string[k+1];
6673 ee_data |= FPT_scamInfo[i].id_string[k];
6674 sum_data += ee_data;
6675 FPT_utilEEWrite(p_port, ee_data, (unsigned short)((EE_SCAMBASE/2) +
6676 (unsigned short)(i*((unsigned short)ID_STRING_LENGTH/2)) + (unsigned short)(k/2)));
6681 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM/2);
6682 FPT_utilEEWriteOnOff(p_port,0); /* Turn off write access */
6685 /*---------------------------------------------------------------------
6687 * Function: FPT_XbowInit
6689 * Description: Setup the Xbow for normal operation.
6691 *---------------------------------------------------------------------*/
6693 static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
6697 i = RD_HARPOON(port+hp_page_ctrl);
6698 WR_HARPOON(port+hp_page_ctrl, (unsigned char) (i | G_INT_DISABLE));
6700 WR_HARPOON(port+hp_scsireset,0x00);
6701 WR_HARPOON(port+hp_portctrl_1,HOST_MODE8);
6703 WR_HARPOON(port+hp_scsireset,(DMA_RESET | HPSCSI_RESET | PROG_RESET | \
6706 WR_HARPOON(port+hp_scsireset,SCSI_INI);
6708 WR_HARPOON(port+hp_clkctrl_0,CLKCTRL_DEFAULT);
6710 WR_HARPOON(port+hp_scsisig,0x00); /* Clear any signals we might */
6711 WR_HARPOON(port+hp_scsictrl_0,ENA_SCAM_SEL);
6713 WRW_HARPOON((port+hp_intstat), CLR_ALL_INT);
6715 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6716 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6718 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6719 FPT_default_intena |= SCAM_SEL;
6721 WRW_HARPOON((port+hp_intena), FPT_default_intena);
6723 WR_HARPOON(port+hp_seltimeout,TO_290ms);
6725 /* Turn on SCSI_MODE8 for narrow cards to fix the
6726 strapping issue with the DUAL CHANNEL card */
6727 if (RD_HARPOON(port+hp_page_ctrl) & NARROW_SCSI_CARD)
6728 WR_HARPOON(port+hp_addstat,SCSI_MODE8);
6730 WR_HARPOON(port+hp_page_ctrl, i);
6735 /*---------------------------------------------------------------------
6737 * Function: FPT_BusMasterInit
6739 * Description: Initialize the BusMaster for normal operations.
6741 *---------------------------------------------------------------------*/
6743 static void FPT_BusMasterInit(unsigned long p_port)
6747 WR_HARPOON(p_port+hp_sys_ctrl, DRVR_RST);
6748 WR_HARPOON(p_port+hp_sys_ctrl, 0x00);
6750 WR_HARPOON(p_port+hp_host_blk_cnt, XFER_BLK64);
6753 WR_HARPOON(p_port+hp_bm_ctrl, (BMCTRL_DEFAULT));
6755 WR_HARPOON(p_port+hp_ee_ctrl, (SCSI_TERM_ENA_H));
6758 RD_HARPOON(p_port+hp_int_status); /*Clear interrupts. */
6759 WR_HARPOON(p_port+hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6760 WR_HARPOON(p_port+hp_page_ctrl, (RD_HARPOON(p_port+hp_page_ctrl) &
6765 /*---------------------------------------------------------------------
6767 * Function: FPT_DiagEEPROM
6769 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6772 *---------------------------------------------------------------------*/
6774 static void FPT_DiagEEPROM(unsigned long p_port)
6776 unsigned short index,temp,max_wd_cnt;
6778 if (RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD)
6779 max_wd_cnt = EEPROM_WD_CNT;
6781 max_wd_cnt = EEPROM_WD_CNT * 2;
6783 temp = FPT_utilEERead(p_port, FW_SIGNATURE/2);
6785 if (temp == 0x4641) {
6787 for (index = 2; index < max_wd_cnt; index++) {
6789 temp += FPT_utilEERead(p_port, index);
6793 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM/2)) {
6795 return; /*EEPROM is Okay so return now! */
6800 FPT_utilEEWriteOnOff(p_port,(unsigned char)1);
6802 for (index = 0; index < max_wd_cnt; index++) {
6804 FPT_utilEEWrite(p_port, 0x0000, index);
6809 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE/2);
6811 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0/2);
6813 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2/2);
6815 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4/2);
6817 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG/2);
6819 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG/2);
6821 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG/2);
6823 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID/2);
6826 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN/2);
6828 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA/2);
6830 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE/2);
6833 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01/2);
6835 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23/2);
6837 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45/2);
6839 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67/2);
6841 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89/2);
6843 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab/2);
6845 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd/2);
6847 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef/2);
6851 FPT_utilEEWrite(p_port, 0x6C46, 64/2); /*PRODUCT ID */
6853 FPT_utilEEWrite(p_port, 0x7361, 66/2); /* FlashPoint LT */
6855 FPT_utilEEWrite(p_port, 0x5068, 68/2);
6857 FPT_utilEEWrite(p_port, 0x696F, 70/2);
6859 FPT_utilEEWrite(p_port, 0x746E, 72/2);
6861 FPT_utilEEWrite(p_port, 0x4C20, 74/2);
6863 FPT_utilEEWrite(p_port, 0x2054, 76/2);
6865 FPT_utilEEWrite(p_port, 0x2020, 78/2);
6868 index = ((EE_SCAMBASE/2)+(7*16));
6869 FPT_utilEEWrite(p_port, (0x0700+TYPE_CODE0), index);
6870 temp += (0x0700+TYPE_CODE0);
6872 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6873 temp += 0x5542; /* BUSLOGIC */
6875 FPT_utilEEWrite(p_port, 0x4C53, index);
6878 FPT_utilEEWrite(p_port, 0x474F, index);
6881 FPT_utilEEWrite(p_port, 0x4349, index);
6884 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6885 temp += 0x5442; /* BT- 930 */
6887 FPT_utilEEWrite(p_port, 0x202D, index);
6890 FPT_utilEEWrite(p_port, 0x3339, index);
6892 index++; /*Serial # */
6893 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6896 FPT_utilEEWrite(p_port, 0x5453, index);
6899 FPT_utilEEWrite(p_port, 0x5645, index);
6902 FPT_utilEEWrite(p_port, 0x2045, index);
6905 FPT_utilEEWrite(p_port, 0x202F, index);
6908 FPT_utilEEWrite(p_port, 0x4F4A, index);
6911 FPT_utilEEWrite(p_port, 0x204E, index);
6914 FPT_utilEEWrite(p_port, 0x3539, index);
6919 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM/2);
6921 FPT_utilEEWriteOnOff(p_port,(unsigned char)0);
6926 /*---------------------------------------------------------------------
6928 * Function: Queue Search Select
6930 * Description: Try to find a new command to execute.
6932 *---------------------------------------------------------------------*/
6934 static void FPT_queueSearchSelect(PSCCBcard pCurrCard, unsigned char p_card)
6936 unsigned char scan_ptr, lun;
6937 struct sccb_mgr_tar_info * currTar_Info;
6938 struct sccb * pOldSccb;
6940 scan_ptr = pCurrCard->scanIndex;
6943 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6944 if((pCurrCard->globalFlags & F_CONLUN_IO) &&
6945 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
6947 if (currTar_Info->TarSelQ_Cnt != 0)
6951 if (scan_ptr == MAX_SCSI_TAR)
6954 for(lun=0; lun < MAX_LUN; lun++)
6956 if(currTar_Info->TarLUNBusy[lun] == 0)
6959 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
6962 while((pCurrCard->currentSCCB != NULL) &&
6963 (lun != pCurrCard->currentSCCB->Lun))
6965 pOldSccb = pCurrCard->currentSCCB;
6966 pCurrCard->currentSCCB = (struct sccb *)(pCurrCard->currentSCCB)->
6969 if(pCurrCard->currentSCCB == NULL)
6971 if(pOldSccb != NULL)
6973 pOldSccb->Sccb_forwardlink = (struct sccb *)(pCurrCard->currentSCCB)->
6975 pOldSccb->Sccb_backlink = (struct sccb *)(pCurrCard->currentSCCB)->
6977 currTar_Info->TarSelQ_Cnt--;
6981 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
6983 if (currTar_Info->TarSelQ_Head == NULL)
6985 currTar_Info->TarSelQ_Tail = NULL;
6986 currTar_Info->TarSelQ_Cnt = 0;
6990 currTar_Info->TarSelQ_Cnt--;
6991 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
6994 pCurrCard->scanIndex = scan_ptr;
6996 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7006 if (scan_ptr == MAX_SCSI_TAR) {
7014 if ((currTar_Info->TarSelQ_Cnt != 0) &&
7015 (currTar_Info->TarLUNBusy[0] == 0))
7018 pCurrCard->currentSCCB = currTar_Info->TarSelQ_Head;
7020 currTar_Info->TarSelQ_Head = (struct sccb *)(pCurrCard->currentSCCB)->Sccb_forwardlink;
7022 if (currTar_Info->TarSelQ_Head == NULL)
7024 currTar_Info->TarSelQ_Tail = NULL;
7025 currTar_Info->TarSelQ_Cnt = 0;
7029 currTar_Info->TarSelQ_Cnt--;
7030 currTar_Info->TarSelQ_Head->Sccb_backlink = (struct sccb *)NULL;
7034 if (scan_ptr == MAX_SCSI_TAR)
7037 pCurrCard->scanIndex = scan_ptr;
7039 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7047 if (scan_ptr == MAX_SCSI_TAR)
7053 } while (scan_ptr != pCurrCard->scanIndex);
7057 /*---------------------------------------------------------------------
7059 * Function: Queue Select Fail
7061 * Description: Add the current SCCB to the head of the Queue.
7063 *---------------------------------------------------------------------*/
7065 static void FPT_queueSelectFail(PSCCBcard pCurrCard, unsigned char p_card)
7067 unsigned char thisTarg;
7068 struct sccb_mgr_tar_info * currTar_Info;
7070 if (pCurrCard->currentSCCB != NULL)
7072 thisTarg = (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->TargID);
7073 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7075 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
7077 pCurrCard->currentSCCB->Sccb_forwardlink = currTar_Info->TarSelQ_Head;
7079 if (currTar_Info->TarSelQ_Cnt == 0)
7081 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
7086 currTar_Info->TarSelQ_Head->Sccb_backlink = pCurrCard->currentSCCB;
7090 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
7092 pCurrCard->currentSCCB = NULL;
7093 currTar_Info->TarSelQ_Cnt++;
7096 /*---------------------------------------------------------------------
7098 * Function: Queue Command Complete
7100 * Description: Call the callback function with the current SCCB.
7102 *---------------------------------------------------------------------*/
7104 static void FPT_queueCmdComplete(PSCCBcard pCurrCard, struct sccb * p_sccb,
7105 unsigned char p_card)
7108 unsigned char i, SCSIcmd;
7109 CALL_BK_FN callback;
7110 struct sccb_mgr_tar_info * currTar_Info;
7112 SCSIcmd = p_sccb->Cdb[0];
7115 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
7117 if ((p_sccb->ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN)) &&
7118 (p_sccb->HostStatus == SCCB_COMPLETE) &&
7119 (p_sccb->TargetStatus != SSCHECK))
7121 if ((SCSIcmd == SCSI_READ) ||
7122 (SCSIcmd == SCSI_WRITE) ||
7123 (SCSIcmd == SCSI_READ_EXTENDED) ||
7124 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
7125 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
7126 (SCSIcmd == SCSI_START_STOP_UNIT) ||
7127 (pCurrCard->globalFlags & F_NO_FILTER)
7129 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
7133 if(p_sccb->SccbStatus == SCCB_IN_PROCESS)
7135 if (p_sccb->HostStatus || p_sccb->TargetStatus)
7136 p_sccb->SccbStatus = SCCB_ERROR;
7138 p_sccb->SccbStatus = SCCB_SUCCESS;
7141 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
7143 p_sccb->CdbLength = p_sccb->Save_CdbLen;
7144 for (i=0; i < 6; i++) {
7145 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
7149 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
7150 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
7152 FPT_utilUpdateResidual(p_sccb);
7155 pCurrCard->cmdCounter--;
7156 if (!pCurrCard->cmdCounter) {
7158 if (pCurrCard->globalFlags & F_GREEN_PC) {
7159 WR_HARPOON(pCurrCard->ioPort+hp_clkctrl_0,(PWR_DWN | CLKCTRL_DEFAULT));
7160 WR_HARPOON(pCurrCard->ioPort+hp_sys_ctrl, STOP_CLK);
7163 WR_HARPOON(pCurrCard->ioPort+hp_semaphore,
7164 (RD_HARPOON(pCurrCard->ioPort+hp_semaphore) & ~SCCB_MGR_ACTIVE));
7168 if(pCurrCard->discQCount != 0)
7170 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7171 if(((pCurrCard->globalFlags & F_CONLUN_IO) &&
7172 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7174 pCurrCard->discQCount--;
7175 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = NULL;
7179 if(p_sccb->Sccb_tag)
7181 pCurrCard->discQCount--;
7182 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
7185 pCurrCard->discQCount--;
7186 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = NULL;
7192 callback = (CALL_BK_FN)p_sccb->SccbCallback;
7194 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
7195 pCurrCard->currentSCCB = NULL;
7199 /*---------------------------------------------------------------------
7201 * Function: Queue Disconnect
7203 * Description: Add SCCB to our disconnect array.
7205 *---------------------------------------------------------------------*/
7206 static void FPT_queueDisconnect(struct sccb * p_sccb, unsigned char p_card)
7208 struct sccb_mgr_tar_info * currTar_Info;
7210 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7212 if(((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7213 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
7215 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[p_sccb->Lun]] = p_sccb;
7219 if (p_sccb->Sccb_tag)
7221 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] = p_sccb;
7222 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] = 0;
7223 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7226 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]] = p_sccb;
7229 FPT_BL_Card[p_card].currentSCCB = NULL;
7233 /*---------------------------------------------------------------------
7235 * Function: Queue Flush SCCB
7237 * Description: Flush all SCCB's back to the host driver for this target.
7239 *---------------------------------------------------------------------*/
7241 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
7243 unsigned char qtag,thisTarg;
7244 struct sccb * currSCCB;
7245 struct sccb_mgr_tar_info * currTar_Info;
7247 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7248 if(currSCCB != NULL)
7250 thisTarg = (unsigned char)currSCCB->TargID;
7251 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7253 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7255 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7256 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7259 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7261 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7263 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7264 currTar_Info->TarTagQ_Cnt--;
7272 /*---------------------------------------------------------------------
7274 * Function: Queue Flush Target SCCB
7276 * Description: Flush all SCCB's back to the host driver for this target.
7278 *---------------------------------------------------------------------*/
7280 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7281 unsigned char error_code)
7284 struct sccb_mgr_tar_info * currTar_Info;
7286 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7288 for (qtag=0; qtag<QUEUE_DEPTH; qtag++) {
7290 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7291 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg))
7294 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus = (unsigned char)error_code;
7296 FPT_queueCmdComplete(&FPT_BL_Card[p_card],FPT_BL_Card[p_card].discQ_Tbl[qtag], p_card);
7298 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7299 currTar_Info->TarTagQ_Cnt--;
7310 static void FPT_queueAddSccb(struct sccb * p_SCCB, unsigned char p_card)
7312 struct sccb_mgr_tar_info * currTar_Info;
7313 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7315 p_SCCB->Sccb_forwardlink = NULL;
7317 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7319 if (currTar_Info->TarSelQ_Cnt == 0) {
7321 currTar_Info->TarSelQ_Head = p_SCCB;
7326 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7330 currTar_Info->TarSelQ_Tail = p_SCCB;
7331 currTar_Info->TarSelQ_Cnt++;
7335 /*---------------------------------------------------------------------
7337 * Function: Queue Find SCCB
7339 * Description: Search the target select Queue for this SCCB, and
7340 * remove it if found.
7342 *---------------------------------------------------------------------*/
7344 static unsigned char FPT_queueFindSccb(struct sccb * p_SCCB, unsigned char p_card)
7346 struct sccb * q_ptr;
7347 struct sccb_mgr_tar_info * currTar_Info;
7349 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7351 q_ptr = currTar_Info->TarSelQ_Head;
7353 while(q_ptr != NULL) {
7355 if (q_ptr == p_SCCB) {
7358 if (currTar_Info->TarSelQ_Head == q_ptr) {
7360 currTar_Info->TarSelQ_Head = q_ptr->Sccb_forwardlink;
7363 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7365 currTar_Info->TarSelQ_Tail = q_ptr->Sccb_backlink;
7368 if (q_ptr->Sccb_forwardlink != NULL) {
7369 q_ptr->Sccb_forwardlink->Sccb_backlink = q_ptr->Sccb_backlink;
7372 if (q_ptr->Sccb_backlink != NULL) {
7373 q_ptr->Sccb_backlink->Sccb_forwardlink = q_ptr->Sccb_forwardlink;
7376 currTar_Info->TarSelQ_Cnt--;
7382 q_ptr = q_ptr->Sccb_forwardlink;
7392 /*---------------------------------------------------------------------
7394 * Function: Utility Update Residual Count
7396 * Description: Update the XferCnt to the remaining byte count.
7397 * If we transferred all the data then just write zero.
7398 * If Non-SG transfer then report Total Cnt - Actual Transfer
7399 * Cnt. For SG transfers add the count fields of all
7400 * remaining SG elements, as well as any partial remaining
7403 *---------------------------------------------------------------------*/
7405 static void FPT_utilUpdateResidual(struct sccb * p_SCCB)
7407 unsigned long partial_cnt;
7408 unsigned int sg_index;
7409 unsigned long *sg_ptr;
7411 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7413 p_SCCB->DataLength = 0x0000;
7416 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7418 partial_cnt = 0x0000;
7420 sg_index = p_SCCB->Sccb_sgseg;
7422 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
7424 if (p_SCCB->Sccb_SGoffset) {
7426 partial_cnt = p_SCCB->Sccb_SGoffset;
7430 while ( ((unsigned long)sg_index * (unsigned long)SG_ELEMENT_SIZE) <
7431 p_SCCB->DataLength ) {
7433 partial_cnt += *(sg_ptr+(sg_index * 2));
7437 p_SCCB->DataLength = partial_cnt;
7442 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7447 /*---------------------------------------------------------------------
7449 * Function: Wait 1 Second
7451 * Description: Wait for 1 second.
7453 *---------------------------------------------------------------------*/
7455 static void FPT_Wait1Second(unsigned long p_port)
7459 for(i=0; i < 4; i++) {
7461 FPT_Wait(p_port, TO_250ms);
7463 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7466 if((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7472 /*---------------------------------------------------------------------
7474 * Function: FPT_Wait
7476 * Description: Wait the desired delay.
7478 *---------------------------------------------------------------------*/
7480 static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
7482 unsigned char old_timer;
7483 unsigned char green_flag;
7485 old_timer = RD_HARPOON(p_port+hp_seltimeout);
7487 green_flag=RD_HARPOON(p_port+hp_clkctrl_0);
7488 WR_HARPOON(p_port+hp_clkctrl_0, CLKCTRL_DEFAULT);
7490 WR_HARPOON(p_port+hp_seltimeout,p_delay);
7491 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7492 WRW_HARPOON((p_port+hp_intena), (FPT_default_intena & ~TIMEOUT));
7495 WR_HARPOON(p_port+hp_portctrl_0,
7496 (RD_HARPOON(p_port+hp_portctrl_0) | START_TO));
7498 while (!(RDW_HARPOON((p_port+hp_intstat)) & TIMEOUT)) {
7500 if ((RD_HARPOON(p_port+hp_scsictrl_0) & SCSI_RST))
7503 if ((RDW_HARPOON((p_port+hp_intstat)) & SCAM_SEL))
7507 WR_HARPOON(p_port+hp_portctrl_0,
7508 (RD_HARPOON(p_port+hp_portctrl_0) & ~START_TO));
7510 WRW_HARPOON((p_port+hp_intstat), TIMEOUT);
7511 WRW_HARPOON((p_port+hp_intena), FPT_default_intena);
7513 WR_HARPOON(p_port+hp_clkctrl_0,green_flag);
7515 WR_HARPOON(p_port+hp_seltimeout,old_timer);
7519 /*---------------------------------------------------------------------
7521 * Function: Enable/Disable Write to EEPROM
7523 * Description: The EEPROM must first be enabled for writes
7524 * A total of 9 clocks are needed.
7526 *---------------------------------------------------------------------*/
7528 static void FPT_utilEEWriteOnOff(unsigned long p_port,unsigned char p_mode)
7530 unsigned char ee_value;
7532 ee_value = (unsigned char)(RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7536 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7541 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7543 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7544 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7548 /*---------------------------------------------------------------------
7550 * Function: Write EEPROM
7552 * Description: Write a word to the EEPROM at the specified
7555 *---------------------------------------------------------------------*/
7557 static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data, unsigned short ee_addr)
7560 unsigned char ee_value;
7563 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7568 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7571 ee_value |= (SEE_MS + SEE_CS);
7573 for(i = 0x8000; i != 0; i>>=1) {
7578 ee_value &= ~SEE_DO;
7580 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7581 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7582 ee_value |= SEE_CLK; /* Clock data! */
7583 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7584 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7585 ee_value &= ~SEE_CLK;
7586 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7587 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7589 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7590 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS));
7592 FPT_Wait(p_port, TO_10ms);
7594 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7595 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7596 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /* Turn off Master Select */
7599 /*---------------------------------------------------------------------
7601 * Function: Read EEPROM
7603 * Description: Read a word from the EEPROM at the desired
7606 *---------------------------------------------------------------------*/
7608 static unsigned short FPT_utilEERead(unsigned long p_port, unsigned short ee_addr)
7610 unsigned short i, ee_data1, ee_data2;
7613 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7616 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7618 if(ee_data1 == ee_data2)
7621 ee_data1 = ee_data2;
7629 /*---------------------------------------------------------------------
7631 * Function: Read EEPROM Original
7633 * Description: Read a word from the EEPROM at the desired
7636 *---------------------------------------------------------------------*/
7638 static unsigned short FPT_utilEEReadOrg(unsigned long p_port, unsigned short ee_addr)
7641 unsigned char ee_value;
7642 unsigned short i, ee_data;
7644 ee_value = (unsigned char)((RD_HARPOON(p_port+hp_ee_ctrl) & (EXT_ARB_ACK | SCSI_TERM_ENA_H))|
7648 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7651 ee_value |= (SEE_MS + SEE_CS);
7654 for(i = 1; i <= 16; i++) {
7656 ee_value |= SEE_CLK; /* Clock data! */
7657 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7658 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7659 ee_value &= ~SEE_CLK;
7660 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7661 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7665 if (RD_HARPOON(p_port+hp_ee_ctrl) & SEE_DI)
7669 ee_value &= ~(SEE_MS + SEE_CS);
7670 WR_HARPOON(p_port+hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7671 WR_HARPOON(p_port+hp_ee_ctrl, ee_value); /*Turn off Master Select */
7677 /*---------------------------------------------------------------------
7679 * Function: Send EE command and Address to the EEPROM
7681 * Description: Transfers the correct command and sends the address
7684 *---------------------------------------------------------------------*/
7686 static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd, unsigned short ee_addr)
7688 unsigned char ee_value;
7689 unsigned char narrow_flg;
7694 narrow_flg= (unsigned char)(RD_HARPOON(p_port+hp_page_ctrl) & NARROW_SCSI_CARD);
7698 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7700 ee_value |= SEE_CS; /* Set CS to EEPROM */
7701 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7704 for(i = 0x04; i != 0; i>>=1) {
7709 ee_value &= ~SEE_DO;
7711 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7712 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7713 ee_value |= SEE_CLK; /* Clock data! */
7714 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7715 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7716 ee_value &= ~SEE_CLK;
7717 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7718 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7734 ee_value &= ~SEE_DO;
7736 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7737 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7738 ee_value |= SEE_CLK; /* Clock data! */
7739 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7740 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7741 ee_value &= ~SEE_CLK;
7742 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7743 WR_HARPOON(p_port+hp_ee_ctrl, ee_value);
7749 static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7751 unsigned short crc=0;
7754 for (i=0; i < ID_STRING_LENGTH; i++)
7756 ch = (unsigned short) buffer[i];
7757 for(j=0; j < 8; j++)
7760 crc = (crc >> 1) ^ CRCMASK;
7769 static unsigned char FPT_CalcLrc(unsigned char buffer[])
7774 for(i = 0; i < ID_STRING_LENGTH; i++)
7782 The following inline definitions avoid type conflicts.
7785 static inline unsigned char
7786 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7788 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
7792 static inline FlashPoint_CardHandle_T
7793 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7795 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *) FlashPointInfo);
7799 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7801 FlashPoint_ReleaseHostAdapter(CardHandle);
7806 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7808 FlashPoint_StartCCB(CardHandle, (struct sccb *) CCB);
7813 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle, struct BusLogic_CCB *CCB)
7815 FlashPoint_AbortCCB(CardHandle, (struct sccb *) CCB);
7819 static inline boolean
7820 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7822 return FlashPoint_InterruptPending(CardHandle);
7827 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7829 return FlashPoint_HandleInterrupt(CardHandle);
7833 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7834 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7835 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7836 #define FlashPoint_StartCCB FlashPoint__StartCCB
7837 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7838 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7839 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7842 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7846 Define prototypes for the FlashPoint SCCB Manager Functions.
7849 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7850 extern FlashPoint_CardHandle_T
7851 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7852 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7853 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7854 extern boolean FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7855 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7856 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7859 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */