1/*
2
3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
4
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.
10
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
12
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
15
16*/
17
18
19#ifdef CONFIG_SCSI_FLASHPOINT
20
21#define MAX_CARDS 8
22#undef BUSTYPE_PCI
23
24#define CRCMASK 0xA001
25
26#define FAILURE 0xFFFFFFFFL
27
28struct sccb;
29typedef void (*CALL_BK_FN) (struct sccb *);
30
31struct sccb_mgr_info {
32 u32 si_baseaddr;
33 unsigned char si_present;
34 unsigned char si_intvect;
35 unsigned char si_id;
36 unsigned char si_lun;
37 u16 si_fw_revision;
38 u16 si_per_targ_init_sync;
39 u16 si_per_targ_fast_nego;
40 u16 si_per_targ_ultra_nego;
41 u16 si_per_targ_no_disc;
42 u16 si_per_targ_wide_nego;
43 u16 si_flags;
44 unsigned char si_card_family;
45 unsigned char si_bustype;
46 unsigned char si_card_model[3];
47 unsigned char si_relative_cardnum;
48 unsigned char si_reserved[4];
49 u32 si_OS_reserved;
50 unsigned char si_XlatInfo[4];
51 u32 si_reserved2[5];
52 u32 si_secondary_range;
53};
54
55#define SCSI_PARITY_ENA 0x0001
56#define LOW_BYTE_TERM 0x0010
57#define HIGH_BYTE_TERM 0x0020
58#define BUSTYPE_PCI 0x3
59
60#define SUPPORT_16TAR_32LUN 0x0002
61#define SOFT_RESET 0x0004
62#define EXTENDED_TRANSLATION 0x0008
63#define POST_ALL_UNDERRRUNS 0x0040
64#define FLAG_SCAM_ENABLED 0x0080
65#define FLAG_SCAM_LEVEL2 0x0100
66
67#define HARPOON_FAMILY 0x02
68
69/* SCCB struct used for both SCCB and UCB manager compiles!
70 * The UCB Manager treats the SCCB as it's 'native hardware structure'
71 */
72
73/*#pragma pack(1)*/
74struct sccb {
75 unsigned char OperationCode;
76 unsigned char ControlByte;
77 unsigned char CdbLength;
78 unsigned char RequestSenseLength;
79 u32 DataLength;
80 void *DataPointer;
81 unsigned char CcbRes[2];
82 unsigned char HostStatus;
83 unsigned char TargetStatus;
84 unsigned char TargID;
85 unsigned char Lun;
86 unsigned char Cdb[12];
87 unsigned char CcbRes1;
88 unsigned char Reserved1;
89 u32 Reserved2;
90 u32 SensePointer;
91
92 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
93 u32 SccbIOPort; /* Identifies board base port */
94 unsigned char SccbStatus;
95 unsigned char SCCBRes2;
96 u16 SccbOSFlags;
97
98 u32 Sccb_XferCnt; /* actual transfer count */
99 u32 Sccb_ATC;
100 u32 SccbVirtDataPtr; /* virtual addr for OS/2 */
101 u32 Sccb_res1;
102 u16 Sccb_MGRFlags;
103 u16 Sccb_sgseg;
104 unsigned char Sccb_scsimsg; /* identify msg for selection */
105 unsigned char Sccb_tag;
106 unsigned char Sccb_scsistat;
107 unsigned char Sccb_idmsg; /* image of last msg in */
108 struct sccb *Sccb_forwardlink;
109 struct sccb *Sccb_backlink;
110 u32 Sccb_savedATC;
111 unsigned char Save_Cdb[6];
112 unsigned char Save_CdbLen;
113 unsigned char Sccb_XferState;
114 u32 Sccb_SGoffset;
115};
116
117#pragma pack()
118
119#define SCATTER_GATHER_COMMAND 0x02
120#define RESIDUAL_COMMAND 0x03
121#define RESIDUAL_SG_COMMAND 0x04
122#define RESET_COMMAND 0x81
123
124#define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
125#define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
126#define SCCB_DATA_XFER_OUT 0x10 /* Write */
127#define SCCB_DATA_XFER_IN 0x08 /* Read */
128
129#define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
130
131#define BUS_FREE_ST 0
132#define SELECT_ST 1
133#define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
134#define SELECT_SN_ST 3 /* Select w\ Sync Nego */
135#define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
136#define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
137#define COMMAND_ST 6
138#define DATA_OUT_ST 7
139#define DATA_IN_ST 8
140#define DISCONNECT_ST 9
141#define ABORT_ST 11
142
143#define F_HOST_XFER_DIR 0x01
144#define F_ALL_XFERRED 0x02
145#define F_SG_XFER 0x04
146#define F_AUTO_SENSE 0x08
147#define F_ODD_BALL_CNT 0x10
148#define F_NO_DATA_YET 0x80
149
150#define F_STATUSLOADED 0x01
151#define F_DEV_SELECTED 0x04
152
153#define SCCB_COMPLETE 0x00 /* SCCB completed without error */
154#define SCCB_DATA_UNDER_RUN 0x0C
155#define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
156#define SCCB_DATA_OVER_RUN 0x12
157#define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
158
159#define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
160#define SCCB_BM_ERR 0x30 /* BusMaster error. */
161#define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
162
163#define SCCB_IN_PROCESS 0x00
164#define SCCB_SUCCESS 0x01
165#define SCCB_ABORT 0x02
166#define SCCB_ERROR 0x04
167
168#define ORION_FW_REV 3110
169
170#define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
171
172#define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
173
174#define MAX_SCSI_TAR 16
175#define MAX_LUN 32
176#define LUN_MASK 0x1f
177
178#define SG_BUF_CNT 16 /*Number of prefetched elements. */
179
180#define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
181
182#define RD_HARPOON(ioport) inb((u32)ioport)
183#define RDW_HARPOON(ioport) inw((u32)ioport)
184#define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
185#define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
186#define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
187#define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
188
189#define TAR_SYNC_MASK (BIT(7)+BIT(6))
190#define SYNC_TRYING BIT(6)
191#define SYNC_SUPPORTED (BIT(7)+BIT(6))
192
193#define TAR_WIDE_MASK (BIT(5)+BIT(4))
194#define WIDE_ENABLED BIT(4)
195#define WIDE_NEGOCIATED BIT(5)
196
197#define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
198#define TAG_Q_TRYING BIT(2)
199#define TAG_Q_REJECT BIT(3)
200
201#define TAR_ALLOW_DISC BIT(0)
202
203#define EE_SYNC_MASK (BIT(0)+BIT(1))
204#define EE_SYNC_5MB BIT(0)
205#define EE_SYNC_10MB BIT(1)
206#define EE_SYNC_20MB (BIT(0)+BIT(1))
207
208#define EE_WIDE_SCSI BIT(7)
209
210struct sccb_mgr_tar_info {
211
212 struct sccb *TarSelQ_Head;
213 struct sccb *TarSelQ_Tail;
214 unsigned char TarLUN_CA; /*Contingent Allgiance */
215 unsigned char TarTagQ_Cnt;
216 unsigned char TarSelQ_Cnt;
217 unsigned char TarStatus;
218 unsigned char TarEEValue;
219 unsigned char TarSyncCtrl;
220 unsigned char TarReserved[2]; /* for alignment */
221 unsigned char LunDiscQ_Idx[MAX_LUN];
222 unsigned char TarLUNBusy[MAX_LUN];
223};
224
225struct nvram_info {
226 unsigned char niModel; /* Model No. of card */
227 unsigned char niCardNo; /* Card no. */
228 u32 niBaseAddr; /* Port Address of card */
229 unsigned char niSysConf; /* Adapter Configuration byte -
230 Byte 16 of eeprom map */
231 unsigned char niScsiConf; /* SCSI Configuration byte -
232 Byte 17 of eeprom map */
233 unsigned char niScamConf; /* SCAM Configuration byte -
234 Byte 20 of eeprom map */
235 unsigned char niAdapId; /* Host Adapter ID -
236 Byte 24 of eerpom map */
237 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte
238 of targets */
239 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name
240 string of Targets */
241};
242
243#define MODEL_LT 1
244#define MODEL_DL 2
245#define MODEL_LW 3
246#define MODEL_DW 4
247
248struct sccb_card {
249 struct sccb *currentSCCB;
250 struct sccb_mgr_info *cardInfo;
251
252 u32 ioPort;
253
254 unsigned short cmdCounter;
255 unsigned char discQCount;
256 unsigned char tagQ_Lst;
257 unsigned char cardIndex;
258 unsigned char scanIndex;
259 unsigned char globalFlags;
260 unsigned char ourId;
261 struct nvram_info *pNvRamInfo;
262 struct sccb *discQ_Tbl[QUEUE_DEPTH];
263
264};
265
266#define F_TAG_STARTED 0x01
267#define F_CONLUN_IO 0x02
268#define F_DO_RENEGO 0x04
269#define F_NO_FILTER 0x08
270#define F_GREEN_PC 0x10
271#define F_HOST_XFER_ACT 0x20
272#define F_NEW_SCCB_CMD 0x40
273#define F_UPDATE_EEPROM 0x80
274
275#define ID_STRING_LENGTH 32
276#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
277
278#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
279
280#define ASSIGN_ID 0x00
281#define SET_P_FLAG 0x01
282#define CFG_CMPLT 0x03
283#define DOM_MSTR 0x0F
284#define SYNC_PTRN 0x1F
285
286#define ID_0_7 0x18
287#define ID_8_F 0x11
288#define MISC_CODE 0x14
289#define CLR_P_FLAG 0x18
290
291#define INIT_SELTD 0x01
292#define LEVEL2_TAR 0x02
293
294enum scam_id_st { ID0, ID1, ID2, ID3, ID4, ID5, ID6, ID7, ID8, ID9, ID10, ID11,
295 ID12,
296 ID13, ID14, ID15, ID_UNUSED, ID_UNASSIGNED, ID_ASSIGNED, LEGACY,
297 CLR_PRIORITY, NO_ID_AVAIL
298};
299
300typedef struct SCCBscam_info {
301
302 unsigned char id_string[ID_STRING_LENGTH];
303 enum scam_id_st state;
304
305} SCCBSCAM_INFO;
306
307#define SCSI_REQUEST_SENSE 0x03
308#define SCSI_READ 0x08
309#define SCSI_WRITE 0x0A
310#define SCSI_START_STOP_UNIT 0x1B
311#define SCSI_READ_EXTENDED 0x28
312#define SCSI_WRITE_EXTENDED 0x2A
313#define SCSI_WRITE_AND_VERIFY 0x2E
314
315#define SSGOOD 0x00
316#define SSCHECK 0x02
317#define SSQ_FULL 0x28
318
319#define SMCMD_COMP 0x00
320#define SMEXT 0x01
321#define SMSAVE_DATA_PTR 0x02
322#define SMREST_DATA_PTR 0x03
323#define SMDISC 0x04
324#define SMABORT 0x06
325#define SMREJECT 0x07
326#define SMNO_OP 0x08
327#define SMPARITY 0x09
328#define SMDEV_RESET 0x0C
329#define SMABORT_TAG 0x0D
330#define SMINIT_RECOVERY 0x0F
331#define SMREL_RECOVERY 0x10
332
333#define SMIDENT 0x80
334#define DISC_PRIV 0x40
335
336#define SMSYNC 0x01
337#define SMWDTR 0x03
338#define SM8BIT 0x00
339#define SM16BIT 0x01
340#define SMIGNORWR 0x23 /* Ignore Wide Residue */
341
342#define SIX_BYTE_CMD 0x06
343#define TWELVE_BYTE_CMD 0x0C
344
345#define ASYNC 0x00
346#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
347
348#define EEPROM_WD_CNT 256
349
350#define EEPROM_CHECK_SUM 0
351#define FW_SIGNATURE 2
352#define MODEL_NUMB_0 4
353#define MODEL_NUMB_2 6
354#define MODEL_NUMB_4 8
355#define SYSTEM_CONFIG 16
356#define SCSI_CONFIG 17
357#define BIOS_CONFIG 18
358#define SCAM_CONFIG 20
359#define ADAPTER_SCSI_ID 24
360
361#define IGNORE_B_SCAN 32
362#define SEND_START_ENA 34
363#define DEVICE_ENABLE 36
364
365#define SYNC_RATE_TBL 38
366#define SYNC_RATE_TBL01 38
367#define SYNC_RATE_TBL23 40
368#define SYNC_RATE_TBL45 42
369#define SYNC_RATE_TBL67 44
370#define SYNC_RATE_TBL89 46
371#define SYNC_RATE_TBLab 48
372#define SYNC_RATE_TBLcd 50
373#define SYNC_RATE_TBLef 52
374
375#define EE_SCAMBASE 256
376
377#define SCAM_ENABLED BIT(2)
378#define SCAM_LEVEL2 BIT(3)
379
380#define RENEGO_ENA BIT(10)
381#define CONNIO_ENA BIT(11)
382#define GREEN_PC_ENA BIT(12)
383
384#define AUTO_RATE_00 00
385#define AUTO_RATE_05 01
386#define AUTO_RATE_10 02
387#define AUTO_RATE_20 03
388
389#define WIDE_NEGO_BIT BIT(7)
390#define DISC_ENABLE_BIT BIT(6)
391
392#define hp_vendor_id_0 0x00 /* LSB */
393#define ORION_VEND_0 0x4B
394
395#define hp_vendor_id_1 0x01 /* MSB */
396#define ORION_VEND_1 0x10
397
398#define hp_device_id_0 0x02 /* LSB */
399#define ORION_DEV_0 0x30
400
401#define hp_device_id_1 0x03 /* MSB */
402#define ORION_DEV_1 0x81
403
404 /* Sub Vendor ID and Sub Device ID only available in
405 Harpoon Version 2 and higher */
406
407#define hp_sub_device_id_0 0x06 /* LSB */
408
409#define hp_semaphore 0x0C
410#define SCCB_MGR_ACTIVE BIT(0)
411#define TICKLE_ME BIT(1)
412#define SCCB_MGR_PRESENT BIT(3)
413#define BIOS_IN_USE BIT(4)
414
415#define hp_sys_ctrl 0x0F
416
417#define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
418#define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
419#define HALT_MACH BIT(3) /*Halt State Machine */
420#define HARD_ABORT BIT(4) /*Hard Abort */
421
422#define hp_host_blk_cnt 0x13
423
424#define XFER_BLK64 0x06 /* 1 1 0 64 byte per block */
425
426#define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes */
427
428#define hp_int_mask 0x17
429
430#define INT_CMD_COMPL BIT(0) /* DMA command complete */
431#define INT_EXT_STATUS BIT(1) /* Extended Status Set */
432
433#define hp_xfer_cnt_lo 0x18
434#define hp_xfer_cnt_hi 0x1A
435#define hp_xfer_cmd 0x1B
436
437#define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
438#define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
439
440#define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
441
442#define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
443
444#define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
445
446#define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
447#define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
448
449#define hp_host_addr_lo 0x1C
450#define hp_host_addr_hmi 0x1E
451
452#define hp_ee_ctrl 0x22
453
454#define EXT_ARB_ACK BIT(7)
455#define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
456#define SEE_MS BIT(5)
457#define SEE_CS BIT(3)
458#define SEE_CLK BIT(2)
459#define SEE_DO BIT(1)
460#define SEE_DI BIT(0)
461
462#define EE_READ 0x06
463#define EE_WRITE 0x05
464#define EWEN 0x04
465#define EWEN_ADDR 0x03C0
466#define EWDS 0x04
467#define EWDS_ADDR 0x0000
468
469#define hp_bm_ctrl 0x26
470
471#define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
472#define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
473#define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
474#define FAST_SINGLE BIT(6) /*?? */
475
476#define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
477
478#define hp_sg_addr 0x28
479#define hp_page_ctrl 0x29
480
481#define SCATTER_EN BIT(0)
482#define SGRAM_ARAM BIT(1)
483#define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
484#define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
485
486#define hp_pci_stat_cfg 0x2D
487
488#define REC_MASTER_ABORT BIT(5) /*received Master abort */
489
490#define hp_rev_num 0x33
491
492#define hp_stack_data 0x34
493#define hp_stack_addr 0x35
494
495#define hp_ext_status 0x36
496
497#define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
498#define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
499#define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
500#define CMD_ABORTED BIT(4) /*Command aborted */
501#define BM_PARITY_ERR BIT(5) /*parity error on data received */
502#define PIO_OVERRUN BIT(6) /*Slave data overrun */
503#define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
504#define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
505 BM_PARITY_ERR | PIO_OVERRUN)
506
507#define hp_int_status 0x37
508
509#define EXT_STATUS_ON BIT(1) /*Extended status is valid */
510#define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
511#define INT_ASSERTED BIT(5) /* */
512
513#define hp_fifo_cnt 0x38
514
515#define hp_intena 0x40
516
517#define RESET BIT(7)
518#define PROG_HLT BIT(6)
519#define PARITY BIT(5)
520#define FIFO BIT(4)
521#define SEL BIT(3)
522#define SCAM_SEL BIT(2)
523#define RSEL BIT(1)
524#define TIMEOUT BIT(0)
525#define BUS_FREE BIT(15)
526#define XFER_CNT_0 BIT(14)
527#define PHASE BIT(13)
528#define IUNKWN BIT(12)
529#define ICMD_COMP BIT(11)
530#define ITICKLE BIT(10)
531#define IDO_STRT BIT(9)
532#define ITAR_DISC BIT(8)
533#define AUTO_INT (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
534#define CLR_ALL_INT 0xFFFF
535#define CLR_ALL_INT_1 0xFF00
536
537#define hp_intstat 0x42
538
539#define hp_scsisig 0x44
540
541#define SCSI_SEL BIT(7)
542#define SCSI_BSY BIT(6)
543#define SCSI_REQ BIT(5)
544#define SCSI_ACK BIT(4)
545#define SCSI_ATN BIT(3)
546#define SCSI_CD BIT(2)
547#define SCSI_MSG BIT(1)
548#define SCSI_IOBIT BIT(0)
549
550#define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
551#define S_MSGO_PH (BIT(2)+BIT(1) )
552#define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
553#define S_DATAI_PH ( BIT(0))
554#define S_DATAO_PH 0x00
555#define S_ILL_PH ( BIT(1) )
556
557#define hp_scsictrl_0 0x45
558
559#define SEL_TAR BIT(6)
560#define ENA_ATN BIT(4)
561#define ENA_RESEL BIT(2)
562#define SCSI_RST BIT(1)
563#define ENA_SCAM_SEL BIT(0)
564
565#define hp_portctrl_0 0x46
566
567#define SCSI_PORT BIT(7)
568#define SCSI_INBIT BIT(6)
569#define DMA_PORT BIT(5)
570#define DMA_RD BIT(4)
571#define HOST_PORT BIT(3)
572#define HOST_WRT BIT(2)
573#define SCSI_BUS_EN BIT(1)
574#define START_TO BIT(0)
575
576#define hp_scsireset 0x47
577
578#define SCSI_INI BIT(6)
579#define SCAM_EN BIT(5)
580#define DMA_RESET BIT(3)
581#define HPSCSI_RESET BIT(2)
582#define PROG_RESET BIT(1)
583#define FIFO_CLR BIT(0)
584
585#define hp_xfercnt_0 0x48
586#define hp_xfercnt_2 0x4A
587
588#define hp_fifodata_0 0x4C
589#define hp_addstat 0x4E
590
591#define SCAM_TIMER BIT(7)
592#define SCSI_MODE8 BIT(3)
593#define SCSI_PAR_ERR BIT(0)
594
595#define hp_prgmcnt_0 0x4F
596
597#define hp_selfid_0 0x50
598#define hp_selfid_1 0x51
599#define hp_arb_id 0x52
600
601#define hp_select_id 0x53
602
603#define hp_synctarg_base 0x54
604#define hp_synctarg_12 0x54
605#define hp_synctarg_13 0x55
606#define hp_synctarg_14 0x56
607#define hp_synctarg_15 0x57
608
609#define hp_synctarg_8 0x58
610#define hp_synctarg_9 0x59
611#define hp_synctarg_10 0x5A
612#define hp_synctarg_11 0x5B
613
614#define hp_synctarg_4 0x5C
615#define hp_synctarg_5 0x5D
616#define hp_synctarg_6 0x5E
617#define hp_synctarg_7 0x5F
618
619#define hp_synctarg_0 0x60
620#define hp_synctarg_1 0x61
621#define hp_synctarg_2 0x62
622#define hp_synctarg_3 0x63
623
624#define NARROW_SCSI BIT(4)
625#define DEFAULT_OFFSET 0x0F
626
627#define hp_autostart_0 0x64
628#define hp_autostart_1 0x65
629#define hp_autostart_3 0x67
630
631#define AUTO_IMMED BIT(5)
632#define SELECT BIT(6)
633#define END_DATA (BIT(7)+BIT(6))
634
635#define hp_gp_reg_0 0x68
636#define hp_gp_reg_1 0x69
637#define hp_gp_reg_3 0x6B
638
639#define hp_seltimeout 0x6C
640
641#define TO_4ms 0x67 /* 3.9959ms */
642
643#define TO_5ms 0x03 /* 4.9152ms */
644#define TO_10ms 0x07 /* 11.xxxms */
645#define TO_250ms 0x99 /* 250.68ms */
646#define TO_290ms 0xB1 /* 289.99ms */
647
648#define hp_clkctrl_0 0x6D
649
650#define PWR_DWN BIT(6)
651#define ACTdeassert BIT(4)
652#define CLK_40MHZ (BIT(1) + BIT(0))
653
654#define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
655
656#define hp_fiforead 0x6E
657#define hp_fifowrite 0x6F
658
659#define hp_offsetctr 0x70
660#define hp_xferstat 0x71
661
662#define FIFO_EMPTY BIT(6)
663
664#define hp_portctrl_1 0x72
665
666#define CHK_SCSI_P BIT(3)
667#define HOST_MODE8 BIT(0)
668
669#define hp_xfer_pad 0x73
670
671#define ID_UNLOCK BIT(3)
672
673#define hp_scsidata_0 0x74
674#define hp_scsidata_1 0x75
675
676#define hp_aramBase 0x80
677#define BIOS_DATA_OFFSET 0x60
678#define BIOS_RELATIVE_CARD 0x64
679
680#define AR3 (BIT(9) + BIT(8))
681#define SDATA BIT(10)
682
683#define CRD_OP BIT(11) /* Cmp Reg. w/ Data */
684
685#define CRR_OP BIT(12) /* Cmp Reg. w. Reg. */
686
687#define CPE_OP (BIT(14)+BIT(11)) /* Cmp SCSI phs & Branch EQ */
688
689#define CPN_OP (BIT(14)+BIT(12)) /* Cmp SCSI phs & Branch NOT EQ */
690
691#define ADATA_OUT 0x00
692#define ADATA_IN BIT(8)
693#define ACOMMAND BIT(10)
694#define ASTATUS (BIT(10)+BIT(8))
695#define AMSG_OUT (BIT(10)+BIT(9))
696#define AMSG_IN (BIT(10)+BIT(9)+BIT(8))
697
698#define BRH_OP BIT(13) /* Branch */
699
700#define ALWAYS 0x00
701#define EQUAL BIT(8)
702#define NOT_EQ BIT(9)
703
704#define TCB_OP (BIT(13)+BIT(11)) /* Test condition & branch */
705
706#define FIFO_0 BIT(10)
707
708#define MPM_OP BIT(15) /* Match phase and move data */
709
710#define MRR_OP BIT(14) /* Move DReg. to Reg. */
711
712#define S_IDREG (BIT(2)+BIT(1)+BIT(0))
713
714#define D_AR0 0x00
715#define D_AR1 BIT(0)
716#define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
717
718#define RAT_OP (BIT(14)+BIT(13)+BIT(11))
719
720#define SSI_OP (BIT(15)+BIT(11))
721
722#define SSI_ITAR_DISC (ITAR_DISC >> 8)
723#define SSI_IDO_STRT (IDO_STRT >> 8)
724
725#define SSI_ICMD_COMP (ICMD_COMP >> 8)
726#define SSI_ITICKLE (ITICKLE >> 8)
727
728#define SSI_IUNKWN (IUNKWN >> 8)
729#define SSI_INO_CC (IUNKWN >> 8)
730#define SSI_IRFAIL (IUNKWN >> 8)
731
732#define NP 0x10 /*Next Phase */
733#define NTCMD 0x02 /*Non- Tagged Command start */
734#define CMDPZ 0x04 /*Command phase */
735#define DINT 0x12 /*Data Out/In interrupt */
736#define DI 0x13 /*Data Out */
737#define DC 0x19 /*Disconnect Message */
738#define ST 0x1D /*Status Phase */
739#define UNKNWN 0x24 /*Unknown bus action */
740#define CC 0x25 /*Command Completion failure */
741#define TICK 0x26 /*New target reselected us. */
742#define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
743
744#define ID_MSG_STRT hp_aramBase + 0x00
745#define NON_TAG_ID_MSG hp_aramBase + 0x06
746#define CMD_STRT hp_aramBase + 0x08
747#define SYNC_MSGS hp_aramBase + 0x08
748
749#define TAG_STRT 0x00
750#define DISCONNECT_START 0x10/2
751#define END_DATA_START 0x14/2
752#define CMD_ONLY_STRT CMDPZ/2
753#define SELCHK_STRT SELCHK/2
754
755#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
756/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
757 xfercnt <<= 16,\
758 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
759 */
760#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
761 addr >>= 16,\
762 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
763 WR_HARP32(port,hp_xfercnt_0,count),\
764 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
765 count >>= 16,\
766 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
767
768#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
769 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
770
771#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
772 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
773
774#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
775 WR_HARPOON(port+hp_scsireset, 0x00))
776
777#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
778 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
779
780#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
781 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
782
783#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
784 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
785
786#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
787 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
788
789static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
790 unsigned char syncFlag);
791static void FPT_ssel(u32 port, unsigned char p_card);
792static void FPT_sres(u32 port, unsigned char p_card,
793 struct sccb_card *pCurrCard);
794static void FPT_shandem(u32 port, unsigned char p_card,
795 struct sccb *pCurrSCCB);
796static void FPT_stsyncn(u32 port, unsigned char p_card);
797static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
798 unsigned char offset);
799static void FPT_sssyncv(u32 p_port, unsigned char p_id,
800 unsigned char p_sync_value,
801 struct sccb_mgr_tar_info *currTar_Info);
802static void FPT_sresb(u32 port, unsigned char p_card);
803static void FPT_sxfrp(u32 p_port, unsigned char p_card);
804static void FPT_schkdd(u32 port, unsigned char p_card);
805static unsigned char FPT_RdStack(u32 port, unsigned char index);
806static void FPT_WrStack(u32 portBase, unsigned char index,
807 unsigned char data);
808static unsigned char FPT_ChkIfChipInitialized(u32 ioPort);
809
810static void FPT_SendMsg(u32 port, unsigned char message);
811static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
812 unsigned char error_code);
813
814static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card);
815static void FPT_RNVRamData(struct nvram_info *pNvRamInfo);
816
817static unsigned char FPT_siwidn(u32 port, unsigned char p_card);
818static void FPT_stwidn(u32 port, unsigned char p_card);
819static void FPT_siwidr(u32 port, unsigned char width);
820
821static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
822 unsigned char p_card);
823static void FPT_queueDisconnect(struct sccb *p_SCCB, unsigned char p_card);
824static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
825 struct sccb *p_SCCB, unsigned char p_card);
826static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
827 unsigned char p_card);
828static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
829static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char card);
830static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
831 unsigned char p_card);
832static void FPT_utilUpdateResidual(struct sccb *p_SCCB);
833static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
834static unsigned char FPT_CalcLrc(unsigned char buffer[]);
835
836static void FPT_Wait1Second(u32 p_port);
837static void FPT_Wait(u32 p_port, unsigned char p_delay);
838static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode);
839static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
840 unsigned short ee_addr);
841static unsigned short FPT_utilEERead(u32 p_port,
842 unsigned short ee_addr);
843static unsigned short FPT_utilEEReadOrg(u32 p_port,
844 unsigned short ee_addr);
845static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
846 unsigned short ee_addr);
847
848static void FPT_phaseDataOut(u32 port, unsigned char p_card);
849static void FPT_phaseDataIn(u32 port, unsigned char p_card);
850static void FPT_phaseCommand(u32 port, unsigned char p_card);
851static void FPT_phaseStatus(u32 port, unsigned char p_card);
852static void FPT_phaseMsgOut(u32 port, unsigned char p_card);
853static void FPT_phaseMsgIn(u32 port, unsigned char p_card);
854static void FPT_phaseIllegal(u32 port, unsigned char p_card);
855
856static void FPT_phaseDecode(u32 port, unsigned char p_card);
857static void FPT_phaseChkFifo(u32 port, unsigned char p_card);
858static void FPT_phaseBusFree(u32 p_port, unsigned char p_card);
859
860static void FPT_XbowInit(u32 port, unsigned char scamFlg);
861static void FPT_BusMasterInit(u32 p_port);
862static void FPT_DiagEEPROM(u32 p_port);
863
864static void FPT_dataXferProcessor(u32 port,
865 struct sccb_card *pCurrCard);
866static void FPT_busMstrSGDataXferStart(u32 port,
867 struct sccb *pCurrSCCB);
868static void FPT_busMstrDataXferStart(u32 port,
869 struct sccb *pCurrSCCB);
870static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
871 struct sccb *pCurrSCCB);
872static void FPT_hostDataXferRestart(struct sccb *currSCCB);
873
874static unsigned char FPT_SccbMgr_bad_isr(u32 p_port,
875 unsigned char p_card,
876 struct sccb_card *pCurrCard,
877 unsigned short p_int);
878
879static void FPT_SccbMgrTableInitAll(void);
880static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
881 unsigned char p_card);
882static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
883 unsigned char target);
884
885static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
886 unsigned char p_power_up);
887
888static int FPT_scarb(u32 p_port, unsigned char p_sel_type);
889static void FPT_scbusf(u32 p_port);
890static void FPT_scsel(u32 p_port);
891static void FPT_scasid(unsigned char p_card, u32 p_port);
892static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data);
893static unsigned char FPT_scsendi(u32 p_port,
894 unsigned char p_id_string[]);
895static unsigned char FPT_sciso(u32 p_port,
896 unsigned char p_id_string[]);
897static void FPT_scwirod(u32 p_port, unsigned char p_data_bit);
898static void FPT_scwiros(u32 p_port, unsigned char p_data_bit);
899static unsigned char FPT_scvalq(unsigned char p_quintet);
900static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id);
901static void FPT_scwtsel(u32 p_port);
902static void FPT_inisci(unsigned char p_card, u32 p_port,
903 unsigned char p_our_id);
904static void FPT_scsavdi(unsigned char p_card, u32 p_port);
905static unsigned char FPT_scmachid(unsigned char p_card,
906 unsigned char p_id_string[]);
907
908static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card);
909static void FPT_autoLoadDefaultMap(u32 p_port);
910
911static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] =
912 { {{0}} };
913static struct sccb_card FPT_BL_Card[MAX_CARDS] = { {0} };
914static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { {{0}} };
915static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { {0} };
916
917static unsigned char FPT_mbCards = 0;
918static unsigned char FPT_scamHAString[] =
919 { 0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C',
920 ' ', 'B', 'T', '-', '9', '3', '0',
921 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
922 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
923};
924
925static unsigned short FPT_default_intena = 0;
926
927static void (*FPT_s_PhaseTbl[8]) (u32, unsigned char) = {
9280};
929
930/*---------------------------------------------------------------------
931 *
932 * Function: FlashPoint_ProbeHostAdapter
933 *
934 * Description: Setup and/or Search for cards and return info to caller.
935 *
936 *---------------------------------------------------------------------*/
937
938static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo)
939{
940 static unsigned char first_time = 1;
941
942 unsigned char i, j, id, ScamFlg;
943 unsigned short temp, temp2, temp3, temp4, temp5, temp6;
944 u32 ioport;
945 struct nvram_info *pCurrNvRam;
946
947 ioport = pCardInfo->si_baseaddr;
948
949 if (RD_HARPOON(ioport + hp_vendor_id_0) != ORION_VEND_0)
950 return (int)FAILURE;
951
952 if ((RD_HARPOON(ioport + hp_vendor_id_1) != ORION_VEND_1))
953 return (int)FAILURE;
954
955 if ((RD_HARPOON(ioport + hp_device_id_0) != ORION_DEV_0))
956 return (int)FAILURE;
957
958 if ((RD_HARPOON(ioport + hp_device_id_1) != ORION_DEV_1))
959 return (int)FAILURE;
960
961 if (RD_HARPOON(ioport + hp_rev_num) != 0x0f) {
962
963/* For new Harpoon then check for sub_device ID LSB
964 the bits(0-3) must be all ZERO for compatible with
965 current version of SCCBMgr, else skip this Harpoon
966 device. */
967
968 if (RD_HARPOON(ioport + hp_sub_device_id_0) & 0x0f)
969 return (int)FAILURE;
970 }
971
972 if (first_time) {
973 FPT_SccbMgrTableInitAll();
974 first_time = 0;
975 FPT_mbCards = 0;
976 }
977
978 if (FPT_RdStack(ioport, 0) != 0x00) {
979 if (FPT_ChkIfChipInitialized(ioport) == 0) {
980 pCurrNvRam = NULL;
981 WR_HARPOON(ioport + hp_semaphore, 0x00);
982 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
983 FPT_DiagEEPROM(ioport);
984 } else {
985 if (FPT_mbCards < MAX_MB_CARDS) {
986 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
987 FPT_mbCards++;
988 pCurrNvRam->niBaseAddr = ioport;
989 FPT_RNVRamData(pCurrNvRam);
990 } else
991 return (int)FAILURE;
992 }
993 } else
994 pCurrNvRam = NULL;
995
996 WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
997 WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
998
999 if (pCurrNvRam)
1000 pCardInfo->si_id = pCurrNvRam->niAdapId;
1001 else
1002 pCardInfo->si_id =
1003 (unsigned
1004 char)(FPT_utilEERead(ioport,
1005 (ADAPTER_SCSI_ID /
1006 2)) & (unsigned char)0x0FF);
1007
1008 pCardInfo->si_lun = 0x00;
1009 pCardInfo->si_fw_revision = ORION_FW_REV;
1010 temp2 = 0x0000;
1011 temp3 = 0x0000;
1012 temp4 = 0x0000;
1013 temp5 = 0x0000;
1014 temp6 = 0x0000;
1015
1016 for (id = 0; id < (16 / 2); id++) {
1017
1018 if (pCurrNvRam) {
1019 temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
1020 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1021 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1022 } else
1023 temp =
1024 FPT_utilEERead(ioport,
1025 (unsigned short)((SYNC_RATE_TBL / 2)
1026 + id));
1027
1028 for (i = 0; i < 2; temp >>= 8, i++) {
1029
1030 temp2 >>= 1;
1031 temp3 >>= 1;
1032 temp4 >>= 1;
1033 temp5 >>= 1;
1034 temp6 >>= 1;
1035 switch (temp & 0x3) {
1036 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1037 temp6 |= 0x8000; /* Fall through */
1038 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1039 temp5 |= 0x8000; /* Fall through */
1040 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1041 temp2 |= 0x8000; /* Fall through */
1042 case AUTO_RATE_00: /* Asynchronous */
1043 break;
1044 }
1045
1046 if (temp & DISC_ENABLE_BIT)
1047 temp3 |= 0x8000;
1048
1049 if (temp & WIDE_NEGO_BIT)
1050 temp4 |= 0x8000;
1051
1052 }
1053 }
1054
1055 pCardInfo->si_per_targ_init_sync = temp2;
1056 pCardInfo->si_per_targ_no_disc = temp3;
1057 pCardInfo->si_per_targ_wide_nego = temp4;
1058 pCardInfo->si_per_targ_fast_nego = temp5;
1059 pCardInfo->si_per_targ_ultra_nego = temp6;
1060
1061 if (pCurrNvRam)
1062 i = pCurrNvRam->niSysConf;
1063 else
1064 i = (unsigned
1065 char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)));
1066
1067 if (pCurrNvRam)
1068 ScamFlg = pCurrNvRam->niScamConf;
1069 else
1070 ScamFlg =
1071 (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1072
1073 pCardInfo->si_flags = 0x0000;
1074
1075 if (i & 0x01)
1076 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1077
1078 if (!(i & 0x02))
1079 pCardInfo->si_flags |= SOFT_RESET;
1080
1081 if (i & 0x10)
1082 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1083
1084 if (ScamFlg & SCAM_ENABLED)
1085 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1086
1087 if (ScamFlg & SCAM_LEVEL2)
1088 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1089
1090 j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1091 if (i & 0x04) {
1092 j |= SCSI_TERM_ENA_L;
1093 }
1094 WR_HARPOON(ioport + hp_bm_ctrl, j);
1095
1096 j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1097 if (i & 0x08) {
1098 j |= SCSI_TERM_ENA_H;
1099 }
1100 WR_HARPOON(ioport + hp_ee_ctrl, j);
1101
1102 if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD))
1103
1104 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1105
1106 pCardInfo->si_card_family = HARPOON_FAMILY;
1107 pCardInfo->si_bustype = BUSTYPE_PCI;
1108
1109 if (pCurrNvRam) {
1110 pCardInfo->si_card_model[0] = '9';
1111 switch (pCurrNvRam->niModel & 0x0f) {
1112 case MODEL_LT:
1113 pCardInfo->si_card_model[1] = '3';
1114 pCardInfo->si_card_model[2] = '0';
1115 break;
1116 case MODEL_LW:
1117 pCardInfo->si_card_model[1] = '5';
1118 pCardInfo->si_card_model[2] = '0';
1119 break;
1120 case MODEL_DL:
1121 pCardInfo->si_card_model[1] = '3';
1122 pCardInfo->si_card_model[2] = '2';
1123 break;
1124 case MODEL_DW:
1125 pCardInfo->si_card_model[1] = '5';
1126 pCardInfo->si_card_model[2] = '2';
1127 break;
1128 }
1129 } else {
1130 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0 / 2));
1131 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1132 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2 / 2));
1133
1134 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1135 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1136 }
1137
1138 if (pCardInfo->si_card_model[1] == '3') {
1139 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1140 pCardInfo->si_flags |= LOW_BYTE_TERM;
1141 } else if (pCardInfo->si_card_model[2] == '0') {
1142 temp = RD_HARPOON(ioport + hp_xfer_pad);
1143 WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4)));
1144 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1145 pCardInfo->si_flags |= LOW_BYTE_TERM;
1146 WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4)));
1147 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1148 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1149 WR_HARPOON(ioport + hp_xfer_pad, temp);
1150 } else {
1151 temp = RD_HARPOON(ioport + hp_ee_ctrl);
1152 temp2 = RD_HARPOON(ioport + hp_xfer_pad);
1153 WR_HARPOON(ioport + hp_ee_ctrl, (temp | SEE_CS));
1154 WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1155 temp3 = 0;
1156 for (i = 0; i < 8; i++) {
1157 temp3 <<= 1;
1158 if (!(RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)))
1159 temp3 |= 1;
1160 WR_HARPOON(ioport + hp_xfer_pad, (temp2 & ~BIT(4)));
1161 WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1162 }
1163 WR_HARPOON(ioport + hp_ee_ctrl, temp);
1164 WR_HARPOON(ioport + hp_xfer_pad, temp2);
1165 if (!(temp3 & BIT(7)))
1166 pCardInfo->si_flags |= LOW_BYTE_TERM;
1167 if (!(temp3 & BIT(6)))
1168 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1169 }
1170
1171 ARAM_ACCESS(ioport);
1172
1173 for (i = 0; i < 4; i++) {
1174
1175 pCardInfo->si_XlatInfo[i] =
1176 RD_HARPOON(ioport + hp_aramBase + BIOS_DATA_OFFSET + i);
1177 }
1178
1179 /* return with -1 if no sort, else return with
1180 logical card number sorted by BIOS (zero-based) */
1181
1182 pCardInfo->si_relative_cardnum =
1183 (unsigned
1184 char)(RD_HARPOON(ioport + hp_aramBase + BIOS_RELATIVE_CARD) - 1);
1185
1186 SGRAM_ACCESS(ioport);
1187
1188 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1189 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1190 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1191 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1192 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1193 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1194 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1195 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1196
1197 pCardInfo->si_present = 0x01;
1198
1199 return 0;
1200}
1201
1202/*---------------------------------------------------------------------
1203 *
1204 * Function: FlashPoint_HardwareResetHostAdapter
1205 *
1206 * Description: Setup adapter for normal operation (hard reset).
1207 *
1208 *---------------------------------------------------------------------*/
1209
1210static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
1211 *pCardInfo)
1212{
1213 struct sccb_card *CurrCard = NULL;
1214 struct nvram_info *pCurrNvRam;
1215 unsigned char i, j, thisCard, ScamFlg;
1216 unsigned short temp, sync_bit_map, id;
1217 u32 ioport;
1218
1219 ioport = pCardInfo->si_baseaddr;
1220
1221 for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) {
1222
1223 if (thisCard == MAX_CARDS)
1224 return (void *)FAILURE;
1225
1226 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1227
1228 CurrCard = &FPT_BL_Card[thisCard];
1229 FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1230 break;
1231 }
1232
1233 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1234
1235 FPT_BL_Card[thisCard].ioPort = ioport;
1236 CurrCard = &FPT_BL_Card[thisCard];
1237
1238 if (FPT_mbCards)
1239 for (i = 0; i < FPT_mbCards; i++) {
1240 if (CurrCard->ioPort ==
1241 FPT_nvRamInfo[i].niBaseAddr)
1242 CurrCard->pNvRamInfo =
1243 &FPT_nvRamInfo[i];
1244 }
1245 FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1246 CurrCard->cardIndex = thisCard;
1247 CurrCard->cardInfo = pCardInfo;
1248
1249 break;
1250 }
1251 }
1252
1253 pCurrNvRam = CurrCard->pNvRamInfo;
1254
1255 if (pCurrNvRam) {
1256 ScamFlg = pCurrNvRam->niScamConf;
1257 } else {
1258 ScamFlg =
1259 (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1260 }
1261
1262 FPT_BusMasterInit(ioport);
1263 FPT_XbowInit(ioport, ScamFlg);
1264
1265 FPT_autoLoadDefaultMap(ioport);
1266
1267 for (i = 0, id = 0x01; i != pCardInfo->si_id; i++, id <<= 1) {
1268 }
1269
1270 WR_HARPOON(ioport + hp_selfid_0, id);
1271 WR_HARPOON(ioport + hp_selfid_1, 0x00);
1272 WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id);
1273 CurrCard->ourId = pCardInfo->si_id;
1274
1275 i = (unsigned char)pCardInfo->si_flags;
1276 if (i & SCSI_PARITY_ENA)
1277 WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P));
1278
1279 j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1280 if (i & LOW_BYTE_TERM)
1281 j |= SCSI_TERM_ENA_L;
1282 WR_HARPOON(ioport + hp_bm_ctrl, j);
1283
1284 j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1285 if (i & HIGH_BYTE_TERM)
1286 j |= SCSI_TERM_ENA_H;
1287 WR_HARPOON(ioport + hp_ee_ctrl, j);
1288
1289 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1290
1291 FPT_sresb(ioport, thisCard);
1292
1293 FPT_scini(thisCard, pCardInfo->si_id, 0);
1294 }
1295
1296 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1297 CurrCard->globalFlags |= F_NO_FILTER;
1298
1299 if (pCurrNvRam) {
1300 if (pCurrNvRam->niSysConf & 0x10)
1301 CurrCard->globalFlags |= F_GREEN_PC;
1302 } else {
1303 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)) & GREEN_PC_ENA)
1304 CurrCard->globalFlags |= F_GREEN_PC;
1305 }
1306
1307 /* Set global flag to indicate Re-Negotiation to be done on all
1308 ckeck condition */
1309 if (pCurrNvRam) {
1310 if (pCurrNvRam->niScsiConf & 0x04)
1311 CurrCard->globalFlags |= F_DO_RENEGO;
1312 } else {
1313 if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & RENEGO_ENA)
1314 CurrCard->globalFlags |= F_DO_RENEGO;
1315 }
1316
1317 if (pCurrNvRam) {
1318 if (pCurrNvRam->niScsiConf & 0x08)
1319 CurrCard->globalFlags |= F_CONLUN_IO;
1320 } else {
1321 if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & CONNIO_ENA)
1322 CurrCard->globalFlags |= F_CONLUN_IO;
1323 }
1324
1325 temp = pCardInfo->si_per_targ_no_disc;
1326
1327 for (i = 0, id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1328
1329 if (temp & id)
1330 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1331 }
1332
1333 sync_bit_map = 0x0001;
1334
1335 for (id = 0; id < (MAX_SCSI_TAR / 2); id++) {
1336
1337 if (pCurrNvRam) {
1338 temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
1339 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1340 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1341 } else
1342 temp =
1343 FPT_utilEERead(ioport,
1344 (unsigned short)((SYNC_RATE_TBL / 2)
1345 + id));
1346
1347 for (i = 0; i < 2; temp >>= 8, i++) {
1348
1349 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1350
1351 FPT_sccbMgrTbl[thisCard][id * 2 +
1352 i].TarEEValue =
1353 (unsigned char)temp;
1354 }
1355
1356 else {
1357 FPT_sccbMgrTbl[thisCard][id * 2 +
1358 i].TarStatus |=
1359 SYNC_SUPPORTED;
1360 FPT_sccbMgrTbl[thisCard][id * 2 +
1361 i].TarEEValue =
1362 (unsigned char)(temp & ~EE_SYNC_MASK);
1363 }
1364
1365/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1366 (id*2+i >= 8)){
1367*/
1368 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map) {
1369
1370 FPT_sccbMgrTbl[thisCard][id * 2 +
1371 i].TarEEValue |=
1372 EE_WIDE_SCSI;
1373
1374 }
1375
1376 else { /* NARROW SCSI */
1377 FPT_sccbMgrTbl[thisCard][id * 2 +
1378 i].TarStatus |=
1379 WIDE_NEGOCIATED;
1380 }
1381
1382 sync_bit_map <<= 1;
1383
1384 }
1385 }
1386
1387 WR_HARPOON((ioport + hp_semaphore),
1388 (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) |
1389 SCCB_MGR_PRESENT));
1390
1391 return (void *)CurrCard;
1392}
1393
1394static void FlashPoint_ReleaseHostAdapter(void *pCurrCard)
1395{
1396 unsigned char i;
1397 u32 portBase;
1398 u32 regOffset;
1399 u32 scamData;
1400 u32 *pScamTbl;
1401 struct nvram_info *pCurrNvRam;
1402
1403 pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
1404
1405 if (pCurrNvRam) {
1406 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1407 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1408 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1409 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1410 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1411
1412 for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1413 FPT_WrStack(pCurrNvRam->niBaseAddr,
1414 (unsigned char)(i + 5),
1415 pCurrNvRam->niSyncTbl[i]);
1416
1417 portBase = pCurrNvRam->niBaseAddr;
1418
1419 for (i = 0; i < MAX_SCSI_TAR; i++) {
1420 regOffset = hp_aramBase + 64 + i * 4;
1421 pScamTbl = (u32 *)&pCurrNvRam->niScamTbl[i];
1422 scamData = *pScamTbl;
1423 WR_HARP32(portBase, regOffset, scamData);
1424 }
1425
1426 } else {
1427 FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0);
1428 }
1429}
1430
1431static void FPT_RNVRamData(struct nvram_info *pNvRamInfo)
1432{
1433 unsigned char i;
1434 u32 portBase;
1435 u32 regOffset;
1436 u32 scamData;
1437 u32 *pScamTbl;
1438
1439 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1440 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1441 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1442 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1443 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1444
1445 for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1446 pNvRamInfo->niSyncTbl[i] =
1447 FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i + 5));
1448
1449 portBase = pNvRamInfo->niBaseAddr;
1450
1451 for (i = 0; i < MAX_SCSI_TAR; i++) {
1452 regOffset = hp_aramBase + 64 + i * 4;
1453 RD_HARP32(portBase, regOffset, scamData);
1454 pScamTbl = (u32 *)&pNvRamInfo->niScamTbl[i];
1455 *pScamTbl = scamData;
1456 }
1457
1458}
1459
1460static unsigned char FPT_RdStack(u32 portBase, unsigned char index)
1461{
1462 WR_HARPOON(portBase + hp_stack_addr, index);
1463 return RD_HARPOON(portBase + hp_stack_data);
1464}
1465
1466static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data)
1467{
1468 WR_HARPOON(portBase + hp_stack_addr, index);
1469 WR_HARPOON(portBase + hp_stack_data, data);
1470}
1471
1472static unsigned char FPT_ChkIfChipInitialized(u32 ioPort)
1473{
1474 if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1475 return 0;
1476 if ((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1477 != CLKCTRL_DEFAULT)
1478 return 0;
1479 if ((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1480 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1481 return 1;
1482 return 0;
1483
1484}
1485
1486/*---------------------------------------------------------------------
1487 *
1488 * Function: FlashPoint_StartCCB
1489 *
1490 * Description: Start a command pointed to by p_Sccb. When the
1491 * command is completed it will be returned via the
1492 * callback function.
1493 *
1494 *---------------------------------------------------------------------*/
1495static void FlashPoint_StartCCB(void *curr_card, struct sccb *p_Sccb)
1496{
1497 u32 ioport;
1498 unsigned char thisCard, lun;
1499 struct sccb *pSaveSccb;
1500 CALL_BK_FN callback;
1501 struct sccb_card *pCurrCard = curr_card;
1502
1503 thisCard = pCurrCard->cardIndex;
1504 ioport = pCurrCard->ioPort;
1505
1506 if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) {
1507
1508 p_Sccb->HostStatus = SCCB_COMPLETE;
1509 p_Sccb->SccbStatus = SCCB_ERROR;
1510 callback = (CALL_BK_FN) p_Sccb->SccbCallback;
1511 if (callback)
1512 callback(p_Sccb);
1513
1514 return;
1515 }
1516
1517 FPT_sinits(p_Sccb, thisCard);
1518
1519 if (!pCurrCard->cmdCounter) {
1520 WR_HARPOON(ioport + hp_semaphore,
1521 (RD_HARPOON(ioport + hp_semaphore)
1522 | SCCB_MGR_ACTIVE));
1523
1524 if (pCurrCard->globalFlags & F_GREEN_PC) {
1525 WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
1526 WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
1527 }
1528 }
1529
1530 pCurrCard->cmdCounter++;
1531
1532 if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) {
1533
1534 WR_HARPOON(ioport + hp_semaphore,
1535 (RD_HARPOON(ioport + hp_semaphore)
1536 | TICKLE_ME));
1537 if (p_Sccb->OperationCode == RESET_COMMAND) {
1538 pSaveSccb =
1539 pCurrCard->currentSCCB;
1540 pCurrCard->currentSCCB = p_Sccb;
1541 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1542 pCurrCard->currentSCCB =
1543 pSaveSccb;
1544 } else {
1545 FPT_queueAddSccb(p_Sccb, thisCard);
1546 }
1547 }
1548
1549 else if ((RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1550
1551 if (p_Sccb->OperationCode == RESET_COMMAND) {
1552 pSaveSccb =
1553 pCurrCard->currentSCCB;
1554 pCurrCard->currentSCCB = p_Sccb;
1555 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1556 pCurrCard->currentSCCB =
1557 pSaveSccb;
1558 } else {
1559 FPT_queueAddSccb(p_Sccb, thisCard);
1560 }
1561 }
1562
1563 else {
1564
1565 MDISABLE_INT(ioport);
1566
1567 if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
1568 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].
1569 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1570 lun = p_Sccb->Lun;
1571 else
1572 lun = 0;
1573 if ((pCurrCard->currentSCCB == NULL) &&
1574 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0)
1575 && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1576 == 0)) {
1577
1578 pCurrCard->currentSCCB = p_Sccb;
1579 FPT_ssel(p_Sccb->SccbIOPort, thisCard);
1580 }
1581
1582 else {
1583
1584 if (p_Sccb->OperationCode == RESET_COMMAND) {
1585 pSaveSccb = pCurrCard->currentSCCB;
1586 pCurrCard->currentSCCB = p_Sccb;
1587 FPT_queueSelectFail(&FPT_BL_Card[thisCard],
1588 thisCard);
1589 pCurrCard->currentSCCB = pSaveSccb;
1590 } else {
1591 FPT_queueAddSccb(p_Sccb, thisCard);
1592 }
1593 }
1594
1595 MENABLE_INT(ioport);
1596 }
1597
1598}
1599
1600/*---------------------------------------------------------------------
1601 *
1602 * Function: FlashPoint_AbortCCB
1603 *
1604 * Description: Abort the command pointed to by p_Sccb. When the
1605 * command is completed it will be returned via the
1606 * callback function.
1607 *
1608 *---------------------------------------------------------------------*/
1609static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb)
1610{
1611 u32 ioport;
1612
1613 unsigned char thisCard;
1614 CALL_BK_FN callback;
1615 unsigned char TID;
1616 struct sccb *pSaveSCCB;
1617 struct sccb_mgr_tar_info *currTar_Info;
1618
1619 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1620
1621 thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1622
1623 if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1624
1625 if (FPT_queueFindSccb(p_Sccb, thisCard)) {
1626
1627 ((struct sccb_card *)pCurrCard)->cmdCounter--;
1628
1629 if (!((struct sccb_card *)pCurrCard)->cmdCounter)
1630 WR_HARPOON(ioport + hp_semaphore,
1631 (RD_HARPOON(ioport + hp_semaphore)
1632 & (unsigned
1633 char)(~(SCCB_MGR_ACTIVE |
1634 TICKLE_ME))));
1635
1636 p_Sccb->SccbStatus = SCCB_ABORT;
1637 callback = p_Sccb->SccbCallback;
1638 callback(p_Sccb);
1639
1640 return 0;
1641 }
1642
1643 else {
1644 if (((struct sccb_card *)pCurrCard)->currentSCCB ==
1645 p_Sccb) {
1646 p_Sccb->SccbStatus = SCCB_ABORT;
1647 return 0;
1648
1649 }
1650
1651 else {
1652
1653 TID = p_Sccb->TargID;
1654
1655 if (p_Sccb->Sccb_tag) {
1656 MDISABLE_INT(ioport);
1657 if (((struct sccb_card *)pCurrCard)->
1658 discQ_Tbl[p_Sccb->Sccb_tag] ==
1659 p_Sccb) {
1660 p_Sccb->SccbStatus = SCCB_ABORT;
1661 p_Sccb->Sccb_scsistat =
1662 ABORT_ST;
1663 p_Sccb->Sccb_scsimsg =
1664 SMABORT_TAG;
1665
1666 if (((struct sccb_card *)
1667 pCurrCard)->currentSCCB ==
1668 NULL) {
1669 ((struct sccb_card *)
1670 pCurrCard)->
1671 currentSCCB = p_Sccb;
1672 FPT_ssel(ioport,
1673 thisCard);
1674 } else {
1675 pSaveSCCB =
1676 ((struct sccb_card
1677 *)pCurrCard)->
1678 currentSCCB;
1679 ((struct sccb_card *)
1680 pCurrCard)->
1681 currentSCCB = p_Sccb;
1682 FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard);
1683 ((struct sccb_card *)
1684 pCurrCard)->
1685 currentSCCB = pSaveSCCB;
1686 }
1687 }
1688 MENABLE_INT(ioport);
1689 return 0;
1690 } else {
1691 currTar_Info =
1692 &FPT_sccbMgrTbl[thisCard][p_Sccb->
1693 TargID];
1694
1695 if (FPT_BL_Card[thisCard].
1696 discQ_Tbl[currTar_Info->
1697 LunDiscQ_Idx[p_Sccb->Lun]]
1698 == p_Sccb) {
1699 p_Sccb->SccbStatus = SCCB_ABORT;
1700 return 0;
1701 }
1702 }
1703 }
1704 }
1705 }
1706 return -1;
1707}
1708
1709/*---------------------------------------------------------------------
1710 *
1711 * Function: FlashPoint_InterruptPending
1712 *
1713 * Description: Do a quick check to determine if there is a pending
1714 * interrupt for this card and disable the IRQ Pin if so.
1715 *
1716 *---------------------------------------------------------------------*/
1717static unsigned char FlashPoint_InterruptPending(void *pCurrCard)
1718{
1719 u32 ioport;
1720
1721 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1722
1723 if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) {
1724 return 1;
1725 }
1726
1727 else
1728
1729 return 0;
1730}
1731
1732/*---------------------------------------------------------------------
1733 *
1734 * Function: FlashPoint_HandleInterrupt
1735 *
1736 * Description: This is our entry point when an interrupt is generated
1737 * by the card and the upper level driver passes it on to
1738 * us.
1739 *
1740 *---------------------------------------------------------------------*/
1741static int FlashPoint_HandleInterrupt(void *pcard)
1742{
1743 struct sccb *currSCCB;
1744 unsigned char thisCard, result, bm_status, bm_int_st;
1745 unsigned short hp_int;
1746 unsigned char i, target;
1747 struct sccb_card *pCurrCard = pcard;
1748 u32 ioport;
1749
1750 thisCard = pCurrCard->cardIndex;
1751 ioport = pCurrCard->ioPort;
1752
1753 MDISABLE_INT(ioport);
1754
1755 if ((bm_int_st = RD_HARPOON(ioport + hp_int_status)) & EXT_STATUS_ON)
1756 bm_status = RD_HARPOON(ioport + hp_ext_status) &
1757 (unsigned char)BAD_EXT_STATUS;
1758 else
1759 bm_status = 0;
1760
1761 WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1762
1763 while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) &
1764 FPT_default_intena) | bm_status) {
1765
1766 currSCCB = pCurrCard->currentSCCB;
1767
1768 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1769 result =
1770 FPT_SccbMgr_bad_isr(ioport, thisCard, pCurrCard,
1771 hp_int);
1772 WRW_HARPOON((ioport + hp_intstat),
1773 (FIFO | TIMEOUT | RESET | SCAM_SEL));
1774 bm_status = 0;
1775
1776 if (result) {
1777
1778 MENABLE_INT(ioport);
1779 return result;
1780 }
1781 }
1782
1783 else if (hp_int & ICMD_COMP) {
1784
1785 if (!(hp_int & BUS_FREE)) {
1786 /* Wait for the BusFree before starting a new command. We
1787 must also check for being reselected since the BusFree
1788 may not show up if another device reselects us in 1.5us or
1789 less. SRR Wednesday, 3/8/1995.
1790 */
1791 while (!
1792 (RDW_HARPOON((ioport + hp_intstat)) &
1793 (BUS_FREE | RSEL))) ;
1794 }
1795
1796 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1797
1798 FPT_phaseChkFifo(ioport, thisCard);
1799
1800/* WRW_HARPOON((ioport+hp_intstat),
1801 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1802 */
1803
1804 WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1);
1805
1806 FPT_autoCmdCmplt(ioport, thisCard);
1807
1808 }
1809
1810 else if (hp_int & ITAR_DISC) {
1811
1812 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1813 FPT_phaseChkFifo(ioport, thisCard);
1814
1815 if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1816 SMSAVE_DATA_PTR) {
1817
1818 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1819 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1820
1821 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1822 }
1823
1824 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1825 FPT_queueDisconnect(currSCCB, thisCard);
1826
1827 /* Wait for the BusFree before starting a new command. We
1828 must also check for being reselected since the BusFree
1829 may not show up if another device reselects us in 1.5us or
1830 less. SRR Wednesday, 3/8/1995.
1831 */
1832 while (!
1833 (RDW_HARPOON((ioport + hp_intstat)) &
1834 (BUS_FREE | RSEL))
1835 && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE)
1836 && RD_HARPOON((ioport + hp_scsisig)) ==
1837 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG |
1838 SCSI_IOBIT))) ;
1839
1840 /*
1841 The additional loop exit condition above detects a timing problem
1842 with the revision D/E harpoon chips. The caller should reset the
1843 host adapter to recover when 0xFE is returned.
1844 */
1845 if (!
1846 (RDW_HARPOON((ioport + hp_intstat)) &
1847 (BUS_FREE | RSEL))) {
1848 MENABLE_INT(ioport);
1849 return 0xFE;
1850 }
1851
1852 WRW_HARPOON((ioport + hp_intstat),
1853 (BUS_FREE | ITAR_DISC));
1854
1855 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1856
1857 }
1858
1859 else if (hp_int & RSEL) {
1860
1861 WRW_HARPOON((ioport + hp_intstat),
1862 (PROG_HLT | RSEL | PHASE | BUS_FREE));
1863
1864 if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) {
1865 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1866 FPT_phaseChkFifo(ioport, thisCard);
1867
1868 if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1869 SMSAVE_DATA_PTR) {
1870 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1871 currSCCB->Sccb_XferState |=
1872 F_NO_DATA_YET;
1873 currSCCB->Sccb_savedATC =
1874 currSCCB->Sccb_ATC;
1875 }
1876
1877 WRW_HARPOON((ioport + hp_intstat),
1878 (BUS_FREE | ITAR_DISC));
1879 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1880 FPT_queueDisconnect(currSCCB, thisCard);
1881 }
1882
1883 FPT_sres(ioport, thisCard, pCurrCard);
1884 FPT_phaseDecode(ioport, thisCard);
1885
1886 }
1887
1888 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) {
1889
1890 WRW_HARPOON((ioport + hp_intstat),
1891 (IDO_STRT | XFER_CNT_0));
1892 FPT_phaseDecode(ioport, thisCard);
1893
1894 }
1895
1896 else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) {
1897 WRW_HARPOON((ioport + hp_intstat),
1898 (PHASE | IUNKWN | PROG_HLT));
1899 if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char)
1900 0x3f) < (unsigned char)SELCHK) {
1901 FPT_phaseDecode(ioport, thisCard);
1902 } else {
1903 /* Harpoon problem some SCSI target device respond to selection
1904 with short BUSY pulse (<400ns) this will make the Harpoon is not able
1905 to latch the correct Target ID into reg. x53.
1906 The work around require to correct this reg. But when write to this
1907 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
1908 need to read this reg first then restore it later. After update to 0x53 */
1909
1910 i = (unsigned
1911 char)(RD_HARPOON(ioport + hp_fifowrite));
1912 target =
1913 (unsigned
1914 char)(RD_HARPOON(ioport + hp_gp_reg_3));
1915 WR_HARPOON(ioport + hp_xfer_pad,
1916 (unsigned char)ID_UNLOCK);
1917 WR_HARPOON(ioport + hp_select_id,
1918 (unsigned char)(target | target <<
1919 4));
1920 WR_HARPOON(ioport + hp_xfer_pad,
1921 (unsigned char)0x00);
1922 WR_HARPOON(ioport + hp_fifowrite, i);
1923 WR_HARPOON(ioport + hp_autostart_3,
1924 (AUTO_IMMED + TAG_STRT));
1925 }
1926 }
1927
1928 else if (hp_int & XFER_CNT_0) {
1929
1930 WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0);
1931
1932 FPT_schkdd(ioport, thisCard);
1933
1934 }
1935
1936 else if (hp_int & BUS_FREE) {
1937
1938 WRW_HARPOON((ioport + hp_intstat), BUS_FREE);
1939
1940 if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
1941
1942 FPT_hostDataXferAbort(ioport, thisCard,
1943 currSCCB);
1944 }
1945
1946 FPT_phaseBusFree(ioport, thisCard);
1947 }
1948
1949 else if (hp_int & ITICKLE) {
1950
1951 WRW_HARPOON((ioport + hp_intstat), ITICKLE);
1952 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1953 }
1954
1955 if (((struct sccb_card *)pCurrCard)->
1956 globalFlags & F_NEW_SCCB_CMD) {
1957
1958 pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1959
1960 if (pCurrCard->currentSCCB == NULL)
1961 FPT_queueSearchSelect(pCurrCard, thisCard);
1962
1963 if (pCurrCard->currentSCCB != NULL) {
1964 pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1965 FPT_ssel(ioport, thisCard);
1966 }
1967
1968 break;
1969
1970 }
1971
1972 } /*end while */
1973
1974 MENABLE_INT(ioport);
1975
1976 return 0;
1977}
1978
1979/*---------------------------------------------------------------------
1980 *
1981 * Function: Sccb_bad_isr
1982 *
1983 * Description: Some type of interrupt has occurred which is slightly
1984 * out of the ordinary. We will now decode it fully, in
1985 * this routine. This is broken up in an attempt to save
1986 * processing time.
1987 *
1988 *---------------------------------------------------------------------*/
1989static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card,
1990 struct sccb_card *pCurrCard,
1991 unsigned short p_int)
1992{
1993 unsigned char temp, ScamFlg;
1994 struct sccb_mgr_tar_info *currTar_Info;
1995 struct nvram_info *pCurrNvRam;
1996
1997 if (RD_HARPOON(p_port + hp_ext_status) &
1998 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) {
1999
2000 if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
2001
2002 FPT_hostDataXferAbort(p_port, p_card,
2003 pCurrCard->currentSCCB);
2004 }
2005
2006 if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT)
2007 {
2008 WR_HARPOON(p_port + hp_pci_stat_cfg,
2009 (RD_HARPOON(p_port + hp_pci_stat_cfg) &
2010 ~REC_MASTER_ABORT));
2011
2012 WR_HARPOON(p_port + hp_host_blk_cnt, 0x00);
2013
2014 }
2015
2016 if (pCurrCard->currentSCCB != NULL) {
2017
2018 if (!pCurrCard->currentSCCB->HostStatus)
2019 pCurrCard->currentSCCB->HostStatus =
2020 SCCB_BM_ERR;
2021
2022 FPT_sxfrp(p_port, p_card);
2023
2024 temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
2025 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2026 WR_HARPOON(p_port + hp_ee_ctrl,
2027 ((unsigned char)temp | SEE_MS | SEE_CS));
2028 WR_HARPOON(p_port + hp_ee_ctrl, temp);
2029
2030 if (!
2031 (RDW_HARPOON((p_port + hp_intstat)) &
2032 (BUS_FREE | RESET))) {
2033 FPT_phaseDecode(p_port, p_card);
2034 }
2035 }
2036 }
2037
2038 else if (p_int & RESET) {
2039
2040 WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
2041 WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
2042 if (pCurrCard->currentSCCB != NULL) {
2043
2044 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2045
2046 FPT_hostDataXferAbort(p_port, p_card,
2047 pCurrCard->currentSCCB);
2048 }
2049
2050 DISABLE_AUTO(p_port);
2051
2052 FPT_sresb(p_port, p_card);
2053
2054 while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) {
2055 }
2056
2057 pCurrNvRam = pCurrCard->pNvRamInfo;
2058 if (pCurrNvRam) {
2059 ScamFlg = pCurrNvRam->niScamConf;
2060 } else {
2061 ScamFlg =
2062 (unsigned char)FPT_utilEERead(p_port,
2063 SCAM_CONFIG / 2);
2064 }
2065
2066 FPT_XbowInit(p_port, ScamFlg);
2067
2068 FPT_scini(p_card, pCurrCard->ourId, 0);
2069
2070 return 0xFF;
2071 }
2072
2073 else if (p_int & FIFO) {
2074
2075 WRW_HARPOON((p_port + hp_intstat), FIFO);
2076
2077 if (pCurrCard->currentSCCB != NULL)
2078 FPT_sxfrp(p_port, p_card);
2079 }
2080
2081 else if (p_int & TIMEOUT) {
2082
2083 DISABLE_AUTO(p_port);
2084
2085 WRW_HARPOON((p_port + hp_intstat),
2086 (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE |
2087 IUNKWN));
2088
2089 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2090
2091 currTar_Info =
2092 &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2093 if ((pCurrCard->globalFlags & F_CONLUN_IO)
2094 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2095 TAG_Q_TRYING))
2096 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] =
2097 0;
2098 else
2099 currTar_Info->TarLUNBusy[0] = 0;
2100
2101 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2102 currTar_Info->TarSyncCtrl = 0;
2103 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2104 }
2105
2106 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2107 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2108 }
2109
2110 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,
2111 currTar_Info);
2112
2113 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2114
2115 }
2116
2117 else if (p_int & SCAM_SEL) {
2118
2119 FPT_scarb(p_port, LEVEL2_TAR);
2120 FPT_scsel(p_port);
2121 FPT_scasid(p_card, p_port);
2122
2123 FPT_scbusf(p_port);
2124
2125 WRW_HARPOON((p_port + hp_intstat), SCAM_SEL);
2126 }
2127
2128 return 0x00;
2129}
2130
2131/*---------------------------------------------------------------------
2132 *
2133 * Function: SccbMgrTableInit
2134 *
2135 * Description: Initialize all Sccb manager data structures.
2136 *
2137 *---------------------------------------------------------------------*/
2138
2139static void FPT_SccbMgrTableInitAll(void)
2140{
2141 unsigned char thisCard;
2142
2143 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) {
2144 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard);
2145
2146 FPT_BL_Card[thisCard].ioPort = 0x00;
2147 FPT_BL_Card[thisCard].cardInfo = NULL;
2148 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2149 FPT_BL_Card[thisCard].ourId = 0x00;
2150 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2151 }
2152}
2153
2154/*---------------------------------------------------------------------
2155 *
2156 * Function: SccbMgrTableInit
2157 *
2158 * Description: Initialize all Sccb manager data structures.
2159 *
2160 *---------------------------------------------------------------------*/
2161
2162static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
2163 unsigned char p_card)
2164{
2165 unsigned char scsiID, qtag;
2166
2167 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2168 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2169 }
2170
2171 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
2172 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2173 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2174 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2175 }
2176
2177 pCurrCard->scanIndex = 0x00;
2178 pCurrCard->currentSCCB = NULL;
2179 pCurrCard->globalFlags = 0x00;
2180 pCurrCard->cmdCounter = 0x00;
2181 pCurrCard->tagQ_Lst = 0x01;
2182 pCurrCard->discQCount = 0;
2183
2184}
2185
2186/*---------------------------------------------------------------------
2187 *
2188 * Function: SccbMgrTableInit
2189 *
2190 * Description: Initialize all Sccb manager data structures.
2191 *
2192 *---------------------------------------------------------------------*/
2193
2194static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
2195 unsigned char target)
2196{
2197
2198 unsigned char lun, qtag;
2199 struct sccb_mgr_tar_info *currTar_Info;
2200
2201 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2202
2203 currTar_Info->TarSelQ_Cnt = 0;
2204 currTar_Info->TarSyncCtrl = 0;
2205
2206 currTar_Info->TarSelQ_Head = NULL;
2207 currTar_Info->TarSelQ_Tail = NULL;
2208 currTar_Info->TarTagQ_Cnt = 0;
2209 currTar_Info->TarLUN_CA = 0;
2210
2211 for (lun = 0; lun < MAX_LUN; lun++) {
2212 currTar_Info->TarLUNBusy[lun] = 0;
2213 currTar_Info->LunDiscQ_Idx[lun] = 0;
2214 }
2215
2216 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2217 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) {
2218 if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
2219 target) {
2220 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2221 FPT_BL_Card[p_card].discQCount--;
2222 }
2223 }
2224 }
2225}
2226
2227/*---------------------------------------------------------------------
2228 *
2229 * Function: sfetm
2230 *
2231 * Description: Read in a message byte from the SCSI bus, and check
2232 * for a parity error.
2233 *
2234 *---------------------------------------------------------------------*/
2235
2236static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB)
2237{
2238 unsigned char message;
2239 unsigned short TimeOutLoop;
2240
2241 TimeOutLoop = 0;
2242 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2243 (TimeOutLoop++ < 20000)) {
2244 }
2245
2246 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2247
2248 message = RD_HARPOON(port + hp_scsidata_0);
2249
2250 WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH);
2251
2252 if (TimeOutLoop > 20000)
2253 message = 0x00; /* force message byte = 0 if Time Out on Req */
2254
2255 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
2256 (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) {
2257 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2258 WR_HARPOON(port + hp_xferstat, 0);
2259 WR_HARPOON(port + hp_fiforead, 0);
2260 WR_HARPOON(port + hp_fifowrite, 0);
2261 if (pCurrSCCB != NULL) {
2262 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2263 }
2264 message = 0x00;
2265 do {
2266 ACCEPT_MSG_ATN(port);
2267 TimeOutLoop = 0;
2268 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2269 (TimeOutLoop++ < 20000)) {
2270 }
2271 if (TimeOutLoop > 20000) {
2272 WRW_HARPOON((port + hp_intstat), PARITY);
2273 return message;
2274 }
2275 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) !=
2276 S_MSGI_PH) {
2277 WRW_HARPOON((port + hp_intstat), PARITY);
2278 return message;
2279 }
2280 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2281
2282 RD_HARPOON(port + hp_scsidata_0);
2283
2284 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2285
2286 } while (1);
2287
2288 }
2289 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2290 WR_HARPOON(port + hp_xferstat, 0);
2291 WR_HARPOON(port + hp_fiforead, 0);
2292 WR_HARPOON(port + hp_fifowrite, 0);
2293 return message;
2294}
2295
2296/*---------------------------------------------------------------------
2297 *
2298 * Function: FPT_ssel
2299 *
2300 * Description: Load up automation and select target device.
2301 *
2302 *---------------------------------------------------------------------*/
2303
2304static void FPT_ssel(u32 port, unsigned char p_card)
2305{
2306
2307 unsigned char auto_loaded, i, target, *theCCB;
2308
2309 u32 cdb_reg;
2310 struct sccb_card *CurrCard;
2311 struct sccb *currSCCB;
2312 struct sccb_mgr_tar_info *currTar_Info;
2313 unsigned char lastTag, lun;
2314
2315 CurrCard = &FPT_BL_Card[p_card];
2316 currSCCB = CurrCard->currentSCCB;
2317 target = currSCCB->TargID;
2318 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2319 lastTag = CurrCard->tagQ_Lst;
2320
2321 ARAM_ACCESS(port);
2322
2323 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2324 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2325
2326 if (((CurrCard->globalFlags & F_CONLUN_IO) &&
2327 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2328
2329 lun = currSCCB->Lun;
2330 else
2331 lun = 0;
2332
2333 if (CurrCard->globalFlags & F_TAG_STARTED) {
2334 if (!(currSCCB->ControlByte & F_USE_CMD_Q)) {
2335 if ((currTar_Info->TarLUN_CA == 0)
2336 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2337 == TAG_Q_TRYING)) {
2338
2339 if (currTar_Info->TarTagQ_Cnt != 0) {
2340 currTar_Info->TarLUNBusy[lun] = 1;
2341 FPT_queueSelectFail(CurrCard, p_card);
2342 SGRAM_ACCESS(port);
2343 return;
2344 }
2345
2346 else {
2347 currTar_Info->TarLUNBusy[lun] = 1;
2348 }
2349
2350 }
2351 /*End non-tagged */
2352 else {
2353 currTar_Info->TarLUNBusy[lun] = 1;
2354 }
2355
2356 }
2357 /*!Use cmd Q Tagged */
2358 else {
2359 if (currTar_Info->TarLUN_CA == 1) {
2360 FPT_queueSelectFail(CurrCard, p_card);
2361 SGRAM_ACCESS(port);
2362 return;
2363 }
2364
2365 currTar_Info->TarLUNBusy[lun] = 1;
2366
2367 } /*else use cmd Q tagged */
2368
2369 }
2370 /*if glob tagged started */
2371 else {
2372 currTar_Info->TarLUNBusy[lun] = 1;
2373 }
2374
2375 if ((((CurrCard->globalFlags & F_CONLUN_IO) &&
2376 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2377 || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) {
2378 if (CurrCard->discQCount >= QUEUE_DEPTH) {
2379 currTar_Info->TarLUNBusy[lun] = 1;
2380 FPT_queueSelectFail(CurrCard, p_card);
2381 SGRAM_ACCESS(port);
2382 return;
2383 }
2384 for (i = 1; i < QUEUE_DEPTH; i++) {
2385 if (++lastTag >= QUEUE_DEPTH)
2386 lastTag = 1;
2387 if (CurrCard->discQ_Tbl[lastTag] == NULL) {
2388 CurrCard->tagQ_Lst = lastTag;
2389 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2390 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2391 CurrCard->discQCount++;
2392 break;
2393 }
2394 }
2395 if (i == QUEUE_DEPTH) {
2396 currTar_Info->TarLUNBusy[lun] = 1;
2397 FPT_queueSelectFail(CurrCard, p_card);
2398 SGRAM_ACCESS(port);
2399 return;
2400 }
2401 }
2402
2403 auto_loaded = 0;
2404
2405 WR_HARPOON(port + hp_select_id, target);
2406 WR_HARPOON(port + hp_gp_reg_3, target); /* Use by new automation logic */
2407
2408 if (currSCCB->OperationCode == RESET_COMMAND) {
2409 WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2410 (currSCCB->
2411 Sccb_idmsg & ~DISC_PRIV)));
2412
2413 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
2414
2415 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2416
2417 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2418 auto_loaded = 1;
2419 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2420
2421 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2422 currTar_Info->TarSyncCtrl = 0;
2423 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2424 }
2425
2426 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2427 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2428 }
2429
2430 FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info);
2431 FPT_SccbMgrTableInitTarget(p_card, target);
2432
2433 }
2434
2435 else if (currSCCB->Sccb_scsistat == ABORT_ST) {
2436 WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2437 (currSCCB->
2438 Sccb_idmsg & ~DISC_PRIV)));
2439
2440 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
2441
2442 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT +
2443 (((unsigned
2444 char)(currSCCB->
2445 ControlByte &
2446 TAG_TYPE_MASK)
2447 >> 6) | (unsigned char)
2448 0x20)));
2449 WRW_HARPOON((port + SYNC_MSGS + 2),
2450 (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag));
2451 WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP));
2452
2453 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2454 auto_loaded = 1;
2455
2456 }
2457
2458 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2459 auto_loaded = FPT_siwidn(port, p_card);
2460 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2461 }
2462
2463 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2464 == SYNC_SUPPORTED)) {
2465 auto_loaded = FPT_sisyncn(port, p_card, 0);
2466 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2467 }
2468
2469 if (!auto_loaded) {
2470
2471 if (currSCCB->ControlByte & F_USE_CMD_Q) {
2472
2473 CurrCard->globalFlags |= F_TAG_STARTED;
2474
2475 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2476 == TAG_Q_REJECT) {
2477 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2478
2479 /* Fix up the start instruction with a jump to
2480 Non-Tag-CMD handling */
2481 WRW_HARPOON((port + ID_MSG_STRT),
2482 BRH_OP + ALWAYS + NTCMD);
2483
2484 WRW_HARPOON((port + NON_TAG_ID_MSG),
2485 (MPM_OP + AMSG_OUT +
2486 currSCCB->Sccb_idmsg));
2487
2488 WR_HARPOON(port + hp_autostart_3,
2489 (SELECT + SELCHK_STRT));
2490
2491 /* Setup our STATE so we know what happened when
2492 the wheels fall off. */
2493 currSCCB->Sccb_scsistat = SELECT_ST;
2494
2495 currTar_Info->TarLUNBusy[lun] = 1;
2496 }
2497
2498 else {
2499 WRW_HARPOON((port + ID_MSG_STRT),
2500 (MPM_OP + AMSG_OUT +
2501 currSCCB->Sccb_idmsg));
2502
2503 WRW_HARPOON((port + ID_MSG_STRT + 2),
2504 (MPM_OP + AMSG_OUT +
2505 (((unsigned char)(currSCCB->
2506 ControlByte &
2507 TAG_TYPE_MASK)
2508 >> 6) | (unsigned char)0x20)));
2509
2510 for (i = 1; i < QUEUE_DEPTH; i++) {
2511 if (++lastTag >= QUEUE_DEPTH)
2512 lastTag = 1;
2513 if (CurrCard->discQ_Tbl[lastTag] ==
2514 NULL) {
2515 WRW_HARPOON((port +
2516 ID_MSG_STRT + 6),
2517 (MPM_OP + AMSG_OUT +
2518 lastTag));
2519 CurrCard->tagQ_Lst = lastTag;
2520 currSCCB->Sccb_tag = lastTag;
2521 CurrCard->discQ_Tbl[lastTag] =
2522 currSCCB;
2523 CurrCard->discQCount++;
2524 break;
2525 }
2526 }
2527
2528 if (i == QUEUE_DEPTH) {
2529 currTar_Info->TarLUNBusy[lun] = 1;
2530 FPT_queueSelectFail(CurrCard, p_card);
2531 SGRAM_ACCESS(port);
2532 return;
2533 }
2534
2535 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2536
2537 WR_HARPOON(port + hp_autostart_3,
2538 (SELECT + SELCHK_STRT));
2539 }
2540 }
2541
2542 else {
2543
2544 WRW_HARPOON((port + ID_MSG_STRT),
2545 BRH_OP + ALWAYS + NTCMD);
2546
2547 WRW_HARPOON((port + NON_TAG_ID_MSG),
2548 (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg));
2549
2550 currSCCB->Sccb_scsistat = SELECT_ST;
2551
2552 WR_HARPOON(port + hp_autostart_3,
2553 (SELECT + SELCHK_STRT));
2554 }
2555
2556 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2557
2558 cdb_reg = port + CMD_STRT;
2559
2560 for (i = 0; i < currSCCB->CdbLength; i++) {
2561 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2562 cdb_reg += 2;
2563 theCCB++;
2564 }
2565
2566 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2567 WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
2568
2569 }
2570 /* auto_loaded */
2571 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2572 WR_HARPOON(port + hp_xferstat, 0x00);
2573
2574 WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2575
2576 WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT));
2577
2578 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) {
2579 WR_HARPOON(port + hp_scsictrl_0,
2580 (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2581 } else {
2582
2583/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2584 auto_loaded |= AUTO_IMMED; */
2585 auto_loaded = AUTO_IMMED;
2586
2587 DISABLE_AUTO(port);
2588
2589 WR_HARPOON(port + hp_autostart_3, auto_loaded);
2590 }
2591
2592 SGRAM_ACCESS(port);
2593}
2594
2595/*---------------------------------------------------------------------
2596 *
2597 * Function: FPT_sres
2598 *
2599 * Description: Hookup the correct CCB and handle the incoming messages.
2600 *
2601 *---------------------------------------------------------------------*/
2602
2603static void FPT_sres(u32 port, unsigned char p_card,
2604 struct sccb_card *pCurrCard)
2605{
2606
2607 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2608
2609 struct sccb_mgr_tar_info *currTar_Info;
2610 struct sccb *currSCCB;
2611
2612 if (pCurrCard->currentSCCB != NULL) {
2613 currTar_Info =
2614 &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2615 DISABLE_AUTO(port);
2616
2617 WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL));
2618
2619 currSCCB = pCurrCard->currentSCCB;
2620 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
2621 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2622 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2623 }
2624 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2625 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2626 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2627 }
2628 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2629 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2630 TAG_Q_TRYING))) {
2631 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2632 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2633 pCurrCard->discQCount--;
2634 pCurrCard->discQ_Tbl[currTar_Info->
2635 LunDiscQ_Idx[currSCCB->
2636 Lun]]
2637 = NULL;
2638 }
2639 } else {
2640 currTar_Info->TarLUNBusy[0] = 0;
2641 if (currSCCB->Sccb_tag) {
2642 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2643 pCurrCard->discQCount--;
2644 pCurrCard->discQ_Tbl[currSCCB->
2645 Sccb_tag] = NULL;
2646 }
2647 } else {
2648 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2649 pCurrCard->discQCount--;
2650 pCurrCard->discQ_Tbl[currTar_Info->
2651 LunDiscQ_Idx[0]] =
2652 NULL;
2653 }
2654 }
2655 }
2656
2657 FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
2658 }
2659
2660 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2661
2662 our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4);
2663 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2664
2665 msgRetryCount = 0;
2666 do {
2667
2668 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2669 tag = 0;
2670
2671 while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2672 if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2673
2674 WRW_HARPOON((port + hp_intstat), PHASE);
2675 return;
2676 }
2677 }
2678
2679 WRW_HARPOON((port + hp_intstat), PHASE);
2680 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) {
2681
2682 message = FPT_sfm(port, pCurrCard->currentSCCB);
2683 if (message) {
2684
2685 if (message <= (0x80 | LUN_MASK)) {
2686 lun = message & (unsigned char)LUN_MASK;
2687
2688 if ((currTar_Info->
2689 TarStatus & TAR_TAG_Q_MASK) ==
2690 TAG_Q_TRYING) {
2691 if (currTar_Info->TarTagQ_Cnt !=
2692 0) {
2693
2694 if (!
2695 (currTar_Info->
2696 TarLUN_CA)) {
2697 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2698
2699 message =
2700 FPT_sfm
2701 (port,
2702 pCurrCard->
2703 currentSCCB);
2704 if (message) {
2705 ACCEPT_MSG
2706 (port);
2707 }
2708
2709 else
2710 message
2711 = 0;
2712
2713 if (message !=
2714 0) {
2715 tag =
2716 FPT_sfm
2717 (port,
2718 pCurrCard->
2719 currentSCCB);
2720
2721 if (!
2722 (tag))
2723 message
2724 =
2725 0;
2726 }
2727
2728 }
2729 /*C.A. exists! */
2730 }
2731 /*End Q cnt != 0 */
2732 }
2733 /*End Tag cmds supported! */
2734 }
2735 /*End valid ID message. */
2736 else {
2737
2738 ACCEPT_MSG_ATN(port);
2739 }
2740
2741 }
2742 /* End good id message. */
2743 else {
2744
2745 message = 0;
2746 }
2747 } else {
2748 ACCEPT_MSG_ATN(port);
2749
2750 while (!
2751 (RDW_HARPOON((port + hp_intstat)) &
2752 (PHASE | RESET))
2753 && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
2754 && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2755
2756 return;
2757 }
2758
2759 if (message == 0) {
2760 msgRetryCount++;
2761 if (msgRetryCount == 1) {
2762 FPT_SendMsg(port, SMPARITY);
2763 } else {
2764 FPT_SendMsg(port, SMDEV_RESET);
2765
2766 FPT_sssyncv(port, our_target, NARROW_SCSI,
2767 currTar_Info);
2768
2769 if (FPT_sccbMgrTbl[p_card][our_target].
2770 TarEEValue & EE_SYNC_MASK) {
2771
2772 FPT_sccbMgrTbl[p_card][our_target].
2773 TarStatus &= ~TAR_SYNC_MASK;
2774
2775 }
2776
2777 if (FPT_sccbMgrTbl[p_card][our_target].
2778 TarEEValue & EE_WIDE_SCSI) {
2779
2780 FPT_sccbMgrTbl[p_card][our_target].
2781 TarStatus &= ~TAR_WIDE_MASK;
2782 }
2783
2784 FPT_queueFlushTargSccb(p_card, our_target,
2785 SCCB_COMPLETE);
2786 FPT_SccbMgrTableInitTarget(p_card, our_target);
2787 return;
2788 }
2789 }
2790 } while (message == 0);
2791
2792 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2793 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
2794 currTar_Info->TarLUNBusy[lun] = 1;
2795 pCurrCard->currentSCCB =
2796 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
2797 if (pCurrCard->currentSCCB != NULL) {
2798 ACCEPT_MSG(port);
2799 } else {
2800 ACCEPT_MSG_ATN(port);
2801 }
2802 } else {
2803 currTar_Info->TarLUNBusy[0] = 1;
2804
2805 if (tag) {
2806 if (pCurrCard->discQ_Tbl[tag] != NULL) {
2807 pCurrCard->currentSCCB =
2808 pCurrCard->discQ_Tbl[tag];
2809 currTar_Info->TarTagQ_Cnt--;
2810 ACCEPT_MSG(port);
2811 } else {
2812 ACCEPT_MSG_ATN(port);
2813 }
2814 } else {
2815 pCurrCard->currentSCCB =
2816 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
2817 if (pCurrCard->currentSCCB != NULL) {
2818 ACCEPT_MSG(port);
2819 } else {
2820 ACCEPT_MSG_ATN(port);
2821 }
2822 }
2823 }
2824
2825 if (pCurrCard->currentSCCB != NULL) {
2826 if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) {
2827 /* During Abort Tag command, the target could have got re-selected
2828 and completed the command. Check the select Q and remove the CCB
2829 if it is in the Select Q */
2830 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
2831 }
2832 }
2833
2834 while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) &&
2835 !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) &&
2836 (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2837}
2838
2839static void FPT_SendMsg(u32 port, unsigned char message)
2840{
2841 while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2842 if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2843
2844 WRW_HARPOON((port + hp_intstat), PHASE);
2845 return;
2846 }
2847 }
2848
2849 WRW_HARPOON((port + hp_intstat), PHASE);
2850 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) {
2851 WRW_HARPOON((port + hp_intstat),
2852 (BUS_FREE | PHASE | XFER_CNT_0));
2853
2854 WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
2855
2856 WR_HARPOON(port + hp_scsidata_0, message);
2857
2858 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2859
2860 ACCEPT_MSG(port);
2861
2862 WR_HARPOON(port + hp_portctrl_0, 0x00);
2863
2864 if ((message == SMABORT) || (message == SMDEV_RESET) ||
2865 (message == SMABORT_TAG)) {
2866 while (!
2867 (RDW_HARPOON((port + hp_intstat)) &
2868 (BUS_FREE | PHASE))) {
2869 }
2870
2871 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2872 WRW_HARPOON((port + hp_intstat), BUS_FREE);
2873 }
2874 }
2875 }
2876}
2877
2878/*---------------------------------------------------------------------
2879 *
2880 * Function: FPT_sdecm
2881 *
2882 * Description: Determine the proper response to the message from the
2883 * target device.
2884 *
2885 *---------------------------------------------------------------------*/
2886static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
2887{
2888 struct sccb *currSCCB;
2889 struct sccb_card *CurrCard;
2890 struct sccb_mgr_tar_info *currTar_Info;
2891
2892 CurrCard = &FPT_BL_Card[p_card];
2893 currSCCB = CurrCard->currentSCCB;
2894
2895 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
2896
2897 if (message == SMREST_DATA_PTR) {
2898 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) {
2899 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
2900
2901 FPT_hostDataXferRestart(currSCCB);
2902 }
2903
2904 ACCEPT_MSG(port);
2905 WR_HARPOON(port + hp_autostart_1,
2906 (AUTO_IMMED + DISCONNECT_START));
2907 }
2908
2909 else if (message == SMCMD_COMP) {
2910
2911 if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
2912 currTar_Info->TarStatus &=
2913 ~(unsigned char)TAR_TAG_Q_MASK;
2914 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
2915 }
2916
2917 ACCEPT_MSG(port);
2918
2919 }
2920
2921 else if ((message == SMNO_OP) || (message >= SMIDENT)
2922 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY)) {
2923
2924 ACCEPT_MSG(port);
2925 WR_HARPOON(port + hp_autostart_1,
2926 (AUTO_IMMED + DISCONNECT_START));
2927 }
2928
2929 else if (message == SMREJECT) {
2930
2931 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
2932 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
2933 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)
2934 || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) ==
2935 TAG_Q_TRYING))
2936 {
2937 WRW_HARPOON((port + hp_intstat), BUS_FREE);
2938
2939 ACCEPT_MSG(port);
2940
2941 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2942 (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
2943 {
2944 }
2945
2946 if (currSCCB->Lun == 0x00) {
2947 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2948
2949 currTar_Info->TarStatus |=
2950 (unsigned char)SYNC_SUPPORTED;
2951
2952 currTar_Info->TarEEValue &=
2953 ~EE_SYNC_MASK;
2954 }
2955
2956 else if (currSCCB->Sccb_scsistat ==
2957 SELECT_WN_ST) {
2958
2959 currTar_Info->TarStatus =
2960 (currTar_Info->
2961 TarStatus & ~WIDE_ENABLED) |
2962 WIDE_NEGOCIATED;
2963
2964 currTar_Info->TarEEValue &=
2965 ~EE_WIDE_SCSI;
2966
2967 }
2968
2969 else if ((currTar_Info->
2970 TarStatus & TAR_TAG_Q_MASK) ==
2971 TAG_Q_TRYING) {
2972 currTar_Info->TarStatus =
2973 (currTar_Info->
2974 TarStatus & ~(unsigned char)
2975 TAR_TAG_Q_MASK) | TAG_Q_REJECT;
2976
2977 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2978 CurrCard->discQCount--;
2979 CurrCard->discQ_Tbl[currSCCB->
2980 Sccb_tag] = NULL;
2981 currSCCB->Sccb_tag = 0x00;
2982
2983 }
2984 }
2985
2986 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2987
2988 if (currSCCB->Lun == 0x00) {
2989 WRW_HARPOON((port + hp_intstat),
2990 BUS_FREE);
2991 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
2992 }
2993 }
2994
2995 else {
2996
2997 if ((CurrCard->globalFlags & F_CONLUN_IO) &&
2998 ((currTar_Info->
2999 TarStatus & TAR_TAG_Q_MASK) !=
3000 TAG_Q_TRYING))
3001 currTar_Info->TarLUNBusy[currSCCB->
3002 Lun] = 1;
3003 else
3004 currTar_Info->TarLUNBusy[0] = 1;
3005
3006 currSCCB->ControlByte &=
3007 ~(unsigned char)F_USE_CMD_Q;
3008
3009 WR_HARPOON(port + hp_autostart_1,
3010 (AUTO_IMMED + DISCONNECT_START));
3011
3012 }
3013 }
3014
3015 else {
3016 ACCEPT_MSG(port);
3017
3018 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
3019 (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
3020 {
3021 }
3022
3023 if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) {
3024 WR_HARPOON(port + hp_autostart_1,
3025 (AUTO_IMMED + DISCONNECT_START));
3026 }
3027 }
3028 }
3029
3030 else if (message == SMEXT) {
3031
3032 ACCEPT_MSG(port);
3033 FPT_shandem(port, p_card, currSCCB);
3034 }
3035
3036 else if (message == SMIGNORWR) {
3037
3038 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3039
3040 message = FPT_sfm(port, currSCCB);
3041
3042 if (currSCCB->Sccb_scsimsg != SMPARITY)
3043 ACCEPT_MSG(port);
3044 WR_HARPOON(port + hp_autostart_1,
3045 (AUTO_IMMED + DISCONNECT_START));
3046 }
3047
3048 else {
3049
3050 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3051 currSCCB->Sccb_scsimsg = SMREJECT;
3052
3053 ACCEPT_MSG_ATN(port);
3054 WR_HARPOON(port + hp_autostart_1,
3055 (AUTO_IMMED + DISCONNECT_START));
3056 }
3057}
3058
3059/*---------------------------------------------------------------------
3060 *
3061 * Function: FPT_shandem
3062 *
3063 * Description: Decide what to do with the extended message.
3064 *
3065 *---------------------------------------------------------------------*/
3066static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
3067{
3068 unsigned char length, message;
3069
3070 length = FPT_sfm(port, pCurrSCCB);
3071 if (length) {
3072
3073 ACCEPT_MSG(port);
3074 message = FPT_sfm(port, pCurrSCCB);
3075 if (message) {
3076
3077 if (message == SMSYNC) {
3078
3079 if (length == 0x03) {
3080
3081 ACCEPT_MSG(port);
3082 FPT_stsyncn(port, p_card);
3083 } else {
3084
3085 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3086 ACCEPT_MSG_ATN(port);
3087 }
3088 } else if (message == SMWDTR) {
3089
3090 if (length == 0x02) {
3091
3092 ACCEPT_MSG(port);
3093 FPT_stwidn(port, p_card);
3094 } else {
3095
3096 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3097 ACCEPT_MSG_ATN(port);
3098
3099 WR_HARPOON(port + hp_autostart_1,
3100 (AUTO_IMMED +
3101 DISCONNECT_START));
3102 }
3103 } else {
3104
3105 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3106 ACCEPT_MSG_ATN(port);
3107
3108 WR_HARPOON(port + hp_autostart_1,
3109 (AUTO_IMMED + DISCONNECT_START));
3110 }
3111 } else {
3112 if (pCurrSCCB->Sccb_scsimsg != SMPARITY)
3113 ACCEPT_MSG(port);
3114 WR_HARPOON(port + hp_autostart_1,
3115 (AUTO_IMMED + DISCONNECT_START));
3116 }
3117 } else {
3118 if (pCurrSCCB->Sccb_scsimsg == SMPARITY)
3119 WR_HARPOON(port + hp_autostart_1,
3120 (AUTO_IMMED + DISCONNECT_START));
3121 }
3122}
3123
3124/*---------------------------------------------------------------------
3125 *
3126 * Function: FPT_sisyncn
3127 *
3128 * Description: Read in a message byte from the SCSI bus, and check
3129 * for a parity error.
3130 *
3131 *---------------------------------------------------------------------*/
3132
3133static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
3134 unsigned char syncFlag)
3135{
3136 struct sccb *currSCCB;
3137 struct sccb_mgr_tar_info *currTar_Info;
3138
3139 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3140 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3141
3142 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3143
3144 WRW_HARPOON((port + ID_MSG_STRT),
3145 (MPM_OP + AMSG_OUT +
3146 (currSCCB->
3147 Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3148
3149 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3150
3151 WRW_HARPOON((port + SYNC_MSGS + 0),
3152 (MPM_OP + AMSG_OUT + SMEXT));
3153 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3154 WRW_HARPOON((port + SYNC_MSGS + 4),
3155 (MPM_OP + AMSG_OUT + SMSYNC));
3156
3157 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3158
3159 WRW_HARPOON((port + SYNC_MSGS + 6),
3160 (MPM_OP + AMSG_OUT + 12));
3161
3162 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3163 EE_SYNC_10MB)
3164
3165 WRW_HARPOON((port + SYNC_MSGS + 6),
3166 (MPM_OP + AMSG_OUT + 25));
3167
3168 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3169 EE_SYNC_5MB)
3170
3171 WRW_HARPOON((port + SYNC_MSGS + 6),
3172 (MPM_OP + AMSG_OUT + 50));
3173
3174 else
3175 WRW_HARPOON((port + SYNC_MSGS + 6),
3176 (MPM_OP + AMSG_OUT + 00));
3177
3178 WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3179 WRW_HARPOON((port + SYNC_MSGS + 10),
3180 (MPM_OP + AMSG_OUT + DEFAULT_OFFSET));
3181 WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3182
3183 if (syncFlag == 0) {
3184 WR_HARPOON(port + hp_autostart_3,
3185 (SELECT + SELCHK_STRT));
3186 currTar_Info->TarStatus =
3187 ((currTar_Info->
3188 TarStatus & ~(unsigned char)TAR_SYNC_MASK) |
3189 (unsigned char)SYNC_TRYING);
3190 } else {
3191 WR_HARPOON(port + hp_autostart_3,
3192 (AUTO_IMMED + CMD_ONLY_STRT));
3193 }
3194
3195 return 1;
3196 }
3197
3198 else {
3199
3200 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3201 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3202 return 0;
3203 }
3204}
3205
3206/*---------------------------------------------------------------------
3207 *
3208 * Function: FPT_stsyncn
3209 *
3210 * Description: The has sent us a Sync Nego message so handle it as
3211 * necessary.
3212 *
3213 *---------------------------------------------------------------------*/
3214static void FPT_stsyncn(u32 port, unsigned char p_card)
3215{
3216 unsigned char sync_msg, offset, sync_reg, our_sync_msg;
3217 struct sccb *currSCCB;
3218 struct sccb_mgr_tar_info *currTar_Info;
3219
3220 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3221 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3222
3223 sync_msg = FPT_sfm(port, currSCCB);
3224
3225 if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3226 WR_HARPOON(port + hp_autostart_1,
3227 (AUTO_IMMED + DISCONNECT_START));
3228 return;
3229 }
3230
3231 ACCEPT_MSG(port);
3232
3233 offset = FPT_sfm(port, currSCCB);
3234
3235 if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3236 WR_HARPOON(port + hp_autostart_1,
3237 (AUTO_IMMED + DISCONNECT_START));
3238 return;
3239 }
3240
3241 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3242
3243 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3244
3245 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3246
3247 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3248
3249 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3250
3251 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3252 else
3253
3254 our_sync_msg = 0; /* Message = Async */
3255
3256 if (sync_msg < our_sync_msg) {
3257 sync_msg = our_sync_msg; /*if faster, then set to max. */
3258 }
3259
3260 if (offset == ASYNC)
3261 sync_msg = ASYNC;
3262
3263 if (offset > MAX_OFFSET)
3264 offset = MAX_OFFSET;
3265
3266 sync_reg = 0x00;
3267
3268 if (sync_msg > 12)
3269
3270 sync_reg = 0x20; /* Use 10MB/s */
3271
3272 if (sync_msg > 25)
3273
3274 sync_reg = 0x40; /* Use 6.6MB/s */
3275
3276 if (sync_msg > 38)
3277
3278 sync_reg = 0x60; /* Use 5MB/s */
3279
3280 if (sync_msg > 50)
3281
3282 sync_reg = 0x80; /* Use 4MB/s */
3283
3284 if (sync_msg > 62)
3285
3286 sync_reg = 0xA0; /* Use 3.33MB/s */
3287
3288 if (sync_msg > 75)
3289
3290 sync_reg = 0xC0; /* Use 2.85MB/s */
3291
3292 if (sync_msg > 87)
3293
3294 sync_reg = 0xE0; /* Use 2.5MB/s */
3295
3296 if (sync_msg > 100) {
3297
3298 sync_reg = 0x00; /* Use ASYNC */
3299 offset = 0x00;
3300 }
3301
3302 if (currTar_Info->TarStatus & WIDE_ENABLED)
3303
3304 sync_reg |= offset;
3305
3306 else
3307
3308 sync_reg |= (offset | NARROW_SCSI);
3309
3310 FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info);
3311
3312 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3313
3314 ACCEPT_MSG(port);
3315
3316 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3317 ~(unsigned char)TAR_SYNC_MASK) |
3318 (unsigned char)SYNC_SUPPORTED);
3319
3320 WR_HARPOON(port + hp_autostart_1,
3321 (AUTO_IMMED + DISCONNECT_START));
3322 }
3323
3324 else {
3325
3326 ACCEPT_MSG_ATN(port);
3327
3328 FPT_sisyncr(port, sync_msg, offset);
3329
3330 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3331 ~(unsigned char)TAR_SYNC_MASK) |
3332 (unsigned char)SYNC_SUPPORTED);
3333 }
3334}
3335
3336/*---------------------------------------------------------------------
3337 *
3338 * Function: FPT_sisyncr
3339 *
3340 * Description: Answer the targets sync message.
3341 *
3342 *---------------------------------------------------------------------*/
3343static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
3344 unsigned char offset)
3345{
3346 ARAM_ACCESS(port);
3347 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
3348 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3349 WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMSYNC));
3350 WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse));
3351 WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3352 WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset));
3353 WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3354 SGRAM_ACCESS(port);
3355
3356 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3357 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3358
3359 WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3360
3361 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3362 }
3363}
3364
3365/*---------------------------------------------------------------------
3366 *
3367 * Function: FPT_siwidn
3368 *
3369 * Description: Read in a message byte from the SCSI bus, and check
3370 * for a parity error.
3371 *
3372 *---------------------------------------------------------------------*/
3373
3374static unsigned char FPT_siwidn(u32 port, unsigned char p_card)
3375{
3376 struct sccb *currSCCB;
3377 struct sccb_mgr_tar_info *currTar_Info;
3378
3379 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3380 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3381
3382 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3383
3384 WRW_HARPOON((port + ID_MSG_STRT),
3385 (MPM_OP + AMSG_OUT +
3386 (currSCCB->
3387 Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3388
3389 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3390
3391 WRW_HARPOON((port + SYNC_MSGS + 0),
3392 (MPM_OP + AMSG_OUT + SMEXT));
3393 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3394 WRW_HARPOON((port + SYNC_MSGS + 4),
3395 (MPM_OP + AMSG_OUT + SMWDTR));
3396 WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3397 WRW_HARPOON((port + SYNC_MSGS + 8),
3398 (MPM_OP + AMSG_OUT + SM16BIT));
3399 WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3400
3401 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
3402
3403 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3404 ~(unsigned char)TAR_WIDE_MASK) |
3405 (unsigned char)WIDE_ENABLED);
3406
3407 return 1;
3408 }
3409
3410 else {
3411
3412 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3413 ~(unsigned char)TAR_WIDE_MASK) |
3414 WIDE_NEGOCIATED);
3415
3416 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3417 return 0;
3418 }
3419}
3420
3421/*---------------------------------------------------------------------
3422 *
3423 * Function: FPT_stwidn
3424 *
3425 * Description: The has sent us a Wide Nego message so handle it as
3426 * necessary.
3427 *
3428 *---------------------------------------------------------------------*/
3429static void FPT_stwidn(u32 port, unsigned char p_card)
3430{
3431 unsigned char width;
3432 struct sccb *currSCCB;
3433 struct sccb_mgr_tar_info *currTar_Info;
3434
3435 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3436 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3437
3438 width = FPT_sfm(port, currSCCB);
3439
3440 if ((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3441 WR_HARPOON(port + hp_autostart_1,
3442 (AUTO_IMMED + DISCONNECT_START));
3443 return;
3444 }
3445
3446 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3447 width = 0;
3448
3449 if (width) {
3450 currTar_Info->TarStatus |= WIDE_ENABLED;
3451 width = 0;
3452 } else {
3453 width = NARROW_SCSI;
3454 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3455 }
3456
3457 FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info);
3458
3459 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
3460
3461 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3462
3463 if (!
3464 ((currTar_Info->TarStatus & TAR_SYNC_MASK) ==
3465 SYNC_SUPPORTED)) {
3466 ACCEPT_MSG_ATN(port);
3467 ARAM_ACCESS(port);
3468 FPT_sisyncn(port, p_card, 1);
3469 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3470 SGRAM_ACCESS(port);
3471 } else {
3472 ACCEPT_MSG(port);
3473 WR_HARPOON(port + hp_autostart_1,
3474 (AUTO_IMMED + DISCONNECT_START));
3475 }
3476 }
3477
3478 else {
3479
3480 ACCEPT_MSG_ATN(port);
3481
3482 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3483 width = SM16BIT;
3484 else
3485 width = SM8BIT;
3486
3487 FPT_siwidr(port, width);
3488
3489 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3490 }
3491}
3492
3493/*---------------------------------------------------------------------
3494 *
3495 * Function: FPT_siwidr
3496 *
3497 * Description: Answer the targets Wide nego message.
3498 *
3499 *---------------------------------------------------------------------*/
3500static void FPT_siwidr(u32 port, unsigned char width)
3501{
3502 ARAM_ACCESS(port);
3503 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
3504 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3505 WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMWDTR));
3506 WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3507 WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width));
3508 WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3509 SGRAM_ACCESS(port);
3510
3511 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3512 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3513
3514 WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3515
3516 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3517 }
3518}
3519
3520/*---------------------------------------------------------------------
3521 *
3522 * Function: FPT_sssyncv
3523 *
3524 * Description: Write the desired value to the Sync Register for the
3525 * ID specified.
3526 *
3527 *---------------------------------------------------------------------*/
3528static void FPT_sssyncv(u32 p_port, unsigned char p_id,
3529 unsigned char p_sync_value,
3530 struct sccb_mgr_tar_info *currTar_Info)
3531{
3532 unsigned char index;
3533
3534 index = p_id;
3535
3536 switch (index) {
3537
3538 case 0:
3539 index = 12; /* hp_synctarg_0 */
3540 break;
3541 case 1:
3542 index = 13; /* hp_synctarg_1 */
3543 break;
3544 case 2:
3545 index = 14; /* hp_synctarg_2 */
3546 break;
3547 case 3:
3548 index = 15; /* hp_synctarg_3 */
3549 break;
3550 case 4:
3551 index = 8; /* hp_synctarg_4 */
3552 break;
3553 case 5:
3554 index = 9; /* hp_synctarg_5 */
3555 break;
3556 case 6:
3557 index = 10; /* hp_synctarg_6 */
3558 break;
3559 case 7:
3560 index = 11; /* hp_synctarg_7 */
3561 break;
3562 case 8:
3563 index = 4; /* hp_synctarg_8 */
3564 break;
3565 case 9:
3566 index = 5; /* hp_synctarg_9 */
3567 break;
3568 case 10:
3569 index = 6; /* hp_synctarg_10 */
3570 break;
3571 case 11:
3572 index = 7; /* hp_synctarg_11 */
3573 break;
3574 case 12:
3575 index = 0; /* hp_synctarg_12 */
3576 break;
3577 case 13:
3578 index = 1; /* hp_synctarg_13 */
3579 break;
3580 case 14:
3581 index = 2; /* hp_synctarg_14 */
3582 break;
3583 case 15:
3584 index = 3; /* hp_synctarg_15 */
3585
3586 }
3587
3588 WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value);
3589
3590 currTar_Info->TarSyncCtrl = p_sync_value;
3591}
3592
3593/*---------------------------------------------------------------------
3594 *
3595 * Function: FPT_sresb
3596 *
3597 * Description: Reset the desired card's SCSI bus.
3598 *
3599 *---------------------------------------------------------------------*/
3600static void FPT_sresb(u32 port, unsigned char p_card)
3601{
3602 unsigned char scsiID, i;
3603
3604 struct sccb_mgr_tar_info *currTar_Info;
3605
3606 WR_HARPOON(port + hp_page_ctrl,
3607 (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE));
3608 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3609
3610 WR_HARPOON(port + hp_scsictrl_0, SCSI_RST);
3611
3612 scsiID = RD_HARPOON(port + hp_seltimeout);
3613 WR_HARPOON(port + hp_seltimeout, TO_5ms);
3614 WRW_HARPOON((port + hp_intstat), TIMEOUT);
3615
3616 WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO));
3617
3618 while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) {
3619 }
3620
3621 WR_HARPOON(port + hp_seltimeout, scsiID);
3622
3623 WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
3624
3625 FPT_Wait(port, TO_5ms);
3626
3627 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3628
3629 WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00));
3630
3631 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
3632 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3633
3634 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
3635 currTar_Info->TarSyncCtrl = 0;
3636 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3637 }
3638
3639 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
3640 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3641 }
3642
3643 FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
3644
3645 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3646 }
3647
3648 FPT_BL_Card[p_card].scanIndex = 0x00;
3649 FPT_BL_Card[p_card].currentSCCB = NULL;
3650 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3651 | F_NEW_SCCB_CMD);
3652 FPT_BL_Card[p_card].cmdCounter = 0x00;
3653 FPT_BL_Card[p_card].discQCount = 0x00;
3654 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3655
3656 for (i = 0; i < QUEUE_DEPTH; i++)
3657 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3658
3659 WR_HARPOON(port + hp_page_ctrl,
3660 (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE));
3661
3662}
3663
3664/*---------------------------------------------------------------------
3665 *
3666 * Function: FPT_ssenss
3667 *
3668 * Description: Setup for the Auto Sense command.
3669 *
3670 *---------------------------------------------------------------------*/
3671static void FPT_ssenss(struct sccb_card *pCurrCard)
3672{
3673 unsigned char i;
3674 struct sccb *currSCCB;
3675
3676 currSCCB = pCurrCard->currentSCCB;
3677
3678 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3679
3680 for (i = 0; i < 6; i++) {
3681
3682 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3683 }
3684
3685 currSCCB->CdbLength = SIX_BYTE_CMD;
3686 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3687 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3688 currSCCB->Cdb[2] = 0x00;
3689 currSCCB->Cdb[3] = 0x00;
3690 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3691 currSCCB->Cdb[5] = 0x00;
3692
3693 currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength;
3694
3695 currSCCB->Sccb_ATC = 0x00;
3696
3697 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3698
3699 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3700
3701 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3702
3703 currSCCB->ControlByte = 0x00;
3704
3705 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3706}
3707
3708/*---------------------------------------------------------------------
3709 *
3710 * Function: FPT_sxfrp
3711 *
3712 * Description: Transfer data into the bit bucket until the device
3713 * decides to switch phase.
3714 *
3715 *---------------------------------------------------------------------*/
3716
3717static void FPT_sxfrp(u32 p_port, unsigned char p_card)
3718{
3719 unsigned char curr_phz;
3720
3721 DISABLE_AUTO(p_port);
3722
3723 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3724
3725 FPT_hostDataXferAbort(p_port, p_card,
3726 FPT_BL_Card[p_card].currentSCCB);
3727
3728 }
3729
3730 /* If the Automation handled the end of the transfer then do not
3731 match the phase or we will get out of sync with the ISR. */
3732
3733 if (RDW_HARPOON((p_port + hp_intstat)) &
3734 (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3735 return;
3736
3737 WR_HARPOON(p_port + hp_xfercnt_0, 0x00);
3738
3739 curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3740
3741 WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0);
3742
3743 WR_HARPOON(p_port + hp_scsisig, curr_phz);
3744
3745 while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) &&
3746 (curr_phz ==
3747 (RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ)))
3748 {
3749 if (curr_phz & (unsigned char)SCSI_IOBIT) {
3750 WR_HARPOON(p_port + hp_portctrl_0,
3751 (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3752
3753 if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3754 RD_HARPOON(p_port + hp_fifodata_0);
3755 }
3756 } else {
3757 WR_HARPOON(p_port + hp_portctrl_0,
3758 (SCSI_PORT | HOST_PORT | HOST_WRT));
3759 if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) {
3760 WR_HARPOON(p_port + hp_fifodata_0, 0xFA);
3761 }
3762 }
3763 } /* End of While loop for padding data I/O phase */
3764
3765 while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3766 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ)
3767 break;
3768 }
3769
3770 WR_HARPOON(p_port + hp_portctrl_0,
3771 (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3772 while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3773 RD_HARPOON(p_port + hp_fifodata_0);
3774 }
3775
3776 if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3777 WR_HARPOON(p_port + hp_autostart_0,
3778 (AUTO_IMMED + DISCONNECT_START));
3779 while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) {
3780 }
3781
3782 if (RDW_HARPOON((p_port + hp_intstat)) &
3783 (ICMD_COMP | ITAR_DISC))
3784 while (!
3785 (RDW_HARPOON((p_port + hp_intstat)) &
3786 (BUS_FREE | RSEL))) ;
3787 }
3788}
3789
3790/*---------------------------------------------------------------------
3791 *
3792 * Function: FPT_schkdd
3793 *
3794 * Description: Make sure data has been flushed from both FIFOs and abort
3795 * the operations if necessary.
3796 *
3797 *---------------------------------------------------------------------*/
3798
3799static void FPT_schkdd(u32 port, unsigned char p_card)
3800{
3801 unsigned short TimeOutLoop;
3802 unsigned char sPhase;
3803
3804 struct sccb *currSCCB;
3805
3806 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3807
3808 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
3809 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
3810 return;
3811 }
3812
3813 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) {
3814
3815 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1);
3816
3817 currSCCB->Sccb_XferCnt = 1;
3818
3819 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
3820 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
3821 WR_HARPOON(port + hp_xferstat, 0x00);
3822 }
3823
3824 else {
3825
3826 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
3827
3828 currSCCB->Sccb_XferCnt = 0;
3829 }
3830
3831 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
3832 (currSCCB->HostStatus == SCCB_COMPLETE)) {
3833
3834 currSCCB->HostStatus = SCCB_PARITY_ERR;
3835 WRW_HARPOON((port + hp_intstat), PARITY);
3836 }
3837
3838 FPT_hostDataXferAbort(port, p_card, currSCCB);
3839
3840 while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) {
3841 }
3842
3843 TimeOutLoop = 0;
3844
3845 while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) {
3846 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
3847 return;
3848 }
3849 if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) {
3850 break;
3851 }
3852 if (RDW_HARPOON((port + hp_intstat)) & RESET) {
3853 return;
3854 }
3855 if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
3856 || (TimeOutLoop++ > 0x3000))
3857 break;
3858 }
3859
3860 sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
3861 if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) ||
3862 (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) ||
3863 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
3864 (sPhase == (SCSI_BSY | S_DATAI_PH))) {
3865
3866 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3867
3868 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) {
3869 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
3870 FPT_phaseDataIn(port, p_card);
3871 }
3872
3873 else {
3874 FPT_phaseDataOut(port, p_card);
3875 }
3876 } else {
3877 FPT_sxfrp(port, p_card);
3878 if (!(RDW_HARPOON((port + hp_intstat)) &
3879 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) {
3880 WRW_HARPOON((port + hp_intstat), AUTO_INT);
3881 FPT_phaseDecode(port, p_card);
3882 }
3883 }
3884
3885 }
3886
3887 else {
3888 WR_HARPOON(port + hp_portctrl_0, 0x00);
3889 }
3890}
3891
3892/*---------------------------------------------------------------------
3893 *
3894 * Function: FPT_sinits
3895 *
3896 * Description: Setup SCCB manager fields in this SCCB.
3897 *
3898 *---------------------------------------------------------------------*/
3899
3900static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
3901{
3902 struct sccb_mgr_tar_info *currTar_Info;
3903
3904 if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) {
3905 return;
3906 }
3907 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
3908
3909 p_sccb->Sccb_XferState = 0x00;
3910 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
3911
3912 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
3913 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
3914
3915 p_sccb->Sccb_SGoffset = 0;
3916 p_sccb->Sccb_XferState = F_SG_XFER;
3917 p_sccb->Sccb_XferCnt = 0x00;
3918 }
3919
3920 if (p_sccb->DataLength == 0x00)
3921
3922 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
3923
3924 if (p_sccb->ControlByte & F_USE_CMD_Q) {
3925 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
3926 p_sccb->ControlByte &= ~F_USE_CMD_Q;
3927
3928 else
3929 currTar_Info->TarStatus |= TAG_Q_TRYING;
3930 }
3931
3932/* For !single SCSI device in system & device allow Disconnect
3933 or command is tag_q type then send Cmd with Disconnect Enable
3934 else send Cmd with Disconnect Disable */
3935
3936/*
3937 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
3938 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
3939 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3940*/
3941 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
3942 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3943 p_sccb->Sccb_idmsg =
3944 (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
3945 }
3946
3947 else {
3948
3949 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
3950 }
3951
3952 p_sccb->HostStatus = 0x00;
3953 p_sccb->TargetStatus = 0x00;
3954 p_sccb->Sccb_tag = 0x00;
3955 p_sccb->Sccb_MGRFlags = 0x00;
3956 p_sccb->Sccb_sgseg = 0x00;
3957 p_sccb->Sccb_ATC = 0x00;
3958 p_sccb->Sccb_savedATC = 0x00;
3959/*
3960 p_sccb->SccbVirtDataPtr = 0x00;
3961 p_sccb->Sccb_forwardlink = NULL;
3962 p_sccb->Sccb_backlink = NULL;
3963 */
3964 p_sccb->Sccb_scsistat = BUS_FREE_ST;
3965 p_sccb->SccbStatus = SCCB_IN_PROCESS;
3966 p_sccb->Sccb_scsimsg = SMNO_OP;
3967
3968}
3969
3970/*---------------------------------------------------------------------
3971 *
3972 * Function: Phase Decode
3973 *
3974 * Description: Determine the phase and call the appropriate function.
3975 *
3976 *---------------------------------------------------------------------*/
3977
3978static void FPT_phaseDecode(u32 p_port, unsigned char p_card)
3979{
3980 unsigned char phase_ref;
3981 void (*phase) (u32, unsigned char);
3982
3983 DISABLE_AUTO(p_port);
3984
3985 phase_ref =
3986 (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ);
3987
3988 phase = FPT_s_PhaseTbl[phase_ref];
3989
3990 (*phase) (p_port, p_card); /* Call the correct phase func */
3991}
3992
3993/*---------------------------------------------------------------------
3994 *
3995 * Function: Data Out Phase
3996 *
3997 * Description: Start up both the BusMaster and Xbow.
3998 *
3999 *---------------------------------------------------------------------*/
4000
4001static void FPT_phaseDataOut(u32 port, unsigned char p_card)
4002{
4003
4004 struct sccb *currSCCB;
4005
4006 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4007 if (currSCCB == NULL) {
4008 return; /* Exit if No SCCB record */
4009 }
4010
4011 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4012 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4013
4014 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4015
4016 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4017
4018 WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4019
4020 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4021
4022 if (currSCCB->Sccb_XferCnt == 0) {
4023
4024 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4025 (currSCCB->HostStatus == SCCB_COMPLETE))
4026 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4027
4028 FPT_sxfrp(port, p_card);
4029 if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4030 FPT_phaseDecode(port, p_card);
4031 }
4032}
4033
4034/*---------------------------------------------------------------------
4035 *
4036 * Function: Data In Phase
4037 *
4038 * Description: Startup the BusMaster and the XBOW.
4039 *
4040 *---------------------------------------------------------------------*/
4041
4042static void FPT_phaseDataIn(u32 port, unsigned char p_card)
4043{
4044
4045 struct sccb *currSCCB;
4046
4047 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4048
4049 if (currSCCB == NULL) {
4050 return; /* Exit if No SCCB record */
4051 }
4052
4053 currSCCB->Sccb_scsistat = DATA_IN_ST;
4054 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4055 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4056
4057 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4058
4059 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4060
4061 WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4062
4063 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4064
4065 if (currSCCB->Sccb_XferCnt == 0) {
4066
4067 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4068 (currSCCB->HostStatus == SCCB_COMPLETE))
4069 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4070
4071 FPT_sxfrp(port, p_card);
4072 if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4073 FPT_phaseDecode(port, p_card);
4074
4075 }
4076}
4077
4078/*---------------------------------------------------------------------
4079 *
4080 * Function: Command Phase
4081 *
4082 * Description: Load the CDB into the automation and start it up.
4083 *
4084 *---------------------------------------------------------------------*/
4085
4086static void FPT_phaseCommand(u32 p_port, unsigned char p_card)
4087{
4088 struct sccb *currSCCB;
4089 u32 cdb_reg;
4090 unsigned char i;
4091
4092 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4093
4094 if (currSCCB->OperationCode == RESET_COMMAND) {
4095
4096 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4097 currSCCB->CdbLength = SIX_BYTE_CMD;
4098 }
4099
4100 WR_HARPOON(p_port + hp_scsisig, 0x00);
4101
4102 ARAM_ACCESS(p_port);
4103
4104 cdb_reg = p_port + CMD_STRT;
4105
4106 for (i = 0; i < currSCCB->CdbLength; i++) {
4107
4108 if (currSCCB->OperationCode == RESET_COMMAND)
4109
4110 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4111
4112 else
4113 WRW_HARPOON(cdb_reg,
4114 (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4115 cdb_reg += 2;
4116 }
4117
4118 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4119 WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
4120
4121 WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT));
4122
4123 currSCCB->Sccb_scsistat = COMMAND_ST;
4124
4125 WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4126 SGRAM_ACCESS(p_port);
4127}
4128
4129/*---------------------------------------------------------------------
4130 *
4131 * Function: Status phase
4132 *
4133 * Description: Bring in the status and command complete message bytes
4134 *
4135 *---------------------------------------------------------------------*/
4136
4137static void FPT_phaseStatus(u32 port, unsigned char p_card)
4138{
4139 /* Start-up the automation to finish off this command and let the
4140 isr handle the interrupt for command complete when it comes in.
4141 We could wait here for the interrupt to be generated?
4142 */
4143
4144 WR_HARPOON(port + hp_scsisig, 0x00);
4145
4146 WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START));
4147}
4148
4149/*---------------------------------------------------------------------
4150 *
4151 * Function: Phase Message Out
4152 *
4153 * Description: Send out our message (if we have one) and handle whatever
4154 * else is involed.
4155 *
4156 *---------------------------------------------------------------------*/
4157
4158static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
4159{
4160 unsigned char message, scsiID;
4161 struct sccb *currSCCB;
4162 struct sccb_mgr_tar_info *currTar_Info;
4163
4164 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4165
4166 if (currSCCB != NULL) {
4167
4168 message = currSCCB->Sccb_scsimsg;
4169 scsiID = currSCCB->TargID;
4170
4171 if (message == SMDEV_RESET) {
4172
4173 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4174 currTar_Info->TarSyncCtrl = 0;
4175 FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
4176
4177 if (FPT_sccbMgrTbl[p_card][scsiID].
4178 TarEEValue & EE_SYNC_MASK) {
4179
4180 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4181 ~TAR_SYNC_MASK;
4182
4183 }
4184
4185 if (FPT_sccbMgrTbl[p_card][scsiID].
4186 TarEEValue & EE_WIDE_SCSI) {
4187
4188 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4189 ~TAR_WIDE_MASK;
4190 }
4191
4192 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4193 FPT_SccbMgrTableInitTarget(p_card, scsiID);
4194 } else if (currSCCB->Sccb_scsistat == ABORT_ST) {
4195 currSCCB->HostStatus = SCCB_COMPLETE;
4196 if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] !=
4197 NULL) {
4198 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4199 Sccb_tag] = NULL;
4200 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4201 }
4202
4203 }
4204
4205 else if (currSCCB->Sccb_scsistat < COMMAND_ST) {
4206
4207 if (message == SMNO_OP) {
4208 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4209
4210 FPT_ssel(port, p_card);
4211 return;
4212 }
4213 } else {
4214
4215 if (message == SMABORT)
4216
4217 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4218 }
4219
4220 } else {
4221 message = SMABORT;
4222 }
4223
4224 WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4225
4226 WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
4227
4228 WR_HARPOON(port + hp_scsidata_0, message);
4229
4230 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
4231
4232 ACCEPT_MSG(port);
4233
4234 WR_HARPOON(port + hp_portctrl_0, 0x00);
4235
4236 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4237 (message == SMABORT_TAG)) {
4238
4239 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) {
4240 }
4241
4242 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
4243 WRW_HARPOON((port + hp_intstat), BUS_FREE);
4244
4245 if (currSCCB != NULL) {
4246
4247 if ((FPT_BL_Card[p_card].
4248 globalFlags & F_CONLUN_IO)
4249 &&
4250 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4251 TarStatus & TAR_TAG_Q_MASK) !=
4252 TAG_Q_TRYING))
4253 FPT_sccbMgrTbl[p_card][currSCCB->
4254 TargID].
4255 TarLUNBusy[currSCCB->Lun] = 0;
4256 else
4257 FPT_sccbMgrTbl[p_card][currSCCB->
4258 TargID].
4259 TarLUNBusy[0] = 0;
4260
4261 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
4262 currSCCB, p_card);
4263 }
4264
4265 else {
4266 FPT_BL_Card[p_card].globalFlags |=
4267 F_NEW_SCCB_CMD;
4268 }
4269 }
4270
4271 else {
4272
4273 FPT_sxfrp(port, p_card);
4274 }
4275 }
4276
4277 else {
4278
4279 if (message == SMPARITY) {
4280 currSCCB->Sccb_scsimsg = SMNO_OP;
4281 WR_HARPOON(port + hp_autostart_1,
4282 (AUTO_IMMED + DISCONNECT_START));
4283 } else {
4284 FPT_sxfrp(port, p_card);
4285 }
4286 }
4287}
4288
4289/*---------------------------------------------------------------------
4290 *
4291 * Function: Message In phase
4292 *
4293 * Description: Bring in the message and determine what to do with it.
4294 *
4295 *---------------------------------------------------------------------*/
4296
4297static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
4298{
4299 unsigned char message;
4300 struct sccb *currSCCB;
4301
4302 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4303
4304 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
4305
4306 FPT_phaseChkFifo(port, p_card);
4307 }
4308
4309 message = RD_HARPOON(port + hp_scsidata_0);
4310 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR)) {
4311
4312 WR_HARPOON(port + hp_autostart_1,
4313 (AUTO_IMMED + END_DATA_START));
4314
4315 }
4316
4317 else {
4318
4319 message = FPT_sfm(port, currSCCB);
4320 if (message) {
4321
4322 FPT_sdecm(message, port, p_card);
4323
4324 } else {
4325 if (currSCCB->Sccb_scsimsg != SMPARITY)
4326 ACCEPT_MSG(port);
4327 WR_HARPOON(port + hp_autostart_1,
4328 (AUTO_IMMED + DISCONNECT_START));
4329 }
4330 }
4331
4332}
4333
4334/*---------------------------------------------------------------------
4335 *
4336 * Function: Illegal phase
4337 *
4338 * Description: Target switched to some illegal phase, so all we can do
4339 * is report an error back to the host (if that is possible)
4340 * and send an ABORT message to the misbehaving target.
4341 *
4342 *---------------------------------------------------------------------*/
4343
4344static void FPT_phaseIllegal(u32 port, unsigned char p_card)
4345{
4346 struct sccb *currSCCB;
4347
4348 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4349
4350 WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig));
4351 if (currSCCB != NULL) {
4352
4353 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4354 currSCCB->Sccb_scsistat = ABORT_ST;
4355 currSCCB->Sccb_scsimsg = SMABORT;
4356 }
4357
4358 ACCEPT_MSG_ATN(port);
4359}
4360
4361/*---------------------------------------------------------------------
4362 *
4363 * Function: Phase Check FIFO
4364 *
4365 * Description: Make sure data has been flushed from both FIFOs and abort
4366 * the operations if necessary.
4367 *
4368 *---------------------------------------------------------------------*/
4369
4370static void FPT_phaseChkFifo(u32 port, unsigned char p_card)
4371{
4372 u32 xfercnt;
4373 struct sccb *currSCCB;
4374
4375 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4376
4377 if (currSCCB->Sccb_scsistat == DATA_IN_ST) {
4378
4379 while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) &&
4380 (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) {
4381 }
4382
4383 if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) {
4384 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4385
4386 currSCCB->Sccb_XferCnt = 0;
4387
4388 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4389 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4390 currSCCB->HostStatus = SCCB_PARITY_ERR;
4391 WRW_HARPOON((port + hp_intstat), PARITY);
4392 }
4393
4394 FPT_hostDataXferAbort(port, p_card, currSCCB);
4395
4396 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4397
4398 while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY))
4399 && (RD_HARPOON(port + hp_ext_status) &
4400 BM_CMD_BUSY)) {
4401 }
4402
4403 }
4404 }
4405
4406 /*End Data In specific code. */
4407 GET_XFER_CNT(port, xfercnt);
4408
4409 WR_HARPOON(port + hp_xfercnt_0, 0x00);
4410
4411 WR_HARPOON(port + hp_portctrl_0, 0x00);
4412
4413 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4414
4415 currSCCB->Sccb_XferCnt = xfercnt;
4416
4417 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4418 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4419
4420 currSCCB->HostStatus = SCCB_PARITY_ERR;
4421 WRW_HARPOON((port + hp_intstat), PARITY);
4422 }
4423
4424 FPT_hostDataXferAbort(port, p_card, currSCCB);
4425
4426 WR_HARPOON(port + hp_fifowrite, 0x00);
4427 WR_HARPOON(port + hp_fiforead, 0x00);
4428 WR_HARPOON(port + hp_xferstat, 0x00);
4429
4430 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4431}
4432
4433/*---------------------------------------------------------------------
4434 *
4435 * Function: Phase Bus Free
4436 *
4437 * Description: We just went bus free so figure out if it was
4438 * because of command complete or from a disconnect.
4439 *
4440 *---------------------------------------------------------------------*/
4441static void FPT_phaseBusFree(u32 port, unsigned char p_card)
4442{
4443 struct sccb *currSCCB;
4444
4445 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4446
4447 if (currSCCB != NULL) {
4448
4449 DISABLE_AUTO(port);
4450
4451 if (currSCCB->OperationCode == RESET_COMMAND) {
4452
4453 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4454 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4455 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4456 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4457 TarLUNBusy[currSCCB->Lun] = 0;
4458 else
4459 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4460 TarLUNBusy[0] = 0;
4461
4462 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4463 p_card);
4464
4465 FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card);
4466
4467 }
4468
4469 else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4470 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4471 (unsigned char)SYNC_SUPPORTED;
4472 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4473 ~EE_SYNC_MASK;
4474 }
4475
4476 else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4477 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4478 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4479 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4480
4481 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4482 ~EE_WIDE_SCSI;
4483 }
4484
4485 else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
4486 /* Make sure this is not a phony BUS_FREE. If we were
4487 reselected or if BUSY is NOT on then this is a
4488 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4489
4490 if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ||
4491 (RDW_HARPOON((port + hp_intstat)) & RSEL)) {
4492 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4493 TarStatus &= ~TAR_TAG_Q_MASK;
4494 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4495 TarStatus |= TAG_Q_REJECT;
4496 }
4497
4498 else {
4499 return;
4500 }
4501 }
4502
4503 else {
4504
4505 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4506
4507 if (!currSCCB->HostStatus) {
4508 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4509 }
4510
4511 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4512 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4513 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4514 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4515 TarLUNBusy[currSCCB->Lun] = 0;
4516 else
4517 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4518 TarLUNBusy[0] = 0;
4519
4520 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4521 p_card);
4522 return;
4523 }
4524
4525 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4526
4527 } /*end if !=null */
4528}
4529
4530/*---------------------------------------------------------------------
4531 *
4532 * Function: Auto Load Default Map
4533 *
4534 * Description: Load the Automation RAM with the defualt map values.
4535 *
4536 *---------------------------------------------------------------------*/
4537static void FPT_autoLoadDefaultMap(u32 p_port)
4538{
4539 u32 map_addr;
4540
4541 ARAM_ACCESS(p_port);
4542 map_addr = p_port + hp_aramBase;
4543
4544 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0)); /*ID MESSAGE */
4545 map_addr += 2;
4546 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20)); /*SIMPLE TAG QUEUEING MSG */
4547 map_addr += 2;
4548 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4549 map_addr += 2;
4550 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00)); /*TAG ID MSG */
4551 map_addr += 2;
4552 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 0 */
4553 map_addr += 2;
4554 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 1 */
4555 map_addr += 2;
4556 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 2 */
4557 map_addr += 2;
4558 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 3 */
4559 map_addr += 2;
4560 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 4 */
4561 map_addr += 2;
4562 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 5 */
4563 map_addr += 2;
4564 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 6 */
4565 map_addr += 2;
4566 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 7 */
4567 map_addr += 2;
4568 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 8 */
4569 map_addr += 2;
4570 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 9 */
4571 map_addr += 2;
4572 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 10 */
4573 map_addr += 2;
4574 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 11 */
4575 map_addr += 2;
4576 WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT)); /*JUMP IF DATA OUT */
4577 map_addr += 2;
4578 WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI)); /*JUMP IF NO DATA IN FIFO */
4579 map_addr += 2; /*This means AYNC DATA IN */
4580 WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4581 map_addr += 2;
4582 WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT)); /*JUMP IF NOT DATA IN PHZ */
4583 map_addr += 2;
4584 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4585 map_addr += 2;
4586 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02)); /*SAVE DATA PTR MSG? */
4587 map_addr += 2;
4588 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC)); /*GO CHECK FOR DISCONNECT MSG */
4589 map_addr += 2;
4590 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1)); /*SAVE DATA PTRS MSG */
4591 map_addr += 2;
4592 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK DATA IN */
4593 map_addr += 2;
4594 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04)); /*DISCONNECT MSG? */
4595 map_addr += 2;
4596 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN)); /*UKNKNOWN MSG */
4597 map_addr += 2;
4598 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*XFER DISCONNECT MSG */
4599 map_addr += 2;
4600 WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC)); /*STOP AND INTERRUPT */
4601 map_addr += 2;
4602