Loading...
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 unsigned long si_baseaddr;
33 unsigned char si_present;
34 unsigned char si_intvect;
35 unsigned char si_id;
36 unsigned char si_lun;
37 unsigned short si_fw_revision;
38 unsigned short si_per_targ_init_sync;
39 unsigned short si_per_targ_fast_nego;
40 unsigned short si_per_targ_ultra_nego;
41 unsigned short si_per_targ_no_disc;
42 unsigned short si_per_targ_wide_nego;
43 unsigned short 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 unsigned long si_OS_reserved;
50 unsigned char si_XlatInfo[4];
51 unsigned long si_reserved2[5];
52 unsigned long 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 unsigned long DataLength;
80 unsigned long 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 unsigned long Reserved2;
90 unsigned long SensePointer;
91
92 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
93 unsigned long SccbIOPort; /* Identifies board base port */
94 unsigned char SccbStatus;
95 unsigned char SCCBRes2;
96 unsigned short SccbOSFlags;
97
98 unsigned long Sccb_XferCnt; /* actual transfer count */
99 unsigned long Sccb_ATC;
100 unsigned long SccbVirtDataPtr; /* virtual addr for OS/2 */
101 unsigned long Sccb_res1;
102 unsigned short Sccb_MGRFlags;
103 unsigned short 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 unsigned long Sccb_savedATC;
111 unsigned char Save_Cdb[6];
112 unsigned char Save_CdbLen;
113 unsigned char Sccb_XferState;
114 unsigned long 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 unsigned long niBaseAddr; /* Port Address of card */
229 unsigned char niSysConf; /* Adapter Configuration byte - Byte 16 of eeprom map */
230 unsigned char niScsiConf; /* SCSI Configuration byte - Byte 17 of eeprom map */
231 unsigned char niScamConf; /* SCAM Configuration byte - Byte 20 of eeprom map */
232 unsigned char niAdapId; /* Host Adapter ID - Byte 24 of eerpom map */
233 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte of targets */
234 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name string of Targets */
235};
236
237#define MODEL_LT 1
238#define MODEL_DL 2
239#define MODEL_LW 3
240#define MODEL_DW 4
241
242struct sccb_card {
243 struct sccb *currentSCCB;
244 struct sccb_mgr_info *cardInfo;
245
246 unsigned long ioPort;
247
248 unsigned short cmdCounter;
249 unsigned char discQCount;
250 unsigned char tagQ_Lst;
251 unsigned char cardIndex;
252 unsigned char scanIndex;
253 unsigned char globalFlags;
254 unsigned char ourId;
255 struct nvram_info *pNvRamInfo;
256 struct sccb *discQ_Tbl[QUEUE_DEPTH];
257
258};
259
260#define F_TAG_STARTED 0x01
261#define F_CONLUN_IO 0x02
262#define F_DO_RENEGO 0x04
263#define F_NO_FILTER 0x08
264#define F_GREEN_PC 0x10
265#define F_HOST_XFER_ACT 0x20
266#define F_NEW_SCCB_CMD 0x40
267#define F_UPDATE_EEPROM 0x80
268
269#define ID_STRING_LENGTH 32
270#define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
271
272#define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
273
274#define ASSIGN_ID 0x00
275#define SET_P_FLAG 0x01
276#define CFG_CMPLT 0x03
277#define DOM_MSTR 0x0F
278#define SYNC_PTRN 0x1F
279
280#define ID_0_7 0x18
281#define ID_8_F 0x11
282#define MISC_CODE 0x14
283#define CLR_P_FLAG 0x18
284
285#define INIT_SELTD 0x01
286#define LEVEL2_TAR 0x02
287
288enum scam_id_st { ID0, ID1, ID2, ID3, ID4, ID5, ID6, ID7, ID8, ID9, ID10, ID11,
289 ID12,
290 ID13, ID14, ID15, ID_UNUSED, ID_UNASSIGNED, ID_ASSIGNED, LEGACY,
291 CLR_PRIORITY, NO_ID_AVAIL
292};
293
294typedef struct SCCBscam_info {
295
296 unsigned char id_string[ID_STRING_LENGTH];
297 enum scam_id_st state;
298
299} SCCBSCAM_INFO;
300
301#define SCSI_REQUEST_SENSE 0x03
302#define SCSI_READ 0x08
303#define SCSI_WRITE 0x0A
304#define SCSI_START_STOP_UNIT 0x1B
305#define SCSI_READ_EXTENDED 0x28
306#define SCSI_WRITE_EXTENDED 0x2A
307#define SCSI_WRITE_AND_VERIFY 0x2E
308
309#define SSGOOD 0x00
310#define SSCHECK 0x02
311#define SSQ_FULL 0x28
312
313#define SMCMD_COMP 0x00
314#define SMEXT 0x01
315#define SMSAVE_DATA_PTR 0x02
316#define SMREST_DATA_PTR 0x03
317#define SMDISC 0x04
318#define SMABORT 0x06
319#define SMREJECT 0x07
320#define SMNO_OP 0x08
321#define SMPARITY 0x09
322#define SMDEV_RESET 0x0C
323#define SMABORT_TAG 0x0D
324#define SMINIT_RECOVERY 0x0F
325#define SMREL_RECOVERY 0x10
326
327#define SMIDENT 0x80
328#define DISC_PRIV 0x40
329
330#define SMSYNC 0x01
331#define SMWDTR 0x03
332#define SM8BIT 0x00
333#define SM16BIT 0x01
334#define SMIGNORWR 0x23 /* Ignore Wide Residue */
335
336#define SIX_BYTE_CMD 0x06
337#define TWELVE_BYTE_CMD 0x0C
338
339#define ASYNC 0x00
340#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
341
342#define EEPROM_WD_CNT 256
343
344#define EEPROM_CHECK_SUM 0
345#define FW_SIGNATURE 2
346#define MODEL_NUMB_0 4
347#define MODEL_NUMB_2 6
348#define MODEL_NUMB_4 8
349#define SYSTEM_CONFIG 16
350#define SCSI_CONFIG 17
351#define BIOS_CONFIG 18
352#define SCAM_CONFIG 20
353#define ADAPTER_SCSI_ID 24
354
355#define IGNORE_B_SCAN 32
356#define SEND_START_ENA 34
357#define DEVICE_ENABLE 36
358
359#define SYNC_RATE_TBL 38
360#define SYNC_RATE_TBL01 38
361#define SYNC_RATE_TBL23 40
362#define SYNC_RATE_TBL45 42
363#define SYNC_RATE_TBL67 44
364#define SYNC_RATE_TBL89 46
365#define SYNC_RATE_TBLab 48
366#define SYNC_RATE_TBLcd 50
367#define SYNC_RATE_TBLef 52
368
369#define EE_SCAMBASE 256
370
371#define SCAM_ENABLED BIT(2)
372#define SCAM_LEVEL2 BIT(3)
373
374#define RENEGO_ENA BIT(10)
375#define CONNIO_ENA BIT(11)
376#define GREEN_PC_ENA BIT(12)
377
378#define AUTO_RATE_00 00
379#define AUTO_RATE_05 01
380#define AUTO_RATE_10 02
381#define AUTO_RATE_20 03
382
383#define WIDE_NEGO_BIT BIT(7)
384#define DISC_ENABLE_BIT BIT(6)
385
386#define hp_vendor_id_0 0x00 /* LSB */
387#define ORION_VEND_0 0x4B
388
389#define hp_vendor_id_1 0x01 /* MSB */
390#define ORION_VEND_1 0x10
391
392#define hp_device_id_0 0x02 /* LSB */
393#define ORION_DEV_0 0x30
394
395#define hp_device_id_1 0x03 /* MSB */
396#define ORION_DEV_1 0x81
397
398 /* Sub Vendor ID and Sub Device ID only available in
399 Harpoon Version 2 and higher */
400
401#define hp_sub_device_id_0 0x06 /* LSB */
402
403#define hp_semaphore 0x0C
404#define SCCB_MGR_ACTIVE BIT(0)
405#define TICKLE_ME BIT(1)
406#define SCCB_MGR_PRESENT BIT(3)
407#define BIOS_IN_USE BIT(4)
408
409#define hp_sys_ctrl 0x0F
410
411#define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
412#define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
413#define HALT_MACH BIT(3) /*Halt State Machine */
414#define HARD_ABORT BIT(4) /*Hard Abort */
415
416#define hp_host_blk_cnt 0x13
417
418#define XFER_BLK64 0x06 /* 1 1 0 64 byte per block */
419
420#define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes */
421
422#define hp_int_mask 0x17
423
424#define INT_CMD_COMPL BIT(0) /* DMA command complete */
425#define INT_EXT_STATUS BIT(1) /* Extended Status Set */
426
427#define hp_xfer_cnt_lo 0x18
428#define hp_xfer_cnt_hi 0x1A
429#define hp_xfer_cmd 0x1B
430
431#define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
432#define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
433
434#define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
435
436#define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
437
438#define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
439
440#define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
441#define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
442
443#define hp_host_addr_lo 0x1C
444#define hp_host_addr_hmi 0x1E
445
446#define hp_ee_ctrl 0x22
447
448#define EXT_ARB_ACK BIT(7)
449#define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
450#define SEE_MS BIT(5)
451#define SEE_CS BIT(3)
452#define SEE_CLK BIT(2)
453#define SEE_DO BIT(1)
454#define SEE_DI BIT(0)
455
456#define EE_READ 0x06
457#define EE_WRITE 0x05
458#define EWEN 0x04
459#define EWEN_ADDR 0x03C0
460#define EWDS 0x04
461#define EWDS_ADDR 0x0000
462
463#define hp_bm_ctrl 0x26
464
465#define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
466#define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
467#define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
468#define FAST_SINGLE BIT(6) /*?? */
469
470#define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
471
472#define hp_sg_addr 0x28
473#define hp_page_ctrl 0x29
474
475#define SCATTER_EN BIT(0)
476#define SGRAM_ARAM BIT(1)
477#define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
478#define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
479
480#define hp_pci_stat_cfg 0x2D
481
482#define REC_MASTER_ABORT BIT(5) /*received Master abort */
483
484#define hp_rev_num 0x33
485
486#define hp_stack_data 0x34
487#define hp_stack_addr 0x35
488
489#define hp_ext_status 0x36
490
491#define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
492#define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
493#define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
494#define CMD_ABORTED BIT(4) /*Command aborted */
495#define BM_PARITY_ERR BIT(5) /*parity error on data received */
496#define PIO_OVERRUN BIT(6) /*Slave data overrun */
497#define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
498#define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
499 BM_PARITY_ERR | PIO_OVERRUN)
500
501#define hp_int_status 0x37
502
503#define EXT_STATUS_ON BIT(1) /*Extended status is valid */
504#define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
505#define INT_ASSERTED BIT(5) /* */
506
507#define hp_fifo_cnt 0x38
508
509#define hp_intena 0x40
510
511#define RESET BIT(7)
512#define PROG_HLT BIT(6)
513#define PARITY BIT(5)
514#define FIFO BIT(4)
515#define SEL BIT(3)
516#define SCAM_SEL BIT(2)
517#define RSEL BIT(1)
518#define TIMEOUT BIT(0)
519#define BUS_FREE BIT(15)
520#define XFER_CNT_0 BIT(14)
521#define PHASE BIT(13)
522#define IUNKWN BIT(12)
523#define ICMD_COMP BIT(11)
524#define ITICKLE BIT(10)
525#define IDO_STRT BIT(9)
526#define ITAR_DISC BIT(8)
527#define AUTO_INT (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
528#define CLR_ALL_INT 0xFFFF
529#define CLR_ALL_INT_1 0xFF00
530
531#define hp_intstat 0x42
532
533#define hp_scsisig 0x44
534
535#define SCSI_SEL BIT(7)
536#define SCSI_BSY BIT(6)
537#define SCSI_REQ BIT(5)
538#define SCSI_ACK BIT(4)
539#define SCSI_ATN BIT(3)
540#define SCSI_CD BIT(2)
541#define SCSI_MSG BIT(1)
542#define SCSI_IOBIT BIT(0)
543
544#define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
545#define S_MSGO_PH (BIT(2)+BIT(1) )
546#define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
547#define S_DATAI_PH ( BIT(0))
548#define S_DATAO_PH 0x00
549#define S_ILL_PH ( BIT(1) )
550
551#define hp_scsictrl_0 0x45
552
553#define SEL_TAR BIT(6)
554#define ENA_ATN BIT(4)
555#define ENA_RESEL BIT(2)
556#define SCSI_RST BIT(1)
557#define ENA_SCAM_SEL BIT(0)
558
559#define hp_portctrl_0 0x46
560
561#define SCSI_PORT BIT(7)
562#define SCSI_INBIT BIT(6)
563#define DMA_PORT BIT(5)
564#define DMA_RD BIT(4)
565#define HOST_PORT BIT(3)
566#define HOST_WRT BIT(2)
567#define SCSI_BUS_EN BIT(1)
568#define START_TO BIT(0)
569
570#define hp_scsireset 0x47
571
572#define SCSI_INI BIT(6)
573#define SCAM_EN BIT(5)
574#define DMA_RESET BIT(3)
575#define HPSCSI_RESET BIT(2)
576#define PROG_RESET BIT(1)
577#define FIFO_CLR BIT(0)
578
579#define hp_xfercnt_0 0x48
580#define hp_xfercnt_2 0x4A
581
582#define hp_fifodata_0 0x4C
583#define hp_addstat 0x4E
584
585#define SCAM_TIMER BIT(7)
586#define SCSI_MODE8 BIT(3)
587#define SCSI_PAR_ERR BIT(0)
588
589#define hp_prgmcnt_0 0x4F
590
591#define hp_selfid_0 0x50
592#define hp_selfid_1 0x51
593#define hp_arb_id 0x52
594
595#define hp_select_id 0x53
596
597#define hp_synctarg_base 0x54
598#define hp_synctarg_12 0x54
599#define hp_synctarg_13 0x55
600#define hp_synctarg_14 0x56
601#define hp_synctarg_15 0x57
602
603#define hp_synctarg_8 0x58
604#define hp_synctarg_9 0x59
605#define hp_synctarg_10 0x5A
606#define hp_synctarg_11 0x5B
607
608#define hp_synctarg_4 0x5C
609#define hp_synctarg_5 0x5D
610#define hp_synctarg_6 0x5E
611#define hp_synctarg_7 0x5F
612
613#define hp_synctarg_0 0x60
614#define hp_synctarg_1 0x61
615#define hp_synctarg_2 0x62
616#define hp_synctarg_3 0x63
617
618#define NARROW_SCSI BIT(4)
619#define DEFAULT_OFFSET 0x0F
620
621#define hp_autostart_0 0x64
622#define hp_autostart_1 0x65
623#define hp_autostart_3 0x67
624
625#define AUTO_IMMED BIT(5)
626#define SELECT BIT(6)
627#define END_DATA (BIT(7)+BIT(6))
628
629#define hp_gp_reg_0 0x68
630#define hp_gp_reg_1 0x69
631#define hp_gp_reg_3 0x6B
632
633#define hp_seltimeout 0x6C
634
635#define TO_4ms 0x67 /* 3.9959ms */
636
637#define TO_5ms 0x03 /* 4.9152ms */
638#define TO_10ms 0x07 /* 11.xxxms */
639#define TO_250ms 0x99 /* 250.68ms */
640#define TO_290ms 0xB1 /* 289.99ms */
641
642#define hp_clkctrl_0 0x6D
643
644#define PWR_DWN BIT(6)
645#define ACTdeassert BIT(4)
646#define CLK_40MHZ (BIT(1) + BIT(0))
647
648#define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
649
650#define hp_fiforead 0x6E
651#define hp_fifowrite 0x6F
652
653#define hp_offsetctr 0x70
654#define hp_xferstat 0x71
655
656#define FIFO_EMPTY BIT(6)
657
658#define hp_portctrl_1 0x72
659
660#define CHK_SCSI_P BIT(3)
661#define HOST_MODE8 BIT(0)
662
663#define hp_xfer_pad 0x73
664
665#define ID_UNLOCK BIT(3)
666
667#define hp_scsidata_0 0x74
668#define hp_scsidata_1 0x75
669
670#define hp_aramBase 0x80
671#define BIOS_DATA_OFFSET 0x60
672#define BIOS_RELATIVE_CARD 0x64
673
674#define AR3 (BIT(9) + BIT(8))
675#define SDATA BIT(10)
676
677#define CRD_OP BIT(11) /* Cmp Reg. w/ Data */
678
679#define CRR_OP BIT(12) /* Cmp Reg. w. Reg. */
680
681#define CPE_OP (BIT(14)+BIT(11)) /* Cmp SCSI phs & Branch EQ */
682
683#define CPN_OP (BIT(14)+BIT(12)) /* Cmp SCSI phs & Branch NOT EQ */
684
685#define ADATA_OUT 0x00
686#define ADATA_IN BIT(8)
687#define ACOMMAND BIT(10)
688#define ASTATUS (BIT(10)+BIT(8))
689#define AMSG_OUT (BIT(10)+BIT(9))
690#define AMSG_IN (BIT(10)+BIT(9)+BIT(8))
691
692#define BRH_OP BIT(13) /* Branch */
693
694#define ALWAYS 0x00
695#define EQUAL BIT(8)
696#define NOT_EQ BIT(9)
697
698#define TCB_OP (BIT(13)+BIT(11)) /* Test condition & branch */
699
700#define FIFO_0 BIT(10)
701
702#define MPM_OP BIT(15) /* Match phase and move data */
703
704#define MRR_OP BIT(14) /* Move DReg. to Reg. */
705
706#define S_IDREG (BIT(2)+BIT(1)+BIT(0))
707
708#define D_AR0 0x00
709#define D_AR1 BIT(0)
710#define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
711
712#define RAT_OP (BIT(14)+BIT(13)+BIT(11))
713
714#define SSI_OP (BIT(15)+BIT(11))
715
716#define SSI_ITAR_DISC (ITAR_DISC >> 8)
717#define SSI_IDO_STRT (IDO_STRT >> 8)
718
719#define SSI_ICMD_COMP (ICMD_COMP >> 8)
720#define SSI_ITICKLE (ITICKLE >> 8)
721
722#define SSI_IUNKWN (IUNKWN >> 8)
723#define SSI_INO_CC (IUNKWN >> 8)
724#define SSI_IRFAIL (IUNKWN >> 8)
725
726#define NP 0x10 /*Next Phase */
727#define NTCMD 0x02 /*Non- Tagged Command start */
728#define CMDPZ 0x04 /*Command phase */
729#define DINT 0x12 /*Data Out/In interrupt */
730#define DI 0x13 /*Data Out */
731#define DC 0x19 /*Disconnect Message */
732#define ST 0x1D /*Status Phase */
733#define UNKNWN 0x24 /*Unknown bus action */
734#define CC 0x25 /*Command Completion failure */
735#define TICK 0x26 /*New target reselected us. */
736#define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
737
738#define ID_MSG_STRT hp_aramBase + 0x00
739#define NON_TAG_ID_MSG hp_aramBase + 0x06
740#define CMD_STRT hp_aramBase + 0x08
741#define SYNC_MSGS hp_aramBase + 0x08
742
743#define TAG_STRT 0x00
744#define DISCONNECT_START 0x10/2
745#define END_DATA_START 0x14/2
746#define CMD_ONLY_STRT CMDPZ/2
747#define SELCHK_STRT SELCHK/2
748
749#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
750/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
751 xfercnt <<= 16,\
752 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
753 */
754#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
755 addr >>= 16,\
756 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
757 WR_HARP32(port,hp_xfercnt_0,count),\
758 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
759 count >>= 16,\
760 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
761
762#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
763 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
764
765#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
766 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
767
768#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
769 WR_HARPOON(port+hp_scsireset, 0x00))
770
771#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
772 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
773
774#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
775 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
776
777#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
778 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
779
780#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
781 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
782
783static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card,
784 unsigned char syncFlag);
785static void FPT_ssel(unsigned long port, unsigned char p_card);
786static void FPT_sres(unsigned long port, unsigned char p_card,
787 struct sccb_card *pCurrCard);
788static void FPT_shandem(unsigned long port, unsigned char p_card,
789 struct sccb *pCurrSCCB);
790static void FPT_stsyncn(unsigned long port, unsigned char p_card);
791static void FPT_sisyncr(unsigned long port, unsigned char sync_pulse,
792 unsigned char offset);
793static void FPT_sssyncv(unsigned long p_port, unsigned char p_id,
794 unsigned char p_sync_value,
795 struct sccb_mgr_tar_info *currTar_Info);
796static void FPT_sresb(unsigned long port, unsigned char p_card);
797static void FPT_sxfrp(unsigned long p_port, unsigned char p_card);
798static void FPT_schkdd(unsigned long port, unsigned char p_card);
799static unsigned char FPT_RdStack(unsigned long port, unsigned char index);
800static void FPT_WrStack(unsigned long portBase, unsigned char index,
801 unsigned char data);
802static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort);
803
804static void FPT_SendMsg(unsigned long port, unsigned char message);
805static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
806 unsigned char error_code);
807
808static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card);
809static void FPT_RNVRamData(struct nvram_info *pNvRamInfo);
810
811static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card);
812static void FPT_stwidn(unsigned long port, unsigned char p_card);
813static void FPT_siwidr(unsigned long port, unsigned char width);
814
815static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
816 unsigned char p_card);
817static void FPT_queueDisconnect(struct sccb *p_SCCB, unsigned char p_card);
818static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
819 struct sccb *p_SCCB, unsigned char p_card);
820static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
821 unsigned char p_card);
822static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
823static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char card);
824static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
825 unsigned char p_card);
826static void FPT_utilUpdateResidual(struct sccb *p_SCCB);
827static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
828static unsigned char FPT_CalcLrc(unsigned char buffer[]);
829
830static void FPT_Wait1Second(unsigned long p_port);
831static void FPT_Wait(unsigned long p_port, unsigned char p_delay);
832static void FPT_utilEEWriteOnOff(unsigned long p_port, unsigned char p_mode);
833static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data,
834 unsigned short ee_addr);
835static unsigned short FPT_utilEERead(unsigned long p_port,
836 unsigned short ee_addr);
837static unsigned short FPT_utilEEReadOrg(unsigned long p_port,
838 unsigned short ee_addr);
839static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd,
840 unsigned short ee_addr);
841
842static void FPT_phaseDataOut(unsigned long port, unsigned char p_card);
843static void FPT_phaseDataIn(unsigned long port, unsigned char p_card);
844static void FPT_phaseCommand(unsigned long port, unsigned char p_card);
845static void FPT_phaseStatus(unsigned long port, unsigned char p_card);
846static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card);
847static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card);
848static void FPT_phaseIllegal(unsigned long port, unsigned char p_card);
849
850static void FPT_phaseDecode(unsigned long port, unsigned char p_card);
851static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card);
852static void FPT_phaseBusFree(unsigned long p_port, unsigned char p_card);
853
854static void FPT_XbowInit(unsigned long port, unsigned char scamFlg);
855static void FPT_BusMasterInit(unsigned long p_port);
856static void FPT_DiagEEPROM(unsigned long p_port);
857
858static void FPT_dataXferProcessor(unsigned long port,
859 struct sccb_card *pCurrCard);
860static void FPT_busMstrSGDataXferStart(unsigned long port,
861 struct sccb *pCurrSCCB);
862static void FPT_busMstrDataXferStart(unsigned long port,
863 struct sccb *pCurrSCCB);
864static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card,
865 struct sccb *pCurrSCCB);
866static void FPT_hostDataXferRestart(struct sccb *currSCCB);
867
868static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port,
869 unsigned char p_card,
870 struct sccb_card *pCurrCard,
871 unsigned short p_int);
872
873static void FPT_SccbMgrTableInitAll(void);
874static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
875 unsigned char p_card);
876static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
877 unsigned char target);
878
879static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
880 unsigned char p_power_up);
881
882static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type);
883static void FPT_scbusf(unsigned long p_port);
884static void FPT_scsel(unsigned long p_port);
885static void FPT_scasid(unsigned char p_card, unsigned long p_port);
886static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data);
887static unsigned char FPT_scsendi(unsigned long p_port,
888 unsigned char p_id_string[]);
889static unsigned char FPT_sciso(unsigned long p_port,
890 unsigned char p_id_string[]);
891static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit);
892static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit);
893static unsigned char FPT_scvalq(unsigned char p_quintet);
894static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id);
895static void FPT_scwtsel(unsigned long p_port);
896static void FPT_inisci(unsigned char p_card, unsigned long p_port,
897 unsigned char p_our_id);
898static void FPT_scsavdi(unsigned char p_card, unsigned long p_port);
899static unsigned char FPT_scmachid(unsigned char p_card,
900 unsigned char p_id_string[]);
901
902static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card);
903static void FPT_autoLoadDefaultMap(unsigned long p_port);
904
905static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] =
906 { {{0}} };
907static struct sccb_card FPT_BL_Card[MAX_CARDS] = { {0} };
908static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { {{0}} };
909static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { {0} };
910
911static unsigned char FPT_mbCards = 0;
912static unsigned char FPT_scamHAString[] =
913 { 0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C',
914 ' ', 'B', 'T', '-', '9', '3', '0',
915 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
916 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
917};
918
919static unsigned short FPT_default_intena = 0;
920
921static void (*FPT_s_PhaseTbl[8]) (unsigned long, unsigned char) = {
9220};
923
924/*---------------------------------------------------------------------
925 *
926 * Function: FlashPoint_ProbeHostAdapter
927 *
928 * Description: Setup and/or Search for cards and return info to caller.
929 *
930 *---------------------------------------------------------------------*/
931
932static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo)
933{
934 static unsigned char first_time = 1;
935
936 unsigned char i, j, id, ScamFlg;
937 unsigned short temp, temp2, temp3, temp4, temp5, temp6;
938 unsigned long ioport;
939 struct nvram_info *pCurrNvRam;
940
941 ioport = pCardInfo->si_baseaddr;
942
943 if (RD_HARPOON(ioport + hp_vendor_id_0) != ORION_VEND_0)
944 return (int)FAILURE;
945
946 if ((RD_HARPOON(ioport + hp_vendor_id_1) != ORION_VEND_1))
947 return (int)FAILURE;
948
949 if ((RD_HARPOON(ioport + hp_device_id_0) != ORION_DEV_0))
950 return (int)FAILURE;
951
952 if ((RD_HARPOON(ioport + hp_device_id_1) != ORION_DEV_1))
953 return (int)FAILURE;
954
955 if (RD_HARPOON(ioport + hp_rev_num) != 0x0f) {
956
957/* For new Harpoon then check for sub_device ID LSB
958 the bits(0-3) must be all ZERO for compatible with
959 current version of SCCBMgr, else skip this Harpoon
960 device. */
961
962 if (RD_HARPOON(ioport + hp_sub_device_id_0) & 0x0f)
963 return (int)FAILURE;
964 }
965
966 if (first_time) {
967 FPT_SccbMgrTableInitAll();
968 first_time = 0;
969 FPT_mbCards = 0;
970 }
971
972 if (FPT_RdStack(ioport, 0) != 0x00) {
973 if (FPT_ChkIfChipInitialized(ioport) == 0) {
974 pCurrNvRam = NULL;
975 WR_HARPOON(ioport + hp_semaphore, 0x00);
976 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
977 FPT_DiagEEPROM(ioport);
978 } else {
979 if (FPT_mbCards < MAX_MB_CARDS) {
980 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
981 FPT_mbCards++;
982 pCurrNvRam->niBaseAddr = ioport;
983 FPT_RNVRamData(pCurrNvRam);
984 } else
985 return (int)FAILURE;
986 }
987 } else
988 pCurrNvRam = NULL;
989
990 WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
991 WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
992
993 if (pCurrNvRam)
994 pCardInfo->si_id = pCurrNvRam->niAdapId;
995 else
996 pCardInfo->si_id =
997 (unsigned
998 char)(FPT_utilEERead(ioport,
999 (ADAPTER_SCSI_ID /
1000 2)) & (unsigned char)0x0FF);
1001
1002 pCardInfo->si_lun = 0x00;
1003 pCardInfo->si_fw_revision = ORION_FW_REV;
1004 temp2 = 0x0000;
1005 temp3 = 0x0000;
1006 temp4 = 0x0000;
1007 temp5 = 0x0000;
1008 temp6 = 0x0000;
1009
1010 for (id = 0; id < (16 / 2); id++) {
1011
1012 if (pCurrNvRam) {
1013 temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
1014 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1015 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1016 } else
1017 temp =
1018 FPT_utilEERead(ioport,
1019 (unsigned short)((SYNC_RATE_TBL / 2)
1020 + id));
1021
1022 for (i = 0; i < 2; temp >>= 8, i++) {
1023
1024 temp2 >>= 1;
1025 temp3 >>= 1;
1026 temp4 >>= 1;
1027 temp5 >>= 1;
1028 temp6 >>= 1;
1029 switch (temp & 0x3) {
1030 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1031 temp6 |= 0x8000; /* Fall through */
1032 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1033 temp5 |= 0x8000; /* Fall through */
1034 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1035 temp2 |= 0x8000; /* Fall through */
1036 case AUTO_RATE_00: /* Asynchronous */
1037 break;
1038 }
1039
1040 if (temp & DISC_ENABLE_BIT)
1041 temp3 |= 0x8000;
1042
1043 if (temp & WIDE_NEGO_BIT)
1044 temp4 |= 0x8000;
1045
1046 }
1047 }
1048
1049 pCardInfo->si_per_targ_init_sync = temp2;
1050 pCardInfo->si_per_targ_no_disc = temp3;
1051 pCardInfo->si_per_targ_wide_nego = temp4;
1052 pCardInfo->si_per_targ_fast_nego = temp5;
1053 pCardInfo->si_per_targ_ultra_nego = temp6;
1054
1055 if (pCurrNvRam)
1056 i = pCurrNvRam->niSysConf;
1057 else
1058 i = (unsigned
1059 char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)));
1060
1061 if (pCurrNvRam)
1062 ScamFlg = pCurrNvRam->niScamConf;
1063 else
1064 ScamFlg =
1065 (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1066
1067 pCardInfo->si_flags = 0x0000;
1068
1069 if (i & 0x01)
1070 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1071
1072 if (!(i & 0x02))
1073 pCardInfo->si_flags |= SOFT_RESET;
1074
1075 if (i & 0x10)
1076 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1077
1078 if (ScamFlg & SCAM_ENABLED)
1079 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1080
1081 if (ScamFlg & SCAM_LEVEL2)
1082 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1083
1084 j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1085 if (i & 0x04) {
1086 j |= SCSI_TERM_ENA_L;
1087 }
1088 WR_HARPOON(ioport + hp_bm_ctrl, j);
1089
1090 j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1091 if (i & 0x08) {
1092 j |= SCSI_TERM_ENA_H;
1093 }
1094 WR_HARPOON(ioport + hp_ee_ctrl, j);
1095
1096 if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD))
1097
1098 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1099
1100 pCardInfo->si_card_family = HARPOON_FAMILY;
1101 pCardInfo->si_bustype = BUSTYPE_PCI;
1102
1103 if (pCurrNvRam) {
1104 pCardInfo->si_card_model[0] = '9';
1105 switch (pCurrNvRam->niModel & 0x0f) {
1106 case MODEL_LT:
1107 pCardInfo->si_card_model[1] = '3';
1108 pCardInfo->si_card_model[2] = '0';
1109 break;
1110 case MODEL_LW:
1111 pCardInfo->si_card_model[1] = '5';
1112 pCardInfo->si_card_model[2] = '0';
1113 break;
1114 case MODEL_DL:
1115 pCardInfo->si_card_model[1] = '3';
1116 pCardInfo->si_card_model[2] = '2';
1117 break;
1118 case MODEL_DW:
1119 pCardInfo->si_card_model[1] = '5';
1120 pCardInfo->si_card_model[2] = '2';
1121 break;
1122 }
1123 } else {
1124 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0 / 2));
1125 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1126 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2 / 2));
1127
1128 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1129 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1130 }
1131
1132 if (pCardInfo->si_card_model[1] == '3') {
1133 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1134 pCardInfo->si_flags |= LOW_BYTE_TERM;
1135 } else if (pCardInfo->si_card_model[2] == '0') {
1136 temp = RD_HARPOON(ioport + hp_xfer_pad);
1137 WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4)));
1138 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1139 pCardInfo->si_flags |= LOW_BYTE_TERM;
1140 WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4)));
1141 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1142 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1143 WR_HARPOON(ioport + hp_xfer_pad, temp);
1144 } else {
1145 temp = RD_HARPOON(ioport + hp_ee_ctrl);
1146 temp2 = RD_HARPOON(ioport + hp_xfer_pad);
1147 WR_HARPOON(ioport + hp_ee_ctrl, (temp | SEE_CS));
1148 WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1149 temp3 = 0;
1150 for (i = 0; i < 8; i++) {
1151 temp3 <<= 1;
1152 if (!(RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)))
1153 temp3 |= 1;
1154 WR_HARPOON(ioport + hp_xfer_pad, (temp2 & ~BIT(4)));
1155 WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1156 }
1157 WR_HARPOON(ioport + hp_ee_ctrl, temp);
1158 WR_HARPOON(ioport + hp_xfer_pad, temp2);
1159 if (!(temp3 & BIT(7)))
1160 pCardInfo->si_flags |= LOW_BYTE_TERM;
1161 if (!(temp3 & BIT(6)))
1162 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1163 }
1164
1165 ARAM_ACCESS(ioport);
1166
1167 for (i = 0; i < 4; i++) {
1168
1169 pCardInfo->si_XlatInfo[i] =
1170 RD_HARPOON(ioport + hp_aramBase + BIOS_DATA_OFFSET + i);
1171 }
1172
1173 /* return with -1 if no sort, else return with
1174 logical card number sorted by BIOS (zero-based) */
1175
1176 pCardInfo->si_relative_cardnum =
1177 (unsigned
1178 char)(RD_HARPOON(ioport + hp_aramBase + BIOS_RELATIVE_CARD) - 1);
1179
1180 SGRAM_ACCESS(ioport);
1181
1182 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1183 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1184 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1185 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1186 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1187 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1188 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1189 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1190
1191 pCardInfo->si_present = 0x01;
1192
1193 return 0;
1194}
1195
1196/*---------------------------------------------------------------------
1197 *
1198 * Function: FlashPoint_HardwareResetHostAdapter
1199 *
1200 * Description: Setup adapter for normal operation (hard reset).
1201 *
1202 *---------------------------------------------------------------------*/
1203
1204static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
1205 *pCardInfo)
1206{
1207 struct sccb_card *CurrCard = NULL;
1208 struct nvram_info *pCurrNvRam;
1209 unsigned char i, j, thisCard, ScamFlg;
1210 unsigned short temp, sync_bit_map, id;
1211 unsigned long ioport;
1212
1213 ioport = pCardInfo->si_baseaddr;
1214
1215 for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) {
1216
1217 if (thisCard == MAX_CARDS) {
1218
1219 return FAILURE;
1220 }
1221
1222 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1223
1224 CurrCard = &FPT_BL_Card[thisCard];
1225 FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1226 break;
1227 }
1228
1229 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1230
1231 FPT_BL_Card[thisCard].ioPort = ioport;
1232 CurrCard = &FPT_BL_Card[thisCard];
1233
1234 if (FPT_mbCards)
1235 for (i = 0; i < FPT_mbCards; i++) {
1236 if (CurrCard->ioPort ==
1237 FPT_nvRamInfo[i].niBaseAddr)
1238 CurrCard->pNvRamInfo =
1239 &FPT_nvRamInfo[i];
1240 }
1241 FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1242 CurrCard->cardIndex = thisCard;
1243 CurrCard->cardInfo = pCardInfo;
1244
1245 break;
1246 }
1247 }
1248
1249 pCurrNvRam = CurrCard->pNvRamInfo;
1250
1251 if (pCurrNvRam) {
1252 ScamFlg = pCurrNvRam->niScamConf;
1253 } else {
1254 ScamFlg =
1255 (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1256 }
1257
1258 FPT_BusMasterInit(ioport);
1259 FPT_XbowInit(ioport, ScamFlg);
1260
1261 FPT_autoLoadDefaultMap(ioport);
1262
1263 for (i = 0, id = 0x01; i != pCardInfo->si_id; i++, id <<= 1) {
1264 }
1265
1266 WR_HARPOON(ioport + hp_selfid_0, id);
1267 WR_HARPOON(ioport + hp_selfid_1, 0x00);
1268 WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id);
1269 CurrCard->ourId = pCardInfo->si_id;
1270
1271 i = (unsigned char)pCardInfo->si_flags;
1272 if (i & SCSI_PARITY_ENA)
1273 WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P));
1274
1275 j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1276 if (i & LOW_BYTE_TERM)
1277 j |= SCSI_TERM_ENA_L;
1278 WR_HARPOON(ioport + hp_bm_ctrl, j);
1279
1280 j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1281 if (i & HIGH_BYTE_TERM)
1282 j |= SCSI_TERM_ENA_H;
1283 WR_HARPOON(ioport + hp_ee_ctrl, j);
1284
1285 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1286
1287 FPT_sresb(ioport, thisCard);
1288
1289 FPT_scini(thisCard, pCardInfo->si_id, 0);
1290 }
1291
1292 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1293 CurrCard->globalFlags |= F_NO_FILTER;
1294
1295 if (pCurrNvRam) {
1296 if (pCurrNvRam->niSysConf & 0x10)
1297 CurrCard->globalFlags |= F_GREEN_PC;
1298 } else {
1299 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)) & GREEN_PC_ENA)
1300 CurrCard->globalFlags |= F_GREEN_PC;
1301 }
1302
1303 /* Set global flag to indicate Re-Negotiation to be done on all
1304 ckeck condition */
1305 if (pCurrNvRam) {
1306 if (pCurrNvRam->niScsiConf & 0x04)
1307 CurrCard->globalFlags |= F_DO_RENEGO;
1308 } else {
1309 if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & RENEGO_ENA)
1310 CurrCard->globalFlags |= F_DO_RENEGO;
1311 }
1312
1313 if (pCurrNvRam) {
1314 if (pCurrNvRam->niScsiConf & 0x08)
1315 CurrCard->globalFlags |= F_CONLUN_IO;
1316 } else {
1317 if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & CONNIO_ENA)
1318 CurrCard->globalFlags |= F_CONLUN_IO;
1319 }
1320
1321 temp = pCardInfo->si_per_targ_no_disc;
1322
1323 for (i = 0, id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1324
1325 if (temp & id)
1326 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1327 }
1328
1329 sync_bit_map = 0x0001;
1330
1331 for (id = 0; id < (MAX_SCSI_TAR / 2); id++) {
1332
1333 if (pCurrNvRam) {
1334 temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
1335 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1336 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1337 } else
1338 temp =
1339 FPT_utilEERead(ioport,
1340 (unsigned short)((SYNC_RATE_TBL / 2)
1341 + id));
1342
1343 for (i = 0; i < 2; temp >>= 8, i++) {
1344
1345 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1346
1347 FPT_sccbMgrTbl[thisCard][id * 2 +
1348 i].TarEEValue =
1349 (unsigned char)temp;
1350 }
1351
1352 else {
1353 FPT_sccbMgrTbl[thisCard][id * 2 +
1354 i].TarStatus |=
1355 SYNC_SUPPORTED;
1356 FPT_sccbMgrTbl[thisCard][id * 2 +
1357 i].TarEEValue =
1358 (unsigned char)(temp & ~EE_SYNC_MASK);
1359 }
1360
1361/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1362 (id*2+i >= 8)){
1363*/
1364 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map) {
1365
1366 FPT_sccbMgrTbl[thisCard][id * 2 +
1367 i].TarEEValue |=
1368 EE_WIDE_SCSI;
1369
1370 }
1371
1372 else { /* NARROW SCSI */
1373 FPT_sccbMgrTbl[thisCard][id * 2 +
1374 i].TarStatus |=
1375 WIDE_NEGOCIATED;
1376 }
1377
1378 sync_bit_map <<= 1;
1379
1380 }
1381 }
1382
1383 WR_HARPOON((ioport + hp_semaphore),
1384 (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) |
1385 SCCB_MGR_PRESENT));
1386
1387 return (unsigned long)CurrCard;
1388}
1389
1390static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard)
1391{
1392 unsigned char i;
1393 unsigned long portBase;
1394 unsigned long regOffset;
1395 unsigned long scamData;
1396 unsigned long *pScamTbl;
1397 struct nvram_info *pCurrNvRam;
1398
1399 pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
1400
1401 if (pCurrNvRam) {
1402 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1403 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1404 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1405 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1406 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1407
1408 for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1409 FPT_WrStack(pCurrNvRam->niBaseAddr,
1410 (unsigned char)(i + 5),
1411 pCurrNvRam->niSyncTbl[i]);
1412
1413 portBase = pCurrNvRam->niBaseAddr;
1414
1415 for (i = 0; i < MAX_SCSI_TAR; i++) {
1416 regOffset = hp_aramBase + 64 + i * 4;
1417 pScamTbl = (unsigned long *)&pCurrNvRam->niScamTbl[i];
1418 scamData = *pScamTbl;
1419 WR_HARP32(portBase, regOffset, scamData);
1420 }
1421
1422 } else {
1423 FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0);
1424 }
1425}
1426
1427static void FPT_RNVRamData(struct nvram_info *pNvRamInfo)
1428{
1429 unsigned char i;
1430 unsigned long portBase;
1431 unsigned long regOffset;
1432 unsigned long scamData;
1433 unsigned long *pScamTbl;
1434
1435 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1436 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1437 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1438 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1439 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1440
1441 for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1442 pNvRamInfo->niSyncTbl[i] =
1443 FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i + 5));
1444
1445 portBase = pNvRamInfo->niBaseAddr;
1446
1447 for (i = 0; i < MAX_SCSI_TAR; i++) {
1448 regOffset = hp_aramBase + 64 + i * 4;
1449 RD_HARP32(portBase, regOffset, scamData);
1450 pScamTbl = (unsigned long *)&pNvRamInfo->niScamTbl[i];
1451 *pScamTbl = scamData;
1452 }
1453
1454}
1455
1456static unsigned char FPT_RdStack(unsigned long portBase, unsigned char index)
1457{
1458 WR_HARPOON(portBase + hp_stack_addr, index);
1459 return RD_HARPOON(portBase + hp_stack_data);
1460}
1461
1462static void FPT_WrStack(unsigned long portBase, unsigned char index,
1463 unsigned char data)
1464{
1465 WR_HARPOON(portBase + hp_stack_addr, index);
1466 WR_HARPOON(portBase + hp_stack_data, data);
1467}
1468
1469static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort)
1470{
1471 if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1472 return 0;
1473 if ((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1474 != CLKCTRL_DEFAULT)
1475 return 0;
1476 if ((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1477 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1478 return 1;
1479 return 0;
1480
1481}
1482
1483/*---------------------------------------------------------------------
1484 *
1485 * Function: FlashPoint_StartCCB
1486 *
1487 * Description: Start a command pointed to by p_Sccb. When the
1488 * command is completed it will be returned via the
1489 * callback function.
1490 *
1491 *---------------------------------------------------------------------*/
1492static void FlashPoint_StartCCB(unsigned long pCurrCard, struct sccb *p_Sccb)
1493{
1494 unsigned long ioport;
1495 unsigned char thisCard, lun;
1496 struct sccb *pSaveSccb;
1497 CALL_BK_FN callback;
1498
1499 thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1500 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1501
1502 if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) {
1503
1504 p_Sccb->HostStatus = SCCB_COMPLETE;
1505 p_Sccb->SccbStatus = SCCB_ERROR;
1506 callback = (CALL_BK_FN) p_Sccb->SccbCallback;
1507 if (callback)
1508 callback(p_Sccb);
1509
1510 return;
1511 }
1512
1513 FPT_sinits(p_Sccb, thisCard);
1514
1515 if (!((struct sccb_card *)pCurrCard)->cmdCounter) {
1516 WR_HARPOON(ioport + hp_semaphore,
1517 (RD_HARPOON(ioport + hp_semaphore)
1518 | SCCB_MGR_ACTIVE));
1519
1520 if (((struct sccb_card *)pCurrCard)->globalFlags & F_GREEN_PC) {
1521 WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
1522 WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
1523 }
1524 }
1525
1526 ((struct sccb_card *)pCurrCard)->cmdCounter++;
1527
1528 if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) {
1529
1530 WR_HARPOON(ioport + hp_semaphore,
1531 (RD_HARPOON(ioport + hp_semaphore)
1532 | TICKLE_ME));
1533 if (p_Sccb->OperationCode == RESET_COMMAND) {
1534 pSaveSccb =
1535 ((struct sccb_card *)pCurrCard)->currentSCCB;
1536 ((struct sccb_card *)pCurrCard)->currentSCCB = p_Sccb;
1537 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1538 ((struct sccb_card *)pCurrCard)->currentSCCB =
1539 pSaveSccb;
1540 } else {
1541 FPT_queueAddSccb(p_Sccb, thisCard);
1542 }
1543 }
1544
1545 else if ((RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1546
1547 if (p_Sccb->OperationCode == RESET_COMMAND) {
1548 pSaveSccb =
1549 ((struct sccb_card *)pCurrCard)->currentSCCB;
1550 ((struct sccb_card *)pCurrCard)->currentSCCB = p_Sccb;
1551 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1552 ((struct sccb_card *)pCurrCard)->currentSCCB =
1553 pSaveSccb;
1554 } else {
1555 FPT_queueAddSccb(p_Sccb, thisCard);
1556 }
1557 }
1558
1559 else {
1560
1561 MDISABLE_INT(ioport);
1562
1563 if ((((struct sccb_card *)pCurrCard)->globalFlags & F_CONLUN_IO)
1564 &&
1565 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].
1566 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1567 lun = p_Sccb->Lun;
1568 else
1569 lun = 0;
1570 if ((((struct sccb_card *)pCurrCard)->currentSCCB == NULL) &&
1571 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0)
1572 && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1573 == 0)) {
1574
1575 ((struct sccb_card *)pCurrCard)->currentSCCB = p_Sccb;
1576 FPT_ssel(p_Sccb->SccbIOPort, thisCard);
1577 }
1578
1579 else {
1580
1581 if (p_Sccb->OperationCode == RESET_COMMAND) {
1582 pSaveSccb =
1583 ((struct sccb_card *)pCurrCard)->
1584 currentSCCB;
1585 ((struct sccb_card *)pCurrCard)->currentSCCB =
1586 p_Sccb;
1587 FPT_queueSelectFail(&FPT_BL_Card[thisCard],
1588 thisCard);
1589 ((struct sccb_card *)pCurrCard)->currentSCCB =
1590 pSaveSccb;
1591 } else {
1592 FPT_queueAddSccb(p_Sccb, thisCard);
1593 }
1594 }
1595
1596 MENABLE_INT(ioport);
1597 }
1598
1599}
1600
1601/*---------------------------------------------------------------------
1602 *
1603 * Function: FlashPoint_AbortCCB
1604 *
1605 * Description: Abort the command pointed to by p_Sccb. When the
1606 * command is completed it will be returned via the
1607 * callback function.
1608 *
1609 *---------------------------------------------------------------------*/
1610static int FlashPoint_AbortCCB(unsigned long pCurrCard, struct sccb *p_Sccb)
1611{
1612 unsigned long ioport;
1613
1614 unsigned char thisCard;
1615 CALL_BK_FN callback;
1616 unsigned char TID;
1617 struct sccb *pSaveSCCB;
1618 struct sccb_mgr_tar_info *currTar_Info;
1619
1620 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1621
1622 thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1623
1624 if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1625
1626 if (FPT_queueFindSccb(p_Sccb, thisCard)) {
1627
1628 ((struct sccb_card *)pCurrCard)->cmdCounter--;
1629
1630 if (!((struct sccb_card *)pCurrCard)->cmdCounter)
1631 WR_HARPOON(ioport + hp_semaphore,
1632 (RD_HARPOON(ioport + hp_semaphore)
1633 & (unsigned
1634 char)(~(SCCB_MGR_ACTIVE |
1635 TICKLE_ME))));
1636
1637 p_Sccb->SccbStatus = SCCB_ABORT;
1638 callback = p_Sccb->SccbCallback;
1639 callback(p_Sccb);
1640
1641 return 0;
1642 }
1643
1644 else {
1645 if (((struct sccb_card *)pCurrCard)->currentSCCB ==
1646 p_Sccb) {
1647 p_Sccb->SccbStatus = SCCB_ABORT;
1648 return 0;
1649
1650 }
1651
1652 else {
1653
1654 TID = p_Sccb->TargID;
1655
1656 if (p_Sccb->Sccb_tag) {
1657 MDISABLE_INT(ioport);
1658 if (((struct sccb_card *)pCurrCard)->
1659 discQ_Tbl[p_Sccb->Sccb_tag] ==
1660 p_Sccb) {
1661 p_Sccb->SccbStatus = SCCB_ABORT;
1662 p_Sccb->Sccb_scsistat =
1663 ABORT_ST;
1664 p_Sccb->Sccb_scsimsg =
1665 SMABORT_TAG;
1666
1667 if (((struct sccb_card *)
1668 pCurrCard)->currentSCCB ==
1669 NULL) {
1670 ((struct sccb_card *)
1671 pCurrCard)->
1672 currentSCCB = p_Sccb;
1673 FPT_ssel(ioport,
1674 thisCard);
1675 } else {
1676 pSaveSCCB =
1677 ((struct sccb_card
1678 *)pCurrCard)->
1679 currentSCCB;
1680 ((struct sccb_card *)
1681 pCurrCard)->
1682 currentSCCB = p_Sccb;
1683 FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard);
1684 ((struct sccb_card *)
1685 pCurrCard)->
1686 currentSCCB = pSaveSCCB;
1687 }
1688 }
1689 MENABLE_INT(ioport);
1690 return 0;
1691 } else {
1692 currTar_Info =
1693 &FPT_sccbMgrTbl[thisCard][p_Sccb->
1694 TargID];
1695
1696 if (FPT_BL_Card[thisCard].
1697 discQ_Tbl[currTar_Info->
1698 LunDiscQ_Idx[p_Sccb->Lun]]
1699 == p_Sccb) {
1700 p_Sccb->SccbStatus = SCCB_ABORT;
1701 return 0;
1702 }
1703 }
1704 }
1705 }
1706 }
1707 return -1;
1708}
1709
1710/*---------------------------------------------------------------------
1711 *
1712 * Function: FlashPoint_InterruptPending
1713 *
1714 * Description: Do a quick check to determine if there is a pending
1715 * interrupt for this card and disable the IRQ Pin if so.
1716 *
1717 *---------------------------------------------------------------------*/
1718static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard)
1719{
1720 unsigned long ioport;
1721
1722 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1723
1724 if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) {
1725 return 1;
1726 }
1727
1728 else
1729
1730 return 0;
1731}
1732
1733/*---------------------------------------------------------------------
1734 *
1735 * Function: FlashPoint_HandleInterrupt
1736 *
1737 * Description: This is our entry point when an interrupt is generated
1738 * by the card and the upper level driver passes it on to
1739 * us.
1740 *
1741 *---------------------------------------------------------------------*/
1742static int FlashPoint_HandleInterrupt(unsigned long pCurrCard)
1743{
1744 struct sccb *currSCCB;
1745 unsigned char thisCard, result, bm_status, bm_int_st;
1746 unsigned short hp_int;
1747 unsigned char i, target;
1748 unsigned long ioport;
1749
1750 thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1751 ioport = ((struct sccb_card *)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 =
1757 RD_HARPOON(ioport +
1758 hp_ext_status) & (unsigned char)BAD_EXT_STATUS;
1759 else
1760 bm_status = 0;
1761
1762 WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1763
1764 while ((hp_int =
1765 RDW_HARPOON((ioport +
1766 hp_intstat)) & FPT_default_intena) | bm_status) {
1767
1768 currSCCB = ((struct sccb_card *)pCurrCard)->currentSCCB;
1769
1770 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1771 result =
1772 FPT_SccbMgr_bad_isr(ioport, thisCard,
1773 ((struct sccb_card *)pCurrCard),
1774 hp_int);
1775 WRW_HARPOON((ioport + hp_intstat),
1776 (FIFO | TIMEOUT | RESET | SCAM_SEL));
1777 bm_status = 0;
1778
1779 if (result) {
1780
1781 MENABLE_INT(ioport);
1782 return result;
1783 }
1784 }
1785
1786 else if (hp_int & ICMD_COMP) {
1787
1788 if (!(hp_int & BUS_FREE)) {
1789 /* Wait for the BusFree before starting a new command. We
1790 must also check for being reselected since the BusFree
1791 may not show up if another device reselects us in 1.5us or
1792 less. SRR Wednesday, 3/8/1995.
1793 */
1794 while (!
1795 (RDW_HARPOON((ioport + hp_intstat)) &
1796 (BUS_FREE | RSEL))) ;
1797 }
1798
1799 if (((struct sccb_card *)pCurrCard)->
1800 globalFlags & F_HOST_XFER_ACT)
1801
1802 FPT_phaseChkFifo(ioport, thisCard);
1803
1804/* WRW_HARPOON((ioport+hp_intstat),
1805 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1806 */
1807
1808 WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1);
1809
1810 FPT_autoCmdCmplt(ioport, thisCard);
1811
1812 }
1813
1814 else if (hp_int & ITAR_DISC) {
1815
1816 if (((struct sccb_card *)pCurrCard)->
1817 globalFlags & F_HOST_XFER_ACT) {
1818
1819 FPT_phaseChkFifo(ioport, thisCard);
1820
1821 }
1822
1823 if (RD_HARPOON(ioport + hp_gp_reg_1) == SMSAVE_DATA_PTR) {
1824
1825 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1826 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1827
1828 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1829 }
1830
1831 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1832 FPT_queueDisconnect(currSCCB, thisCard);
1833
1834 /* Wait for the BusFree before starting a new command. We
1835 must also check for being reselected since the BusFree
1836 may not show up if another device reselects us in 1.5us or
1837 less. SRR Wednesday, 3/8/1995.
1838 */
1839 while (!
1840 (RDW_HARPOON((ioport + hp_intstat)) &
1841 (BUS_FREE | RSEL))
1842 && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE)
1843 && RD_HARPOON((ioport + hp_scsisig)) ==
1844 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG |
1845 SCSI_IOBIT))) ;
1846
1847 /*
1848 The additional loop exit condition above detects a timing problem
1849 with the revision D/E harpoon chips. The caller should reset the
1850 host adapter to recover when 0xFE is returned.
1851 */
1852 if (!
1853 (RDW_HARPOON((ioport + hp_intstat)) &
1854 (BUS_FREE | RSEL))) {
1855 MENABLE_INT(ioport);
1856 return 0xFE;
1857 }
1858
1859 WRW_HARPOON((ioport + hp_intstat),
1860 (BUS_FREE | ITAR_DISC));
1861
1862 ((struct sccb_card *)pCurrCard)->globalFlags |=
1863 F_NEW_SCCB_CMD;
1864
1865 }
1866
1867 else if (hp_int & RSEL) {
1868
1869 WRW_HARPOON((ioport + hp_intstat),
1870 (PROG_HLT | RSEL | PHASE | BUS_FREE));
1871
1872 if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) {
1873 if (((struct sccb_card *)pCurrCard)->
1874 globalFlags & F_HOST_XFER_ACT) {
1875 FPT_phaseChkFifo(ioport, thisCard);
1876 }
1877
1878 if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1879 SMSAVE_DATA_PTR) {
1880 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1881 currSCCB->Sccb_XferState |=
1882 F_NO_DATA_YET;
1883 currSCCB->Sccb_savedATC =
1884 currSCCB->Sccb_ATC;
1885 }
1886
1887 WRW_HARPOON((ioport + hp_intstat),
1888 (BUS_FREE | ITAR_DISC));
1889 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1890 FPT_queueDisconnect(currSCCB, thisCard);
1891 }
1892
1893 FPT_sres(ioport, thisCard,
1894 ((struct sccb_card *)pCurrCard));
1895 FPT_phaseDecode(ioport, thisCard);
1896
1897 }
1898
1899 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) {
1900
1901 WRW_HARPOON((ioport + hp_intstat),
1902 (IDO_STRT | XFER_CNT_0));
1903 FPT_phaseDecode(ioport, thisCard);
1904
1905 }
1906
1907 else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) {
1908 WRW_HARPOON((ioport + hp_intstat),
1909 (PHASE | IUNKWN | PROG_HLT));
1910 if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char)
1911 0x3f) < (unsigned char)SELCHK) {
1912 FPT_phaseDecode(ioport, thisCard);
1913 } else {
1914 /* Harpoon problem some SCSI target device respond to selection
1915 with short BUSY pulse (<400ns) this will make the Harpoon is not able
1916 to latch the correct Target ID into reg. x53.
1917 The work around require to correct this reg. But when write to this
1918 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
1919 need to read this reg first then restore it later. After update to 0x53 */
1920
1921 i = (unsigned
1922 char)(RD_HARPOON(ioport + hp_fifowrite));
1923 target =
1924 (unsigned
1925 char)(RD_HARPOON(ioport + hp_gp_reg_3));
1926 WR_HARPOON(ioport + hp_xfer_pad,
1927 (unsigned char)ID_UNLOCK);
1928 WR_HARPOON(ioport + hp_select_id,
1929 (unsigned char)(target | target <<
1930 4));
1931 WR_HARPOON(ioport + hp_xfer_pad,
1932 (unsigned char)0x00);
1933 WR_HARPOON(ioport + hp_fifowrite, i);
1934 WR_HARPOON(ioport + hp_autostart_3,
1935 (AUTO_IMMED + TAG_STRT));
1936 }
1937 }
1938
1939 else if (hp_int & XFER_CNT_0) {
1940
1941 WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0);
1942
1943 FPT_schkdd(ioport, thisCard);
1944
1945 }
1946
1947 else if (hp_int & BUS_FREE) {
1948
1949 WRW_HARPOON((ioport + hp_intstat), BUS_FREE);
1950
1951 if (((struct sccb_card *)pCurrCard)->
1952 globalFlags & F_HOST_XFER_ACT) {
1953
1954 FPT_hostDataXferAbort(ioport, thisCard,
1955 currSCCB);
1956 }
1957
1958 FPT_phaseBusFree(ioport, thisCard);
1959 }
1960
1961 else if (hp_int & ITICKLE) {
1962
1963 WRW_HARPOON((ioport + hp_intstat), ITICKLE);
1964 ((struct sccb_card *)pCurrCard)->globalFlags |=
1965 F_NEW_SCCB_CMD;
1966 }
1967
1968 if (((struct sccb_card *)pCurrCard)->
1969 globalFlags & F_NEW_SCCB_CMD) {
1970
1971 ((struct sccb_card *)pCurrCard)->globalFlags &=
1972 ~F_NEW_SCCB_CMD;
1973
1974 if (((struct sccb_card *)pCurrCard)->currentSCCB ==
1975 NULL) {
1976
1977 FPT_queueSearchSelect(((struct sccb_card *)
1978 pCurrCard), thisCard);
1979 }
1980
1981 if (((struct sccb_card *)pCurrCard)->currentSCCB !=
1982 NULL) {
1983 ((struct sccb_card *)pCurrCard)->globalFlags &=
1984 ~F_NEW_SCCB_CMD;
1985 FPT_ssel(ioport, thisCard);
1986 }
1987
1988 break;
1989
1990 }
1991
1992 } /*end while */
1993
1994 MENABLE_INT(ioport);
1995
1996 return 0;
1997}
1998
1999/*---------------------------------------------------------------------
2000 *
2001 * Function: Sccb_bad_isr
2002 *
2003 * Description: Some type of interrupt has occurred which is slightly
2004 * out of the ordinary. We will now decode it fully, in
2005 * this routine. This is broken up in an attempt to save
2006 * processing time.
2007 *
2008 *---------------------------------------------------------------------*/
2009static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port,
2010 unsigned char p_card,
2011 struct sccb_card *pCurrCard,
2012 unsigned short p_int)
2013{
2014 unsigned char temp, ScamFlg;
2015 struct sccb_mgr_tar_info *currTar_Info;
2016 struct nvram_info *pCurrNvRam;
2017
2018 if (RD_HARPOON(p_port + hp_ext_status) &
2019 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) {
2020
2021 if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
2022
2023 FPT_hostDataXferAbort(p_port, p_card,
2024 pCurrCard->currentSCCB);
2025 }
2026
2027 if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT)
2028 {
2029 WR_HARPOON(p_port + hp_pci_stat_cfg,
2030 (RD_HARPOON(p_port + hp_pci_stat_cfg) &
2031 ~REC_MASTER_ABORT));
2032
2033 WR_HARPOON(p_port + hp_host_blk_cnt, 0x00);
2034
2035 }
2036
2037 if (pCurrCard->currentSCCB != NULL) {
2038
2039 if (!pCurrCard->currentSCCB->HostStatus)
2040 pCurrCard->currentSCCB->HostStatus =
2041 SCCB_BM_ERR;
2042
2043 FPT_sxfrp(p_port, p_card);
2044
2045 temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
2046 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2047 WR_HARPOON(p_port + hp_ee_ctrl,
2048 ((unsigned char)temp | SEE_MS | SEE_CS));
2049 WR_HARPOON(p_port + hp_ee_ctrl, temp);
2050
2051 if (!
2052 (RDW_HARPOON((p_port + hp_intstat)) &
2053 (BUS_FREE | RESET))) {
2054 FPT_phaseDecode(p_port, p_card);
2055 }
2056 }
2057 }
2058
2059 else if (p_int & RESET) {
2060
2061 WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
2062 WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
2063 if (pCurrCard->currentSCCB != NULL) {
2064
2065 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2066
2067 FPT_hostDataXferAbort(p_port, p_card,
2068 pCurrCard->currentSCCB);
2069 }
2070
2071 DISABLE_AUTO(p_port);
2072
2073 FPT_sresb(p_port, p_card);
2074
2075 while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) {
2076 }
2077
2078 pCurrNvRam = pCurrCard->pNvRamInfo;
2079 if (pCurrNvRam) {
2080 ScamFlg = pCurrNvRam->niScamConf;
2081 } else {
2082 ScamFlg =
2083 (unsigned char)FPT_utilEERead(p_port,
2084 SCAM_CONFIG / 2);
2085 }
2086
2087 FPT_XbowInit(p_port, ScamFlg);
2088
2089 FPT_scini(p_card, pCurrCard->ourId, 0);
2090
2091 return 0xFF;
2092 }
2093
2094 else if (p_int & FIFO) {
2095
2096 WRW_HARPOON((p_port + hp_intstat), FIFO);
2097
2098 if (pCurrCard->currentSCCB != NULL)
2099 FPT_sxfrp(p_port, p_card);
2100 }
2101
2102 else if (p_int & TIMEOUT) {
2103
2104 DISABLE_AUTO(p_port);
2105
2106 WRW_HARPOON((p_port + hp_intstat),
2107 (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE |
2108 IUNKWN));
2109
2110 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2111
2112 currTar_Info =
2113 &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2114 if ((pCurrCard->globalFlags & F_CONLUN_IO)
2115 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2116 TAG_Q_TRYING))
2117 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] =
2118 0;
2119 else
2120 currTar_Info->TarLUNBusy[0] = 0;
2121
2122 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2123 currTar_Info->TarSyncCtrl = 0;
2124 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2125 }
2126
2127 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2128 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2129 }
2130
2131 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,
2132 currTar_Info);
2133
2134 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2135
2136 }
2137
2138 else if (p_int & SCAM_SEL) {
2139
2140 FPT_scarb(p_port, LEVEL2_TAR);
2141 FPT_scsel(p_port);
2142 FPT_scasid(p_card, p_port);
2143
2144 FPT_scbusf(p_port);
2145
2146 WRW_HARPOON((p_port + hp_intstat), SCAM_SEL);
2147 }
2148
2149 return 0x00;
2150}
2151
2152/*---------------------------------------------------------------------
2153 *
2154 * Function: SccbMgrTableInit
2155 *
2156 * Description: Initialize all Sccb manager data structures.
2157 *
2158 *---------------------------------------------------------------------*/
2159
2160static void FPT_SccbMgrTableInitAll()
2161{
2162 unsigned char thisCard;
2163
2164 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) {
2165 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard);
2166
2167 FPT_BL_Card[thisCard].ioPort = 0x00;
2168 FPT_BL_Card[thisCard].cardInfo = NULL;
2169 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2170 FPT_BL_Card[thisCard].ourId = 0x00;
2171 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2172 }
2173}
2174
2175/*---------------------------------------------------------------------
2176 *
2177 * Function: SccbMgrTableInit
2178 *
2179 * Description: Initialize all Sccb manager data structures.
2180 *
2181 *---------------------------------------------------------------------*/
2182
2183static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
2184 unsigned char p_card)
2185{
2186 unsigned char scsiID, qtag;
2187
2188 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2189 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2190 }
2191
2192 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
2193 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2194 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2195 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2196 }
2197
2198 pCurrCard->scanIndex = 0x00;
2199 pCurrCard->currentSCCB = NULL;
2200 pCurrCard->globalFlags = 0x00;
2201 pCurrCard->cmdCounter = 0x00;
2202 pCurrCard->tagQ_Lst = 0x01;
2203 pCurrCard->discQCount = 0;
2204
2205}
2206
2207/*---------------------------------------------------------------------
2208 *
2209 * Function: SccbMgrTableInit
2210 *
2211 * Description: Initialize all Sccb manager data structures.
2212 *
2213 *---------------------------------------------------------------------*/
2214
2215static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
2216 unsigned char target)
2217{
2218
2219 unsigned char lun, qtag;
2220 struct sccb_mgr_tar_info *currTar_Info;
2221
2222 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2223
2224 currTar_Info->TarSelQ_Cnt = 0;
2225 currTar_Info->TarSyncCtrl = 0;
2226
2227 currTar_Info->TarSelQ_Head = NULL;
2228 currTar_Info->TarSelQ_Tail = NULL;
2229 currTar_Info->TarTagQ_Cnt = 0;
2230 currTar_Info->TarLUN_CA = 0;
2231
2232 for (lun = 0; lun < MAX_LUN; lun++) {
2233 currTar_Info->TarLUNBusy[lun] = 0;
2234 currTar_Info->LunDiscQ_Idx[lun] = 0;
2235 }
2236
2237 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2238 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) {
2239 if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
2240 target) {
2241 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2242 FPT_BL_Card[p_card].discQCount--;
2243 }
2244 }
2245 }
2246}
2247
2248/*---------------------------------------------------------------------
2249 *
2250 * Function: sfetm
2251 *
2252 * Description: Read in a message byte from the SCSI bus, and check
2253 * for a parity error.
2254 *
2255 *---------------------------------------------------------------------*/
2256
2257static unsigned char FPT_sfm(unsigned long port, struct sccb *pCurrSCCB)
2258{
2259 unsigned char message;
2260 unsigned short TimeOutLoop;
2261
2262 TimeOutLoop = 0;
2263 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2264 (TimeOutLoop++ < 20000)) {
2265 }
2266
2267 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2268
2269 message = RD_HARPOON(port + hp_scsidata_0);
2270
2271 WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH);
2272
2273 if (TimeOutLoop > 20000)
2274 message = 0x00; /* force message byte = 0 if Time Out on Req */
2275
2276 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
2277 (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) {
2278 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2279 WR_HARPOON(port + hp_xferstat, 0);
2280 WR_HARPOON(port + hp_fiforead, 0);
2281 WR_HARPOON(port + hp_fifowrite, 0);
2282 if (pCurrSCCB != NULL) {
2283 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2284 }
2285 message = 0x00;
2286 do {
2287 ACCEPT_MSG_ATN(port);
2288 TimeOutLoop = 0;
2289 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2290 (TimeOutLoop++ < 20000)) {
2291 }
2292 if (TimeOutLoop > 20000) {
2293 WRW_HARPOON((port + hp_intstat), PARITY);
2294 return message;
2295 }
2296 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) !=
2297 S_MSGI_PH) {
2298 WRW_HARPOON((port + hp_intstat), PARITY);
2299 return message;
2300 }
2301 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2302
2303 RD_HARPOON(port + hp_scsidata_0);
2304
2305 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2306
2307 } while (1);
2308
2309 }
2310 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2311 WR_HARPOON(port + hp_xferstat, 0);
2312 WR_HARPOON(port + hp_fiforead, 0);
2313 WR_HARPOON(port + hp_fifowrite, 0);
2314 return message;
2315}
2316
2317/*---------------------------------------------------------------------
2318 *
2319 * Function: FPT_ssel
2320 *
2321 * Description: Load up automation and select target device.
2322 *
2323 *---------------------------------------------------------------------*/
2324
2325static void FPT_ssel(unsigned long port, unsigned char p_card)
2326{
2327
2328 unsigned char auto_loaded, i, target, *theCCB;
2329
2330 unsigned long cdb_reg;
2331 struct sccb_card *CurrCard;
2332 struct sccb *currSCCB;
2333 struct sccb_mgr_tar_info *currTar_Info;
2334 unsigned char lastTag, lun;
2335
2336 CurrCard = &FPT_BL_Card[p_card];
2337 currSCCB = CurrCard->currentSCCB;
2338 target = currSCCB->TargID;
2339 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2340 lastTag = CurrCard->tagQ_Lst;
2341
2342 ARAM_ACCESS(port);
2343
2344 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2345 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2346
2347 if (((CurrCard->globalFlags & F_CONLUN_IO) &&
2348 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2349
2350 lun = currSCCB->Lun;
2351 else
2352 lun = 0;
2353
2354 if (CurrCard->globalFlags & F_TAG_STARTED) {
2355 if (!(currSCCB->ControlByte & F_USE_CMD_Q)) {
2356 if ((currTar_Info->TarLUN_CA == 0)
2357 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2358 == TAG_Q_TRYING)) {
2359
2360 if (currTar_Info->TarTagQ_Cnt != 0) {
2361 currTar_Info->TarLUNBusy[lun] = 1;
2362 FPT_queueSelectFail(CurrCard, p_card);
2363 SGRAM_ACCESS(port);
2364 return;
2365 }
2366
2367 else {
2368 currTar_Info->TarLUNBusy[lun] = 1;
2369 }
2370
2371 }
2372 /*End non-tagged */
2373 else {
2374 currTar_Info->TarLUNBusy[lun] = 1;
2375 }
2376
2377 }
2378 /*!Use cmd Q Tagged */
2379 else {
2380 if (currTar_Info->TarLUN_CA == 1) {
2381 FPT_queueSelectFail(CurrCard, p_card);
2382 SGRAM_ACCESS(port);
2383 return;
2384 }
2385
2386 currTar_Info->TarLUNBusy[lun] = 1;
2387
2388 } /*else use cmd Q tagged */
2389
2390 }
2391 /*if glob tagged started */
2392 else {
2393 currTar_Info->TarLUNBusy[lun] = 1;
2394 }
2395
2396 if ((((CurrCard->globalFlags & F_CONLUN_IO) &&
2397 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2398 || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) {
2399 if (CurrCard->discQCount >= QUEUE_DEPTH) {
2400 currTar_Info->TarLUNBusy[lun] = 1;
2401 FPT_queueSelectFail(CurrCard, p_card);
2402 SGRAM_ACCESS(port);
2403 return;
2404 }
2405 for (i = 1; i < QUEUE_DEPTH; i++) {
2406 if (++lastTag >= QUEUE_DEPTH)
2407 lastTag = 1;
2408 if (CurrCard->discQ_Tbl[lastTag] == NULL) {
2409 CurrCard->tagQ_Lst = lastTag;
2410 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2411 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2412 CurrCard->discQCount++;
2413 break;
2414 }
2415 }
2416 if (i == QUEUE_DEPTH) {
2417 currTar_Info->TarLUNBusy[lun] = 1;
2418 FPT_queueSelectFail(CurrCard, p_card);
2419 SGRAM_ACCESS(port);
2420 return;
2421 }
2422 }
2423
2424 auto_loaded = 0;
2425
2426 WR_HARPOON(port + hp_select_id, target);
2427 WR_HARPOON(port + hp_gp_reg_3, target); /* Use by new automation logic */
2428
2429 if (currSCCB->OperationCode == RESET_COMMAND) {
2430 WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2431 (currSCCB->
2432 Sccb_idmsg & ~DISC_PRIV)));
2433
2434 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
2435
2436 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2437
2438 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2439 auto_loaded = 1;
2440 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2441
2442 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2443 currTar_Info->TarSyncCtrl = 0;
2444 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2445 }
2446
2447 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2448 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2449 }
2450
2451 FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info);
2452 FPT_SccbMgrTableInitTarget(p_card, target);
2453
2454 }
2455
2456 else if (currSCCB->Sccb_scsistat == ABORT_ST) {
2457 WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2458 (currSCCB->
2459 Sccb_idmsg & ~DISC_PRIV)));
2460
2461 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
2462
2463 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT +
2464 (((unsigned
2465 char)(currSCCB->
2466 ControlByte &
2467 TAG_TYPE_MASK)
2468 >> 6) | (unsigned char)
2469 0x20)));
2470 WRW_HARPOON((port + SYNC_MSGS + 2),
2471 (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag));
2472 WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP));
2473
2474 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2475 auto_loaded = 1;
2476
2477 }
2478
2479 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2480 auto_loaded = FPT_siwidn(port, p_card);
2481 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2482 }
2483
2484 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2485 == SYNC_SUPPORTED)) {
2486 auto_loaded = FPT_sisyncn(port, p_card, 0);
2487 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2488 }
2489
2490 if (!auto_loaded) {
2491
2492 if (currSCCB->ControlByte & F_USE_CMD_Q) {
2493
2494 CurrCard->globalFlags |= F_TAG_STARTED;
2495
2496 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2497 == TAG_Q_REJECT) {
2498 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2499
2500 /* Fix up the start instruction with a jump to
2501 Non-Tag-CMD handling */
2502 WRW_HARPOON((port + ID_MSG_STRT),
2503 BRH_OP + ALWAYS + NTCMD);
2504
2505 WRW_HARPOON((port + NON_TAG_ID_MSG),
2506 (MPM_OP + AMSG_OUT +
2507 currSCCB->Sccb_idmsg));
2508
2509 WR_HARPOON(port + hp_autostart_3,
2510 (SELECT + SELCHK_STRT));
2511
2512 /* Setup our STATE so we know what happened when
2513 the wheels fall off. */
2514 currSCCB->Sccb_scsistat = SELECT_ST;
2515
2516 currTar_Info->TarLUNBusy[lun] = 1;
2517 }
2518
2519 else {
2520 WRW_HARPOON((port + ID_MSG_STRT),
2521 (MPM_OP + AMSG_OUT +
2522 currSCCB->Sccb_idmsg));
2523
2524 WRW_HARPOON((port + ID_MSG_STRT + 2),
2525 (MPM_OP + AMSG_OUT +
2526 (((unsigned char)(currSCCB->
2527 ControlByte &
2528 TAG_TYPE_MASK)
2529 >> 6) | (unsigned char)0x20)));
2530
2531 for (i = 1; i < QUEUE_DEPTH; i++) {
2532 if (++lastTag >= QUEUE_DEPTH)
2533 lastTag = 1;
2534 if (CurrCard->discQ_Tbl[lastTag] ==
2535 NULL) {
2536 WRW_HARPOON((port +
2537 ID_MSG_STRT + 6),
2538 (MPM_OP + AMSG_OUT +
2539 lastTag));
2540 CurrCard->tagQ_Lst = lastTag;
2541 currSCCB->Sccb_tag = lastTag;
2542 CurrCard->discQ_Tbl[lastTag] =
2543 currSCCB;
2544 CurrCard->discQCount++;
2545 break;
2546 }
2547 }
2548
2549 if (i == QUEUE_DEPTH) {
2550 currTar_Info->TarLUNBusy[lun] = 1;
2551 FPT_queueSelectFail(CurrCard, p_card);
2552 SGRAM_ACCESS(port);
2553 return;
2554 }
2555
2556 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2557
2558 WR_HARPOON(port + hp_autostart_3,
2559 (SELECT + SELCHK_STRT));
2560 }
2561 }
2562
2563 else {
2564
2565 WRW_HARPOON((port + ID_MSG_STRT),
2566 BRH_OP + ALWAYS + NTCMD);
2567
2568 WRW_HARPOON((port + NON_TAG_ID_MSG),
2569 (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg));
2570
2571 currSCCB->Sccb_scsistat = SELECT_ST;
2572
2573 WR_HARPOON(port + hp_autostart_3,
2574 (SELECT + SELCHK_STRT));
2575 }
2576
2577 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2578
2579 cdb_reg = port + CMD_STRT;
2580
2581 for (i = 0; i < currSCCB->CdbLength; i++) {
2582 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2583 cdb_reg += 2;
2584 theCCB++;
2585 }
2586
2587 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2588 WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
2589
2590 }
2591 /* auto_loaded */
2592 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2593 WR_HARPOON(port + hp_xferstat, 0x00);
2594
2595 WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2596
2597 WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT));
2598
2599 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) {
2600 WR_HARPOON(port + hp_scsictrl_0,
2601 (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2602 } else {
2603
2604/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2605 auto_loaded |= AUTO_IMMED; */
2606 auto_loaded = AUTO_IMMED;
2607
2608 DISABLE_AUTO(port);
2609
2610 WR_HARPOON(port + hp_autostart_3, auto_loaded);
2611 }
2612
2613 SGRAM_ACCESS(port);
2614}
2615
2616/*---------------------------------------------------------------------
2617 *
2618 * Function: FPT_sres
2619 *
2620 * Description: Hookup the correct CCB and handle the incoming messages.
2621 *
2622 *---------------------------------------------------------------------*/
2623
2624static void FPT_sres(unsigned long port, unsigned char p_card,
2625 struct sccb_card *pCurrCard)
2626{
2627
2628 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2629
2630 struct sccb_mgr_tar_info *currTar_Info;
2631 struct sccb *currSCCB;
2632
2633 if (pCurrCard->currentSCCB != NULL) {
2634 currTar_Info =
2635 &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2636 DISABLE_AUTO(port);
2637
2638 WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL));
2639
2640 currSCCB = pCurrCard->currentSCCB;
2641 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
2642 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2643 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2644 }
2645 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2646 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2647 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2648 }
2649 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2650 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2651 TAG_Q_TRYING))) {
2652 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2653 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2654 pCurrCard->discQCount--;
2655 pCurrCard->discQ_Tbl[currTar_Info->
2656 LunDiscQ_Idx[currSCCB->
2657 Lun]]
2658 = NULL;
2659 }
2660 } else {
2661 currTar_Info->TarLUNBusy[0] = 0;
2662 if (currSCCB->Sccb_tag) {
2663 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2664 pCurrCard->discQCount--;
2665 pCurrCard->discQ_Tbl[currSCCB->
2666 Sccb_tag] = NULL;
2667 }
2668 } else {
2669 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2670 pCurrCard->discQCount--;
2671 pCurrCard->discQ_Tbl[currTar_Info->
2672 LunDiscQ_Idx[0]] =
2673 NULL;
2674 }
2675 }
2676 }
2677
2678 FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
2679 }
2680
2681 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2682
2683 our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4);
2684 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2685
2686 msgRetryCount = 0;
2687 do {
2688
2689 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2690 tag = 0;
2691
2692 while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2693 if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2694
2695 WRW_HARPOON((port + hp_intstat), PHASE);
2696 return;
2697 }
2698 }
2699
2700 WRW_HARPOON((port + hp_intstat), PHASE);
2701 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) {
2702
2703 message = FPT_sfm(port, pCurrCard->currentSCCB);
2704 if (message) {
2705
2706 if (message <= (0x80 | LUN_MASK)) {
2707 lun = message & (unsigned char)LUN_MASK;
2708
2709 if ((currTar_Info->
2710 TarStatus & TAR_TAG_Q_MASK) ==
2711 TAG_Q_TRYING) {
2712 if (currTar_Info->TarTagQ_Cnt !=
2713 0) {
2714
2715 if (!
2716 (currTar_Info->
2717 TarLUN_CA)) {
2718 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2719
2720 message =
2721 FPT_sfm
2722 (port,
2723 pCurrCard->
2724 currentSCCB);
2725 if (message) {
2726 ACCEPT_MSG
2727 (port);
2728 }
2729
2730 else
2731 message
2732 = 0;
2733
2734 if (message !=
2735 0) {
2736 tag =
2737 FPT_sfm
2738 (port,
2739 pCurrCard->
2740 currentSCCB);
2741
2742 if (!
2743 (tag))
2744 message
2745 =
2746 0;
2747 }
2748
2749 }
2750 /*C.A. exists! */
2751 }
2752 /*End Q cnt != 0 */
2753 }
2754 /*End Tag cmds supported! */
2755 }
2756 /*End valid ID message. */
2757 else {
2758
2759 ACCEPT_MSG_ATN(port);
2760 }
2761
2762 }
2763 /* End good id message. */
2764 else {
2765
2766 message = 0;
2767 }
2768 } else {
2769 ACCEPT_MSG_ATN(port);
2770
2771 while (!
2772 (RDW_HARPOON((port + hp_intstat)) &
2773 (PHASE | RESET))
2774 && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
2775 && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2776
2777 return;
2778 }
2779
2780 if (message == 0) {
2781 msgRetryCount++;
2782 if (msgRetryCount == 1) {
2783 FPT_SendMsg(port, SMPARITY);
2784 } else {
2785 FPT_SendMsg(port, SMDEV_RESET);
2786
2787 FPT_sssyncv(port, our_target, NARROW_SCSI,
2788 currTar_Info);
2789
2790 if (FPT_sccbMgrTbl[p_card][our_target].
2791 TarEEValue & EE_SYNC_MASK) {
2792
2793 FPT_sccbMgrTbl[p_card][our_target].
2794 TarStatus &= ~TAR_SYNC_MASK;
2795
2796 }
2797
2798 if (FPT_sccbMgrTbl[p_card][our_target].
2799 TarEEValue & EE_WIDE_SCSI) {
2800
2801 FPT_sccbMgrTbl[p_card][our_target].
2802 TarStatus &= ~TAR_WIDE_MASK;
2803 }
2804
2805 FPT_queueFlushTargSccb(p_card, our_target,
2806 SCCB_COMPLETE);
2807 FPT_SccbMgrTableInitTarget(p_card, our_target);
2808 return;
2809 }
2810 }
2811 } while (message == 0);
2812
2813 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2814 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
2815 currTar_Info->TarLUNBusy[lun] = 1;
2816 pCurrCard->currentSCCB =
2817 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
2818 if (pCurrCard->currentSCCB != NULL) {
2819 ACCEPT_MSG(port);
2820 } else {
2821 ACCEPT_MSG_ATN(port);
2822 }
2823 } else {
2824 currTar_Info->TarLUNBusy[0] = 1;
2825
2826 if (tag) {
2827 if (pCurrCard->discQ_Tbl[tag] != NULL) {
2828 pCurrCard->currentSCCB =
2829 pCurrCard->discQ_Tbl[tag];
2830 currTar_Info->TarTagQ_Cnt--;
2831 ACCEPT_MSG(port);
2832 } else {
2833 ACCEPT_MSG_ATN(port);
2834 }
2835 } else {
2836 pCurrCard->currentSCCB =
2837 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
2838 if (pCurrCard->currentSCCB != NULL) {
2839 ACCEPT_MSG(port);
2840 } else {
2841 ACCEPT_MSG_ATN(port);
2842 }
2843 }
2844 }
2845
2846 if (pCurrCard->currentSCCB != NULL) {
2847 if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) {
2848 /* During Abort Tag command, the target could have got re-selected
2849 and completed the command. Check the select Q and remove the CCB
2850 if it is in the Select Q */
2851 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
2852 }
2853 }
2854
2855 while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) &&
2856 !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) &&
2857 (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2858}
2859
2860static void FPT_SendMsg(unsigned long port, unsigned char message)
2861{
2862 while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2863 if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2864
2865 WRW_HARPOON((port + hp_intstat), PHASE);
2866 return;
2867 }
2868 }
2869
2870 WRW_HARPOON((port + hp_intstat), PHASE);
2871 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) {
2872 WRW_HARPOON((port + hp_intstat),
2873 (BUS_FREE | PHASE | XFER_CNT_0));
2874
2875 WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
2876
2877 WR_HARPOON(port + hp_scsidata_0, message);
2878
2879 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2880
2881 ACCEPT_MSG(port);
2882
2883 WR_HARPOON(port + hp_portctrl_0, 0x00);
2884
2885 if ((message == SMABORT) || (message == SMDEV_RESET) ||
2886 (message == SMABORT_TAG)) {
2887 while (!
2888 (RDW_HARPOON((port + hp_intstat)) &
2889 (BUS_FREE | PHASE))) {
2890 }
2891
2892 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2893 WRW_HARPOON((port + hp_intstat), BUS_FREE);
2894 }
2895 }
2896 }
2897}
2898
2899/*---------------------------------------------------------------------
2900 *
2901 * Function: FPT_sdecm
2902 *
2903 * Description: Determine the proper response to the message from the
2904 * target device.
2905 *
2906 *---------------------------------------------------------------------*/
2907static void FPT_sdecm(unsigned char message, unsigned long port,
2908 unsigned char p_card)
2909{
2910 struct sccb *currSCCB;
2911 struct sccb_card *CurrCard;
2912 struct sccb_mgr_tar_info *currTar_Info;
2913
2914 CurrCard = &FPT_BL_Card[p_card];
2915 currSCCB = CurrCard->currentSCCB;
2916
2917 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
2918
2919 if (message == SMREST_DATA_PTR) {
2920 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) {
2921 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
2922
2923 FPT_hostDataXferRestart(currSCCB);
2924 }
2925
2926 ACCEPT_MSG(port);
2927 WR_HARPOON(port + hp_autostart_1,
2928 (AUTO_IMMED + DISCONNECT_START));
2929 }
2930
2931 else if (message == SMCMD_COMP) {
2932
2933 if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
2934 currTar_Info->TarStatus &=
2935 ~(unsigned char)TAR_TAG_Q_MASK;
2936 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
2937 }
2938
2939 ACCEPT_MSG(port);
2940
2941 }
2942
2943 else if ((message == SMNO_OP) || (message >= SMIDENT)
2944 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY)) {
2945
2946 ACCEPT_MSG(port);
2947 WR_HARPOON(port + hp_autostart_1,
2948 (AUTO_IMMED + DISCONNECT_START));
2949 }
2950
2951 else if (message == SMREJECT) {
2952
2953 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
2954 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
2955 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)
2956 || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) ==
2957 TAG_Q_TRYING))
2958 {
2959 WRW_HARPOON((port + hp_intstat), BUS_FREE);
2960
2961 ACCEPT_MSG(port);
2962
2963 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2964 (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
2965 {
2966 }
2967
2968 if (currSCCB->Lun == 0x00) {
2969 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST)) {
2970
2971 currTar_Info->TarStatus |=
2972 (unsigned char)SYNC_SUPPORTED;
2973
2974 currTar_Info->TarEEValue &=
2975 ~EE_SYNC_MASK;
2976 }
2977
2978 else if ((currSCCB->Sccb_scsistat ==
2979 SELECT_WN_ST)) {
2980
2981 currTar_Info->TarStatus =
2982 (currTar_Info->
2983 TarStatus & ~WIDE_ENABLED) |
2984 WIDE_NEGOCIATED;
2985
2986 currTar_Info->TarEEValue &=
2987 ~EE_WIDE_SCSI;
2988
2989 }
2990
2991 else if ((currTar_Info->
2992 TarStatus & TAR_TAG_Q_MASK) ==
2993 TAG_Q_TRYING) {
2994 currTar_Info->TarStatus =
2995 (currTar_Info->
2996 TarStatus & ~(unsigned char)
2997 TAR_TAG_Q_MASK) | TAG_Q_REJECT;
2998
2999 currSCCB->ControlByte &= ~F_USE_CMD_Q;
3000 CurrCard->discQCount--;
3001 CurrCard->discQ_Tbl[currSCCB->
3002 Sccb_tag] = NULL;
3003 currSCCB->Sccb_tag = 0x00;
3004
3005 }
3006 }
3007
3008 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
3009
3010 if (currSCCB->Lun == 0x00) {
3011 WRW_HARPOON((port + hp_intstat),
3012 BUS_FREE);
3013 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
3014 }
3015 }
3016
3017 else {
3018
3019 if ((CurrCard->globalFlags & F_CONLUN_IO) &&
3020 ((currTar_Info->
3021 TarStatus & TAR_TAG_Q_MASK) !=
3022 TAG_Q_TRYING))
3023 currTar_Info->TarLUNBusy[currSCCB->
3024 Lun] = 1;
3025 else
3026 currTar_Info->TarLUNBusy[0] = 1;
3027
3028 currSCCB->ControlByte &=
3029 ~(unsigned char)F_USE_CMD_Q;
3030
3031 WR_HARPOON(port + hp_autostart_1,
3032 (AUTO_IMMED + DISCONNECT_START));
3033
3034 }
3035 }
3036
3037 else {
3038 ACCEPT_MSG(port);
3039
3040 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
3041 (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
3042 {
3043 }
3044
3045 if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) {
3046 WR_HARPOON(port + hp_autostart_1,
3047 (AUTO_IMMED + DISCONNECT_START));
3048 }
3049 }
3050 }
3051
3052 else if (message == SMEXT) {
3053
3054 ACCEPT_MSG(port);
3055 FPT_shandem(port, p_card, currSCCB);
3056 }
3057
3058 else if (message == SMIGNORWR) {
3059
3060 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3061
3062 message = FPT_sfm(port, currSCCB);
3063
3064 if (currSCCB->Sccb_scsimsg != SMPARITY)
3065 ACCEPT_MSG(port);
3066 WR_HARPOON(port + hp_autostart_1,
3067 (AUTO_IMMED + DISCONNECT_START));
3068 }
3069
3070 else {
3071
3072 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3073 currSCCB->Sccb_scsimsg = SMREJECT;
3074
3075 ACCEPT_MSG_ATN(port);
3076 WR_HARPOON(port + hp_autostart_1,
3077 (AUTO_IMMED + DISCONNECT_START));
3078 }
3079}
3080
3081/*---------------------------------------------------------------------
3082 *
3083 * Function: FPT_shandem
3084 *
3085 * Description: Decide what to do with the extended message.
3086 *
3087 *---------------------------------------------------------------------*/
3088static void FPT_shandem(unsigned long port, unsigned char p_card,
3089 struct sccb *pCurrSCCB)
3090{
3091 unsigned char length, message;
3092
3093 length = FPT_sfm(port, pCurrSCCB);
3094 if (length) {
3095
3096 ACCEPT_MSG(port);
3097 message = FPT_sfm(port, pCurrSCCB);
3098 if (message) {
3099
3100 if (message == SMSYNC) {
3101
3102 if (length == 0x03) {
3103
3104 ACCEPT_MSG(port);
3105 FPT_stsyncn(port, p_card);
3106 } else {
3107
3108 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3109 ACCEPT_MSG_ATN(port);
3110 }
3111 } else if (message == SMWDTR) {
3112
3113 if (length == 0x02) {
3114
3115 ACCEPT_MSG(port);
3116 FPT_stwidn(port, p_card);
3117 } else {
3118
3119 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3120 ACCEPT_MSG_ATN(port);
3121
3122 WR_HARPOON(port + hp_autostart_1,
3123 (AUTO_IMMED +
3124 DISCONNECT_START));
3125 }
3126 } else {
3127
3128 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3129 ACCEPT_MSG_ATN(port);
3130
3131 WR_HARPOON(port + hp_autostart_1,
3132 (AUTO_IMMED + DISCONNECT_START));
3133 }
3134 } else {
3135 if (pCurrSCCB->Sccb_scsimsg != SMPARITY)
3136 ACCEPT_MSG(port);
3137 WR_HARPOON(port + hp_autostart_1,
3138 (AUTO_IMMED + DISCONNECT_START));
3139 }
3140 } else {
3141 if (pCurrSCCB->Sccb_scsimsg == SMPARITY)
3142 WR_HARPOON(port + hp_autostart_1,
3143 (AUTO_IMMED + DISCONNECT_START));
3144 }
3145}
3146
3147/*---------------------------------------------------------------------
3148 *
3149 * Function: FPT_sisyncn
3150 *
3151 * Description: Read in a message byte from the SCSI bus, and check
3152 * for a parity error.
3153 *
3154 *---------------------------------------------------------------------*/
3155
3156static unsigned char FPT_sisyncn(unsigned long port, unsigned char p_card,
3157 unsigned char syncFlag)
3158{
3159 struct sccb *currSCCB;
3160 struct sccb_mgr_tar_info *currTar_Info;
3161
3162 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3163 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3164
3165 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3166
3167 WRW_HARPOON((port + ID_MSG_STRT),
3168 (MPM_OP + AMSG_OUT +
3169 (currSCCB->
3170 Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3171
3172 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3173
3174 WRW_HARPOON((port + SYNC_MSGS + 0),
3175 (MPM_OP + AMSG_OUT + SMEXT));
3176 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3177 WRW_HARPOON((port + SYNC_MSGS + 4),
3178 (MPM_OP + AMSG_OUT + SMSYNC));
3179
3180 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3181
3182 WRW_HARPOON((port + SYNC_MSGS + 6),
3183 (MPM_OP + AMSG_OUT + 12));
3184
3185 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3186 EE_SYNC_10MB)
3187
3188 WRW_HARPOON((port + SYNC_MSGS + 6),
3189 (MPM_OP + AMSG_OUT + 25));
3190
3191 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3192 EE_SYNC_5MB)
3193
3194 WRW_HARPOON((port + SYNC_MSGS + 6),
3195 (MPM_OP + AMSG_OUT + 50));
3196
3197 else
3198 WRW_HARPOON((port + SYNC_MSGS + 6),
3199 (MPM_OP + AMSG_OUT + 00));
3200
3201 WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3202 WRW_HARPOON((port + SYNC_MSGS + 10),
3203 (MPM_OP + AMSG_OUT + DEFAULT_OFFSET));
3204 WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3205
3206 if (syncFlag == 0) {
3207 WR_HARPOON(port + hp_autostart_3,
3208 (SELECT + SELCHK_STRT));
3209 currTar_Info->TarStatus =
3210 ((currTar_Info->
3211 TarStatus & ~(unsigned char)TAR_SYNC_MASK) |
3212 (unsigned char)SYNC_TRYING);
3213 } else {
3214 WR_HARPOON(port + hp_autostart_3,
3215 (AUTO_IMMED + CMD_ONLY_STRT));
3216 }
3217
3218 return 1;
3219 }
3220
3221 else {
3222
3223 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3224 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3225 return 0;
3226 }
3227}
3228
3229/*---------------------------------------------------------------------
3230 *
3231 * Function: FPT_stsyncn
3232 *
3233 * Description: The has sent us a Sync Nego message so handle it as
3234 * necessary.
3235 *
3236 *---------------------------------------------------------------------*/
3237static void FPT_stsyncn(unsigned long port, unsigned char p_card)
3238{
3239 unsigned char sync_msg, offset, sync_reg, our_sync_msg;
3240 struct sccb *currSCCB;
3241 struct sccb_mgr_tar_info *currTar_Info;
3242
3243 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3244 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3245
3246 sync_msg = FPT_sfm(port, currSCCB);
3247
3248 if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3249 WR_HARPOON(port + hp_autostart_1,
3250 (AUTO_IMMED + DISCONNECT_START));
3251 return;
3252 }
3253
3254 ACCEPT_MSG(port);
3255
3256 offset = FPT_sfm(port, currSCCB);
3257
3258 if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3259 WR_HARPOON(port + hp_autostart_1,
3260 (AUTO_IMMED + DISCONNECT_START));
3261 return;
3262 }
3263
3264 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3265
3266 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3267
3268 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3269
3270 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3271
3272 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3273
3274 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3275 else
3276
3277 our_sync_msg = 0; /* Message = Async */
3278
3279 if (sync_msg < our_sync_msg) {
3280 sync_msg = our_sync_msg; /*if faster, then set to max. */
3281 }
3282
3283 if (offset == ASYNC)
3284 sync_msg = ASYNC;
3285
3286 if (offset > MAX_OFFSET)
3287 offset = MAX_OFFSET;
3288
3289 sync_reg = 0x00;
3290
3291 if (sync_msg > 12)
3292
3293 sync_reg = 0x20; /* Use 10MB/s */
3294
3295 if (sync_msg > 25)
3296
3297 sync_reg = 0x40; /* Use 6.6MB/s */
3298
3299 if (sync_msg > 38)
3300
3301 sync_reg = 0x60; /* Use 5MB/s */
3302
3303 if (sync_msg > 50)
3304
3305 sync_reg = 0x80; /* Use 4MB/s */
3306
3307 if (sync_msg > 62)
3308
3309 sync_reg = 0xA0; /* Use 3.33MB/s */
3310
3311 if (sync_msg > 75)
3312
3313 sync_reg = 0xC0; /* Use 2.85MB/s */
3314
3315 if (sync_msg > 87)
3316
3317 sync_reg = 0xE0; /* Use 2.5MB/s */
3318
3319 if (sync_msg > 100) {
3320
3321 sync_reg = 0x00; /* Use ASYNC */
3322 offset = 0x00;
3323 }
3324
3325 if (currTar_Info->TarStatus & WIDE_ENABLED)
3326
3327 sync_reg |= offset;
3328
3329 else
3330
3331 sync_reg |= (offset | NARROW_SCSI);
3332
3333 FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info);
3334
3335 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3336
3337 ACCEPT_MSG(port);
3338
3339 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3340 ~(unsigned char)TAR_SYNC_MASK) |
3341 (unsigned char)SYNC_SUPPORTED);
3342
3343 WR_HARPOON(port + hp_autostart_1,
3344 (AUTO_IMMED + DISCONNECT_START));
3345 }
3346
3347 else {
3348
3349 ACCEPT_MSG_ATN(port);
3350
3351 FPT_sisyncr(port, sync_msg, offset);
3352
3353 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3354 ~(unsigned char)TAR_SYNC_MASK) |
3355 (unsigned char)SYNC_SUPPORTED);
3356 }
3357}
3358
3359/*---------------------------------------------------------------------
3360 *
3361 * Function: FPT_sisyncr
3362 *
3363 * Description: Answer the targets sync message.
3364 *
3365 *---------------------------------------------------------------------*/
3366static void FPT_sisyncr(unsigned long port, unsigned char sync_pulse,
3367 unsigned char offset)
3368{
3369 ARAM_ACCESS(port);
3370 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
3371 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3372 WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMSYNC));
3373 WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse));
3374 WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3375 WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset));
3376 WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3377 SGRAM_ACCESS(port);
3378
3379 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3380 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3381
3382 WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3383
3384 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3385 }
3386}
3387
3388/*---------------------------------------------------------------------
3389 *
3390 * Function: FPT_siwidn
3391 *
3392 * Description: Read in a message byte from the SCSI bus, and check
3393 * for a parity error.
3394 *
3395 *---------------------------------------------------------------------*/
3396
3397static unsigned char FPT_siwidn(unsigned long port, unsigned char p_card)
3398{
3399 struct sccb *currSCCB;
3400 struct sccb_mgr_tar_info *currTar_Info;
3401
3402 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3403 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3404
3405 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3406
3407 WRW_HARPOON((port + ID_MSG_STRT),
3408 (MPM_OP + AMSG_OUT +
3409 (currSCCB->
3410 Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3411
3412 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3413
3414 WRW_HARPOON((port + SYNC_MSGS + 0),
3415 (MPM_OP + AMSG_OUT + SMEXT));
3416 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3417 WRW_HARPOON((port + SYNC_MSGS + 4),
3418 (MPM_OP + AMSG_OUT + SMWDTR));
3419 WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3420 WRW_HARPOON((port + SYNC_MSGS + 8),
3421 (MPM_OP + AMSG_OUT + SM16BIT));
3422 WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3423
3424 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
3425
3426 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3427 ~(unsigned char)TAR_WIDE_MASK) |
3428 (unsigned char)WIDE_ENABLED);
3429
3430 return 1;
3431 }
3432
3433 else {
3434
3435 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3436 ~(unsigned char)TAR_WIDE_MASK) |
3437 WIDE_NEGOCIATED);
3438
3439 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3440 return 0;
3441 }
3442}
3443
3444/*---------------------------------------------------------------------
3445 *
3446 * Function: FPT_stwidn
3447 *
3448 * Description: The has sent us a Wide Nego message so handle it as
3449 * necessary.
3450 *
3451 *---------------------------------------------------------------------*/
3452static void FPT_stwidn(unsigned long port, unsigned char p_card)
3453{
3454 unsigned char width;
3455 struct sccb *currSCCB;
3456 struct sccb_mgr_tar_info *currTar_Info;
3457
3458 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3459 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3460
3461 width = FPT_sfm(port, currSCCB);
3462
3463 if ((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3464 WR_HARPOON(port + hp_autostart_1,
3465 (AUTO_IMMED + DISCONNECT_START));
3466 return;
3467 }
3468
3469 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3470 width = 0;
3471
3472 if (width) {
3473 currTar_Info->TarStatus |= WIDE_ENABLED;
3474 width = 0;
3475 } else {
3476 width = NARROW_SCSI;
3477 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3478 }
3479
3480 FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info);
3481
3482 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
3483
3484 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3485
3486 if (!
3487 ((currTar_Info->TarStatus & TAR_SYNC_MASK) ==
3488 SYNC_SUPPORTED)) {
3489 ACCEPT_MSG_ATN(port);
3490 ARAM_ACCESS(port);
3491 FPT_sisyncn(port, p_card, 1);
3492 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3493 SGRAM_ACCESS(port);
3494 } else {
3495 ACCEPT_MSG(port);
3496 WR_HARPOON(port + hp_autostart_1,
3497 (AUTO_IMMED + DISCONNECT_START));
3498 }
3499 }
3500
3501 else {
3502
3503 ACCEPT_MSG_ATN(port);
3504
3505 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3506 width = SM16BIT;
3507 else
3508 width = SM8BIT;
3509
3510 FPT_siwidr(port, width);
3511
3512 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3513 }
3514}
3515
3516/*---------------------------------------------------------------------
3517 *
3518 * Function: FPT_siwidr
3519 *
3520 * Description: Answer the targets Wide nego message.
3521 *
3522 *---------------------------------------------------------------------*/
3523static void FPT_siwidr(unsigned long port, unsigned char width)
3524{
3525 ARAM_ACCESS(port);
3526 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
3527 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3528 WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMWDTR));
3529 WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3530 WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width));
3531 WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3532 SGRAM_ACCESS(port);
3533
3534 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3535 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3536
3537 WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3538
3539 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3540 }
3541}
3542
3543/*---------------------------------------------------------------------
3544 *
3545 * Function: FPT_sssyncv
3546 *
3547 * Description: Write the desired value to the Sync Register for the
3548 * ID specified.
3549 *
3550 *---------------------------------------------------------------------*/
3551static void FPT_sssyncv(unsigned long p_port, unsigned char p_id,
3552 unsigned char p_sync_value,
3553 struct sccb_mgr_tar_info *currTar_Info)
3554{
3555 unsigned char index;
3556
3557 index = p_id;
3558
3559 switch (index) {
3560
3561 case 0:
3562 index = 12; /* hp_synctarg_0 */
3563 break;
3564 case 1:
3565 index = 13; /* hp_synctarg_1 */
3566 break;
3567 case 2:
3568 index = 14; /* hp_synctarg_2 */
3569 break;
3570 case 3:
3571 index = 15; /* hp_synctarg_3 */
3572 break;
3573 case 4:
3574 index = 8; /* hp_synctarg_4 */
3575 break;
3576 case 5:
3577 index = 9; /* hp_synctarg_5 */
3578 break;
3579 case 6:
3580 index = 10; /* hp_synctarg_6 */
3581 break;
3582 case 7:
3583 index = 11; /* hp_synctarg_7 */
3584 break;
3585 case 8:
3586 index = 4; /* hp_synctarg_8 */
3587 break;
3588 case 9:
3589 index = 5; /* hp_synctarg_9 */
3590 break;
3591 case 10:
3592 index = 6; /* hp_synctarg_10 */
3593 break;
3594 case 11:
3595 index = 7; /* hp_synctarg_11 */
3596 break;
3597 case 12:
3598 index = 0; /* hp_synctarg_12 */
3599 break;
3600 case 13:
3601 index = 1; /* hp_synctarg_13 */
3602 break;
3603 case 14:
3604 index = 2; /* hp_synctarg_14 */
3605 break;
3606 case 15:
3607 index = 3; /* hp_synctarg_15 */
3608
3609 }
3610
3611 WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value);
3612
3613 currTar_Info->TarSyncCtrl = p_sync_value;
3614}
3615
3616/*---------------------------------------------------------------------
3617 *
3618 * Function: FPT_sresb
3619 *
3620 * Description: Reset the desired card's SCSI bus.
3621 *
3622 *---------------------------------------------------------------------*/
3623static void FPT_sresb(unsigned long port, unsigned char p_card)
3624{
3625 unsigned char scsiID, i;
3626
3627 struct sccb_mgr_tar_info *currTar_Info;
3628
3629 WR_HARPOON(port + hp_page_ctrl,
3630 (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE));
3631 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3632
3633 WR_HARPOON(port + hp_scsictrl_0, SCSI_RST);
3634
3635 scsiID = RD_HARPOON(port + hp_seltimeout);
3636 WR_HARPOON(port + hp_seltimeout, TO_5ms);
3637 WRW_HARPOON((port + hp_intstat), TIMEOUT);
3638
3639 WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO));
3640
3641 while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) {
3642 }
3643
3644 WR_HARPOON(port + hp_seltimeout, scsiID);
3645
3646 WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
3647
3648 FPT_Wait(port, TO_5ms);
3649
3650 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3651
3652 WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00));
3653
3654 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
3655 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3656
3657 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
3658 currTar_Info->TarSyncCtrl = 0;
3659 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3660 }
3661
3662 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
3663 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3664 }
3665
3666 FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
3667
3668 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3669 }
3670
3671 FPT_BL_Card[p_card].scanIndex = 0x00;
3672 FPT_BL_Card[p_card].currentSCCB = NULL;
3673 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3674 | F_NEW_SCCB_CMD);
3675 FPT_BL_Card[p_card].cmdCounter = 0x00;
3676 FPT_BL_Card[p_card].discQCount = 0x00;
3677 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3678
3679 for (i = 0; i < QUEUE_DEPTH; i++)
3680 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3681
3682 WR_HARPOON(port + hp_page_ctrl,
3683 (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE));
3684
3685}
3686
3687/*---------------------------------------------------------------------
3688 *
3689 * Function: FPT_ssenss
3690 *
3691 * Description: Setup for the Auto Sense command.
3692 *
3693 *---------------------------------------------------------------------*/
3694static void FPT_ssenss(struct sccb_card *pCurrCard)
3695{
3696 unsigned char i;
3697 struct sccb *currSCCB;
3698
3699 currSCCB = pCurrCard->currentSCCB;
3700
3701 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3702
3703 for (i = 0; i < 6; i++) {
3704
3705 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3706 }
3707
3708 currSCCB->CdbLength = SIX_BYTE_CMD;
3709 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3710 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3711 currSCCB->Cdb[2] = 0x00;
3712 currSCCB->Cdb[3] = 0x00;
3713 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3714 currSCCB->Cdb[5] = 0x00;
3715
3716 currSCCB->Sccb_XferCnt = (unsigned long)currSCCB->RequestSenseLength;
3717
3718 currSCCB->Sccb_ATC = 0x00;
3719
3720 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3721
3722 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3723
3724 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3725
3726 currSCCB->ControlByte = 0x00;
3727
3728 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3729}
3730
3731/*---------------------------------------------------------------------
3732 *
3733 * Function: FPT_sxfrp
3734 *
3735 * Description: Transfer data into the bit bucket until the device
3736 * decides to switch phase.
3737 *
3738 *---------------------------------------------------------------------*/
3739
3740static void FPT_sxfrp(unsigned long p_port, unsigned char p_card)
3741{
3742 unsigned char curr_phz;
3743
3744 DISABLE_AUTO(p_port);
3745
3746 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3747
3748 FPT_hostDataXferAbort(p_port, p_card,
3749 FPT_BL_Card[p_card].currentSCCB);
3750
3751 }
3752
3753 /* If the Automation handled the end of the transfer then do not
3754 match the phase or we will get out of sync with the ISR. */
3755
3756 if (RDW_HARPOON((p_port + hp_intstat)) &
3757 (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3758 return;
3759
3760 WR_HARPOON(p_port + hp_xfercnt_0, 0x00);
3761
3762 curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3763
3764 WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0);
3765
3766 WR_HARPOON(p_port + hp_scsisig, curr_phz);
3767
3768 while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) &&
3769 (curr_phz ==
3770 (RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ)))
3771 {
3772 if (curr_phz & (unsigned char)SCSI_IOBIT) {
3773 WR_HARPOON(p_port + hp_portctrl_0,
3774 (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3775
3776 if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3777 RD_HARPOON(p_port + hp_fifodata_0);
3778 }
3779 } else {
3780 WR_HARPOON(p_port + hp_portctrl_0,
3781 (SCSI_PORT | HOST_PORT | HOST_WRT));
3782 if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) {
3783 WR_HARPOON(p_port + hp_fifodata_0, 0xFA);
3784 }
3785 }
3786 } /* End of While loop for padding data I/O phase */
3787
3788 while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3789 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ)
3790 break;
3791 }
3792
3793 WR_HARPOON(p_port + hp_portctrl_0,
3794 (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3795 while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3796 RD_HARPOON(p_port + hp_fifodata_0);
3797 }
3798
3799 if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3800 WR_HARPOON(p_port + hp_autostart_0,
3801 (AUTO_IMMED + DISCONNECT_START));
3802 while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) {
3803 }
3804
3805 if (RDW_HARPOON((p_port + hp_intstat)) &
3806 (ICMD_COMP | ITAR_DISC))
3807 while (!
3808 (RDW_HARPOON((p_port + hp_intstat)) &
3809 (BUS_FREE | RSEL))) ;
3810 }
3811}
3812
3813/*---------------------------------------------------------------------
3814 *
3815 * Function: FPT_schkdd
3816 *
3817 * Description: Make sure data has been flushed from both FIFOs and abort
3818 * the operations if necessary.
3819 *
3820 *---------------------------------------------------------------------*/
3821
3822static void FPT_schkdd(unsigned long port, unsigned char p_card)
3823{
3824 unsigned short TimeOutLoop;
3825 unsigned char sPhase;
3826
3827 struct sccb *currSCCB;
3828
3829 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3830
3831 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
3832 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
3833 return;
3834 }
3835
3836 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) {
3837
3838 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1);
3839
3840 currSCCB->Sccb_XferCnt = 1;
3841
3842 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
3843 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
3844 WR_HARPOON(port + hp_xferstat, 0x00);
3845 }
3846
3847 else {
3848
3849 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
3850
3851 currSCCB->Sccb_XferCnt = 0;
3852 }
3853
3854 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
3855 (currSCCB->HostStatus == SCCB_COMPLETE)) {
3856
3857 currSCCB->HostStatus = SCCB_PARITY_ERR;
3858 WRW_HARPOON((port + hp_intstat), PARITY);
3859 }
3860
3861 FPT_hostDataXferAbort(port, p_card, currSCCB);
3862
3863 while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) {
3864 }
3865
3866 TimeOutLoop = 0;
3867
3868 while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) {
3869 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
3870 return;
3871 }
3872 if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) {
3873 break;
3874 }
3875 if (RDW_HARPOON((port + hp_intstat)) & RESET) {
3876 return;
3877 }
3878 if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
3879 || (TimeOutLoop++ > 0x3000))
3880 break;
3881 }
3882
3883 sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
3884 if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) ||
3885 (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) ||
3886 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
3887 (sPhase == (SCSI_BSY | S_DATAI_PH))) {
3888
3889 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3890
3891 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) {
3892 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
3893 FPT_phaseDataIn(port, p_card);
3894 }
3895
3896 else {
3897 FPT_phaseDataOut(port, p_card);
3898 }
3899 } else {
3900 FPT_sxfrp(port, p_card);
3901 if (!(RDW_HARPOON((port + hp_intstat)) &
3902 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) {
3903 WRW_HARPOON((port + hp_intstat), AUTO_INT);
3904 FPT_phaseDecode(port, p_card);
3905 }
3906 }
3907
3908 }
3909
3910 else {
3911 WR_HARPOON(port + hp_portctrl_0, 0x00);
3912 }
3913}
3914
3915/*---------------------------------------------------------------------
3916 *
3917 * Function: FPT_sinits
3918 *
3919 * Description: Setup SCCB manager fields in this SCCB.
3920 *
3921 *---------------------------------------------------------------------*/
3922
3923static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
3924{
3925 struct sccb_mgr_tar_info *currTar_Info;
3926
3927 if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) {
3928 return;
3929 }
3930 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
3931
3932 p_sccb->Sccb_XferState = 0x00;
3933 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
3934
3935 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
3936 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
3937
3938 p_sccb->Sccb_SGoffset = 0;
3939 p_sccb->Sccb_XferState = F_SG_XFER;
3940 p_sccb->Sccb_XferCnt = 0x00;
3941 }
3942
3943 if (p_sccb->DataLength == 0x00)
3944
3945 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
3946
3947 if (p_sccb->ControlByte & F_USE_CMD_Q) {
3948 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
3949 p_sccb->ControlByte &= ~F_USE_CMD_Q;
3950
3951 else
3952 currTar_Info->TarStatus |= TAG_Q_TRYING;
3953 }
3954
3955/* For !single SCSI device in system & device allow Disconnect
3956 or command is tag_q type then send Cmd with Disconnect Enable
3957 else send Cmd with Disconnect Disable */
3958
3959/*
3960 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
3961 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
3962 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3963*/
3964 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
3965 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3966 p_sccb->Sccb_idmsg =
3967 (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
3968 }
3969
3970 else {
3971
3972 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
3973 }
3974
3975 p_sccb->HostStatus = 0x00;
3976 p_sccb->TargetStatus = 0x00;
3977 p_sccb->Sccb_tag = 0x00;
3978 p_sccb->Sccb_MGRFlags = 0x00;
3979 p_sccb->Sccb_sgseg = 0x00;
3980 p_sccb->Sccb_ATC = 0x00;
3981 p_sccb->Sccb_savedATC = 0x00;
3982/*
3983 p_sccb->SccbVirtDataPtr = 0x00;
3984 p_sccb->Sccb_forwardlink = NULL;
3985 p_sccb->Sccb_backlink = NULL;
3986 */
3987 p_sccb->Sccb_scsistat = BUS_FREE_ST;
3988 p_sccb->SccbStatus = SCCB_IN_PROCESS;
3989 p_sccb->Sccb_scsimsg = SMNO_OP;
3990
3991}
3992
3993/*---------------------------------------------------------------------
3994 *
3995 * Function: Phase Decode
3996 *
3997 * Description: Determine the phase and call the appropriate function.
3998 *
3999 *---------------------------------------------------------------------*/
4000
4001static void FPT_phaseDecode(unsigned long p_port, unsigned char p_card)
4002{
4003 unsigned char phase_ref;
4004 void (*phase) (unsigned long, unsigned char);
4005
4006 DISABLE_AUTO(p_port);
4007
4008 phase_ref =
4009 (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ);
4010
4011 phase = FPT_s_PhaseTbl[phase_ref];
4012
4013 (*phase) (p_port, p_card); /* Call the correct phase func */
4014}
4015
4016/*---------------------------------------------------------------------
4017 *
4018 * Function: Data Out Phase
4019 *
4020 * Description: Start up both the BusMaster and Xbow.
4021 *
4022 *---------------------------------------------------------------------*/
4023
4024static void FPT_phaseDataOut(unsigned long port, unsigned char p_card)
4025{
4026
4027 struct sccb *currSCCB;
4028
4029 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4030 if (currSCCB == NULL) {
4031 return; /* Exit if No SCCB record */
4032 }
4033
4034 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4035 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4036
4037 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4038
4039 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4040
4041 WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4042
4043 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4044
4045 if (currSCCB->Sccb_XferCnt == 0) {
4046
4047 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4048 (currSCCB->HostStatus == SCCB_COMPLETE))
4049 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4050
4051 FPT_sxfrp(port, p_card);
4052 if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4053 FPT_phaseDecode(port, p_card);
4054 }
4055}
4056
4057/*---------------------------------------------------------------------
4058 *
4059 * Function: Data In Phase
4060 *
4061 * Description: Startup the BusMaster and the XBOW.
4062 *
4063 *---------------------------------------------------------------------*/
4064
4065static void FPT_phaseDataIn(unsigned long port, unsigned char p_card)
4066{
4067
4068 struct sccb *currSCCB;
4069
4070 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4071
4072 if (currSCCB == NULL) {
4073 return; /* Exit if No SCCB record */
4074 }
4075
4076 currSCCB->Sccb_scsistat = DATA_IN_ST;
4077 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4078 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4079
4080 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4081
4082 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4083
4084 WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4085
4086 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4087
4088 if (currSCCB->Sccb_XferCnt == 0) {
4089
4090 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4091 (currSCCB->HostStatus == SCCB_COMPLETE))
4092 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4093
4094 FPT_sxfrp(port, p_card);
4095 if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4096 FPT_phaseDecode(port, p_card);
4097
4098 }
4099}
4100
4101/*---------------------------------------------------------------------
4102 *
4103 * Function: Command Phase
4104 *
4105 * Description: Load the CDB into the automation and start it up.
4106 *
4107 *---------------------------------------------------------------------*/
4108
4109static void FPT_phaseCommand(unsigned long p_port, unsigned char p_card)
4110{
4111 struct sccb *currSCCB;
4112 unsigned long cdb_reg;
4113 unsigned char i;
4114
4115 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4116
4117 if (currSCCB->OperationCode == RESET_COMMAND) {
4118
4119 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4120 currSCCB->CdbLength = SIX_BYTE_CMD;
4121 }
4122
4123 WR_HARPOON(p_port + hp_scsisig, 0x00);
4124
4125 ARAM_ACCESS(p_port);
4126
4127 cdb_reg = p_port + CMD_STRT;
4128
4129 for (i = 0; i < currSCCB->CdbLength; i++) {
4130
4131 if (currSCCB->OperationCode == RESET_COMMAND)
4132
4133 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4134
4135 else
4136 WRW_HARPOON(cdb_reg,
4137 (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4138 cdb_reg += 2;
4139 }
4140
4141 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4142 WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
4143
4144 WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT));
4145
4146 currSCCB->Sccb_scsistat = COMMAND_ST;
4147
4148 WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4149 SGRAM_ACCESS(p_port);
4150}
4151
4152/*---------------------------------------------------------------------
4153 *
4154 * Function: Status phase
4155 *
4156 * Description: Bring in the status and command complete message bytes
4157 *
4158 *---------------------------------------------------------------------*/
4159
4160static void FPT_phaseStatus(unsigned long port, unsigned char p_card)
4161{
4162 /* Start-up the automation to finish off this command and let the
4163 isr handle the interrupt for command complete when it comes in.
4164 We could wait here for the interrupt to be generated?
4165 */
4166
4167 WR_HARPOON(port + hp_scsisig, 0x00);
4168
4169 WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START));
4170}
4171
4172/*---------------------------------------------------------------------
4173 *
4174 * Function: Phase Message Out
4175 *
4176 * Description: Send out our message (if we have one) and handle whatever
4177 * else is involed.
4178 *
4179 *---------------------------------------------------------------------*/
4180
4181static void FPT_phaseMsgOut(unsigned long port, unsigned char p_card)
4182{
4183 unsigned char message, scsiID;
4184 struct sccb *currSCCB;
4185 struct sccb_mgr_tar_info *currTar_Info;
4186
4187 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4188
4189 if (currSCCB != NULL) {
4190
4191 message = currSCCB->Sccb_scsimsg;
4192 scsiID = currSCCB->TargID;
4193
4194 if (message == SMDEV_RESET) {
4195
4196 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4197 currTar_Info->TarSyncCtrl = 0;
4198 FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
4199
4200 if (FPT_sccbMgrTbl[p_card][scsiID].
4201 TarEEValue & EE_SYNC_MASK) {
4202
4203 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4204 ~TAR_SYNC_MASK;
4205
4206 }
4207
4208 if (FPT_sccbMgrTbl[p_card][scsiID].
4209 TarEEValue & EE_WIDE_SCSI) {
4210
4211 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4212 ~TAR_WIDE_MASK;
4213 }
4214
4215 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4216 FPT_SccbMgrTableInitTarget(p_card, scsiID);
4217 } else if (currSCCB->Sccb_scsistat == ABORT_ST) {
4218 currSCCB->HostStatus = SCCB_COMPLETE;
4219 if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] !=
4220 NULL) {
4221 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4222 Sccb_tag] = NULL;
4223 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4224 }
4225
4226 }
4227
4228 else if (currSCCB->Sccb_scsistat < COMMAND_ST) {
4229
4230 if (message == SMNO_OP) {
4231 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4232
4233 FPT_ssel(port, p_card);
4234 return;
4235 }
4236 } else {
4237
4238 if (message == SMABORT)
4239
4240 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4241 }
4242
4243 } else {
4244 message = SMABORT;
4245 }
4246
4247 WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4248
4249 WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
4250
4251 WR_HARPOON(port + hp_scsidata_0, message);
4252
4253 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
4254
4255 ACCEPT_MSG(port);
4256
4257 WR_HARPOON(port + hp_portctrl_0, 0x00);
4258
4259 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4260 (message == SMABORT_TAG)) {
4261
4262 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) {
4263 }
4264
4265 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
4266 WRW_HARPOON((port + hp_intstat), BUS_FREE);
4267
4268 if (currSCCB != NULL) {
4269
4270 if ((FPT_BL_Card[p_card].
4271 globalFlags & F_CONLUN_IO)
4272 &&
4273 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4274 TarStatus & TAR_TAG_Q_MASK) !=
4275 TAG_Q_TRYING))
4276 FPT_sccbMgrTbl[p_card][currSCCB->
4277 TargID].
4278 TarLUNBusy[currSCCB->Lun] = 0;
4279 else
4280 FPT_sccbMgrTbl[p_card][currSCCB->
4281 TargID].
4282 TarLUNBusy[0] = 0;
4283
4284 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
4285 currSCCB, p_card);
4286 }
4287
4288 else {
4289 FPT_BL_Card[p_card].globalFlags |=
4290 F_NEW_SCCB_CMD;
4291 }
4292 }
4293
4294 else {
4295
4296 FPT_sxfrp(port, p_card);
4297 }
4298 }
4299
4300 else {
4301
4302 if (message == SMPARITY) {
4303 currSCCB->Sccb_scsimsg = SMNO_OP;
4304 WR_HARPOON(port + hp_autostart_1,
4305 (AUTO_IMMED + DISCONNECT_START));
4306 } else {
4307 FPT_sxfrp(port, p_card);
4308 }
4309 }
4310}
4311
4312/*---------------------------------------------------------------------
4313 *
4314 * Function: Message In phase
4315 *
4316 * Description: Bring in the message and determine what to do with it.
4317 *
4318 *---------------------------------------------------------------------*/
4319
4320static void FPT_phaseMsgIn(unsigned long port, unsigned char p_card)
4321{
4322 unsigned char message;
4323 struct sccb *currSCCB;
4324
4325 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4326
4327 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
4328
4329 FPT_phaseChkFifo(port, p_card);
4330 }
4331
4332 message = RD_HARPOON(port + hp_scsidata_0);
4333 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR)) {
4334
4335 WR_HARPOON(port + hp_autostart_1,
4336 (AUTO_IMMED + END_DATA_START));
4337
4338 }
4339
4340 else {
4341
4342 message = FPT_sfm(port, currSCCB);
4343 if (message) {
4344
4345 FPT_sdecm(message, port, p_card);
4346
4347 } else {
4348 if (currSCCB->Sccb_scsimsg != SMPARITY)
4349 ACCEPT_MSG(port);
4350 WR_HARPOON(port + hp_autostart_1,
4351 (AUTO_IMMED + DISCONNECT_START));
4352 }
4353 }
4354
4355}
4356
4357/*---------------------------------------------------------------------
4358 *
4359 * Function: Illegal phase
4360 *
4361 * Description: Target switched to some illegal phase, so all we can do
4362 * is report an error back to the host (if that is possible)
4363 * and send an ABORT message to the misbehaving target.
4364 *
4365 *---------------------------------------------------------------------*/
4366
4367static void FPT_phaseIllegal(unsigned long port, unsigned char p_card)
4368{
4369 struct sccb *currSCCB;
4370
4371 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4372
4373 WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig));
4374 if (currSCCB != NULL) {
4375
4376 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4377 currSCCB->Sccb_scsistat = ABORT_ST;
4378 currSCCB->Sccb_scsimsg = SMABORT;
4379 }
4380
4381 ACCEPT_MSG_ATN(port);
4382}
4383
4384/*---------------------------------------------------------------------
4385 *
4386 * Function: Phase Check FIFO
4387 *
4388 * Description: Make sure data has been flushed from both FIFOs and abort
4389 * the operations if necessary.
4390 *
4391 *---------------------------------------------------------------------*/
4392
4393static void FPT_phaseChkFifo(unsigned long port, unsigned char p_card)
4394{
4395 unsigned long xfercnt;
4396 struct sccb *currSCCB;
4397
4398 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4399
4400 if (currSCCB->Sccb_scsistat == DATA_IN_ST) {
4401
4402 while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) &&
4403 (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) {
4404 }
4405
4406 if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) {
4407 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4408
4409 currSCCB->Sccb_XferCnt = 0;
4410
4411 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4412 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4413 currSCCB->HostStatus = SCCB_PARITY_ERR;
4414 WRW_HARPOON((port + hp_intstat), PARITY);
4415 }
4416
4417 FPT_hostDataXferAbort(port, p_card, currSCCB);
4418
4419 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4420
4421 while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY))
4422 && (RD_HARPOON(port + hp_ext_status) &
4423 BM_CMD_BUSY)) {
4424 }
4425
4426 }
4427 }
4428
4429 /*End Data In specific code. */
4430 GET_XFER_CNT(port, xfercnt);
4431
4432 WR_HARPOON(port + hp_xfercnt_0, 0x00);
4433
4434 WR_HARPOON(port + hp_portctrl_0, 0x00);
4435
4436 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4437
4438 currSCCB->Sccb_XferCnt = xfercnt;
4439
4440 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4441 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4442
4443 currSCCB->HostStatus = SCCB_PARITY_ERR;
4444 WRW_HARPOON((port + hp_intstat), PARITY);
4445 }
4446
4447 FPT_hostDataXferAbort(port, p_card, currSCCB);
4448
4449 WR_HARPOON(port + hp_fifowrite, 0x00);
4450 WR_HARPOON(port + hp_fiforead, 0x00);
4451 WR_HARPOON(port + hp_xferstat, 0x00);
4452
4453 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4454}
4455
4456/*---------------------------------------------------------------------
4457 *
4458 * Function: Phase Bus Free
4459 *
4460 * Description: We just went bus free so figure out if it was
4461 * because of command complete or from a disconnect.
4462 *
4463 *---------------------------------------------------------------------*/
4464static void FPT_phaseBusFree(unsigned long port, unsigned char p_card)
4465{
4466 struct sccb *currSCCB;
4467
4468 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4469
4470 if (currSCCB != NULL) {
4471
4472 DISABLE_AUTO(port);
4473
4474 if (currSCCB->OperationCode == RESET_COMMAND) {
4475
4476 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4477 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4478 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4479 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4480 TarLUNBusy[currSCCB->Lun] = 0;
4481 else
4482 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4483 TarLUNBusy[0] = 0;
4484
4485 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4486 p_card);
4487
4488 FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card);
4489
4490 }
4491
4492 else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4493 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4494 (unsigned char)SYNC_SUPPORTED;
4495 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4496 ~EE_SYNC_MASK;
4497 }
4498
4499 else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4500 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4501 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4502 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4503
4504 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4505 ~EE_WIDE_SCSI;
4506 }
4507
4508 else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
4509 /* Make sure this is not a phony BUS_FREE. If we were
4510 reselected or if BUSY is NOT on then this is a
4511 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4512
4513 if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ||
4514 (RDW_HARPOON((port + hp_intstat)) & RSEL)) {
4515 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4516 TarStatus &= ~TAR_TAG_Q_MASK;
4517 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4518 TarStatus |= TAG_Q_REJECT;
4519 }
4520
4521 else {
4522 return;
4523 }
4524 }
4525
4526 else {
4527
4528 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4529
4530 if (!currSCCB->HostStatus) {
4531 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4532 }
4533
4534 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4535 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4536 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4537 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4538 TarLUNBusy[currSCCB->Lun] = 0;
4539 else
4540 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4541 TarLUNBusy[0] = 0;
4542
4543 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4544 p_card);
4545 return;
4546 }
4547
4548 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4549
4550 } /*end if !=null */
4551}
4552
4553/*---------------------------------------------------------------------
4554 *
4555 * Function: Auto Load Default Map
4556 *
4557 * Description: Load the Automation RAM with the defualt map values.
4558 *
4559 *---------------------------------------------------------------------*/
4560static void FPT_autoLoadDefaultMap(unsigned long p_port)
4561{
4562 unsigned long map_addr;
4563
4564 ARAM_ACCESS(p_port);
4565 map_addr = p_port + hp_aramBase;
4566
4567 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0)); /*ID MESSAGE */
4568 map_addr += 2;
4569 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20)); /*SIMPLE TAG QUEUEING MSG */
4570 map_addr += 2;
4571 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4572 map_addr += 2;
4573 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00)); /*TAG ID MSG */
4574 map_addr += 2;
4575 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 0 */
4576 map_addr += 2;
4577 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 1 */
4578 map_addr += 2;
4579 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 2 */
4580 map_addr += 2;
4581 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 3 */
4582 map_addr += 2;
4583 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 4 */
4584 map_addr += 2;
4585 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 5 */
4586 map_addr += 2;
4587 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 6 */
4588 map_addr += 2;
4589 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 7 */
4590 map_addr += 2;
4591 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 8 */
4592 map_addr += 2;
4593 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 9 */
4594 map_addr += 2;
4595 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 10 */
4596 map_addr += 2;
4597 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 11 */
4598 map_addr += 2;
4599 WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT)); /*JUMP IF DATA OUT */
4600 map_addr += 2;
4601 WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI)); /*JUMP IF NO DATA IN FIFO */
4602 map_addr += 2; /*This means AYNC DATA IN */
4603 WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4604 map_addr += 2;
4605 WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT)); /*JUMP IF NOT DATA IN PHZ */
4606 map_addr += 2;
4607 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4608 map_addr += 2;
4609 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02)); /*SAVE DATA PTR MSG? */
4610 map_addr += 2;
4611 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC)); /*GO CHECK FOR DISCONNECT MSG */
4612 map_addr += 2;
4613 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1)); /*SAVE DATA PTRS MSG */
4614 map_addr += 2;
4615 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK DATA IN */
4616 map_addr += 2;
4617 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04)); /*DISCONNECT MSG? */
4618 map_addr += 2;
4619 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN)); /*UKNKNOWN MSG */
4620 map_addr += 2;
4621 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*XFER DISCONNECT MSG */
4622 map_addr += 2;
4623 WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC)); /*STOP AND INTERRUPT */
4624 map_addr += 2;
4625 WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN)); /*JUMP IF NOT STATUS PHZ. */
4626 map_addr += 2;
4627 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0)); /*GET STATUS BYTE */
4628 map_addr += 2;
4629 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC)); /*ERROR IF NOT MSG IN PHZ */
4630 map_addr += 2;
4631 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4632 map_addr += 2;
4633 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4634 map_addr += 2;
4635 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*GET CMD COMPLETE MSG */
4636 map_addr += 2;
4637 WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP)); /*END OF COMMAND */
4638 map_addr += 2;
4639
4640 WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4641 map_addr += 2;
4642 WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4643 map_addr += 2;
4644 WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4645 map_addr += 2;
4646 WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4647 map_addr += 2; /* DIDN'T GET ONE */
4648 WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG)); /* comp SCSI SEL ID & AR3 */
4649 map_addr += 2;
4650 WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00)); /*SEL ID OK then Conti. */
4651 map_addr += 2;
4652 WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4653
4654 SGRAM_ACCESS(p_port);
4655}
4656
4657/*---------------------------------------------------------------------
4658 *
4659 * Function: Auto Command Complete
4660 *
4661 * Description: Post command back to host and find another command
4662 * to execute.
4663 *
4664 *---------------------------------------------------------------------*/
4665
4666static void FPT_autoCmdCmplt(unsigned long p_port, unsigned char p_card)
4667{
4668 struct sccb *currSCCB;
4669 unsigned char status_byte;
4670
4671 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4672
4673 status_byte = RD_HARPOON(p_port + hp_gp_reg_0);
4674
4675 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4676
4677 if (status_byte != SSGOOD) {
4678
4679 if (status_byte == SSQ_FULL) {
4680
4681 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4682 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4683 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4684 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4685 TarLUNBusy[currSCCB->Lun] = 1;
4686 if (FPT_BL_Card[p_card].discQCount != 0)
4687 FPT_BL_Card[p_card].discQCount--;
4688 FPT_BL_Card[p_card].
4689 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4690 [currSCCB->TargID].
4691 LunDiscQ_Idx[currSCCB->Lun]] =
4692 NULL;
4693 } else {
4694 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4695 TarLUNBusy[0] = 1;
4696 if (currSCCB->Sccb_tag) {
4697 if (FPT_BL_Card[p_card].discQCount != 0)
4698 FPT_BL_Card[p_card].
4699 discQCount--;
4700 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4701 Sccb_tag]
4702 = NULL;
4703 } else {
4704 if (FPT_BL_Card[p_card].discQCount != 0)
4705 FPT_BL_Card[p_card].
4706 discQCount--;
4707 FPT_BL_Card[p_card].
4708 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4709 [currSCCB->TargID].
4710 LunDiscQ_Idx[0]] = NULL;
4711 }
4712 }
4713
4714 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4715
4716 FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
4717
4718 return;
4719 }
4720
4721 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4722 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4723 (unsigned char)SYNC_SUPPORTED;
4724
4725 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4726 ~EE_SYNC_MASK;
4727 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4728
4729 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4730 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4731 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4732 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4733 TarLUNBusy[currSCCB->Lun] = 1;
4734 if (FPT_BL_Card[p_card].discQCount != 0)
4735 FPT_BL_Card[p_card].discQCount--;
4736 FPT_BL_Card[p_card].
4737 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4738 [currSCCB->TargID].
4739 LunDiscQ_Idx[currSCCB->Lun]] =
4740 NULL;
4741 } else {
4742 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4743 TarLUNBusy[0] = 1;
4744 if (currSCCB->Sccb_tag) {
4745 if (FPT_BL_Card[p_card].discQCount != 0)
4746 FPT_BL_Card[p_card].
4747 discQCount--;
4748 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4749 Sccb_tag]
4750 = NULL;
4751 } else {
4752 if (FPT_BL_Card[p_card].discQCount != 0)
4753 FPT_BL_Card[p_card].
4754 discQCount--;
4755 FPT_BL_Card[p_card].
4756 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4757 [currSCCB->TargID].
4758 LunDiscQ_Idx[0]] = NULL;
4759 }
4760 }
4761 return;
4762
4763 }
4764
4765 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4766
4767 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4768 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4769 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4770
4771 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4772 ~EE_WIDE_SCSI;
4773 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4774
4775 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4776 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4777 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4778 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4779 TarLUNBusy[currSCCB->Lun] = 1;
4780 if (FPT_BL_Card[p_card].discQCount != 0)
4781 FPT_BL_Card[p_card].discQCount--;
4782 FPT_BL_Card[p_card].
4783 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4784 [currSCCB->TargID].
4785 LunDiscQ_Idx[currSCCB->Lun]] =
4786 NULL;
4787 } else {
4788 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4789 TarLUNBusy[0] = 1;
4790 if (currSCCB->Sccb_tag) {
4791 if (FPT_BL_Card[p_card].discQCount != 0)
4792 FPT_BL_Card[p_card].
4793 discQCount--;
4794 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4795 Sccb_tag]
4796 = NULL;
4797 } else {
4798 if (FPT_BL_Card[p_card].discQCount != 0)
4799 FPT_BL_Card[p_card].
4800 discQCount--;
4801 FPT_BL_Card[p_card].
4802 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4803 [currSCCB->TargID].
4804 LunDiscQ_Idx[0]] = NULL;
4805 }
4806 }
4807 return;
4808
4809 }
4810
4811 if (status_byte == SSCHECK) {
4812 if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) {
4813 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4814 TarEEValue & EE_SYNC_MASK) {
4815 FPT_sccbMgrTbl[p_card][currSCCB->
4816 TargID].
4817 TarStatus &= ~TAR_SYNC_MASK;
4818 }
4819 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4820 TarEEValue & EE_WIDE_SCSI) {
4821 FPT_sccbMgrTbl[p_card][currSCCB->
4822 TargID].
4823 TarStatus &= ~TAR_WIDE_MASK;
4824 }
4825 }
4826 }
4827
4828 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
4829
4830 currSCCB->SccbStatus = SCCB_ERROR;
4831 currSCCB->TargetStatus = status_byte;
4832
4833 if (status_byte == SSCHECK) {
4834
4835 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4836 TarLUN_CA = 1;
4837
4838 if (currSCCB->RequestSenseLength !=
4839 NO_AUTO_REQUEST_SENSE) {
4840
4841 if (currSCCB->RequestSenseLength == 0)
4842 currSCCB->RequestSenseLength =
4843 14;
4844
4845 FPT_ssenss(&FPT_BL_Card[p_card]);
4846 FPT_BL_Card[p_card].globalFlags |=
4847 F_NEW_SCCB_CMD;
4848
4849 if (((FPT_BL_Card[p_card].
4850 globalFlags & F_CONLUN_IO)
4851 &&
4852 ((FPT_sccbMgrTbl[p_card]
4853 [currSCCB->TargID].
4854 TarStatus & TAR_TAG_Q_MASK) !=
4855 TAG_Q_TRYING))) {
4856 FPT_sccbMgrTbl[p_card]
4857 [currSCCB->TargID].
4858 TarLUNBusy[currSCCB->Lun] =
4859 1;
4860 if (FPT_BL_Card[p_card].
4861 discQCount != 0)
4862 FPT_BL_Card[p_card].
4863 discQCount--;
4864 FPT_BL_Card[p_card].
4865 discQ_Tbl[FPT_sccbMgrTbl
4866 [p_card]
4867 [currSCCB->
4868 TargID].
4869 LunDiscQ_Idx
4870 [currSCCB->Lun]] =
4871 NULL;
4872 } else {
4873 FPT_sccbMgrTbl[p_card]
4874 [currSCCB->TargID].
4875 TarLUNBusy[0] = 1;
4876 if (currSCCB->Sccb_tag) {
4877 if (FPT_BL_Card[p_card].
4878 discQCount != 0)
4879 FPT_BL_Card
4880 [p_card].
4881 discQCount--;
4882 FPT_BL_Card[p_card].
4883 discQ_Tbl[currSCCB->
4884 Sccb_tag]
4885 = NULL;
4886 } else {
4887 if (FPT_BL_Card[p_card].
4888 discQCount != 0)
4889 FPT_BL_Card
4890 [p_card].
4891 discQCount--;
4892 FPT_BL_Card[p_card].
4893 discQ_Tbl
4894 [FPT_sccbMgrTbl
4895 [p_card][currSCCB->
4896 TargID].
4897 LunDiscQ_Idx[0]] =
4898 NULL;
4899 }
4900 }
4901 return;
4902 }
4903 }
4904 }
4905 }
4906
4907 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4908 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4909 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4910 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->
4911 Lun] = 0;
4912 else
4913 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4914
4915 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4916}
4917
4918#define SHORT_WAIT 0x0000000F
4919#define LONG_WAIT 0x0000FFFFL
4920
4921/*---------------------------------------------------------------------
4922 *
4923 * Function: Data Transfer Processor
4924 *
4925 * Description: This routine performs two tasks.
4926 * (1) Start data transfer by calling HOST_DATA_XFER_START
4927 * function. Once data transfer is started, (2) Depends
4928 * on the type of data transfer mode Scatter/Gather mode
4929 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
4930 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
4931 * data transfer done. In Scatter/Gather mode, this routine
4932 * checks bus master command complete and dual rank busy
4933 * bit to keep chaining SC transfer command. Similarly,
4934 * in Scatter/Gather mode, it checks Sccb_MGRFlag
4935 * (F_HOST_XFER_ACT bit) for data transfer done.
4936 *
4937 *---------------------------------------------------------------------*/
4938
4939static void FPT_dataXferProcessor(unsigned long port,
4940 struct sccb_card *pCurrCard)
4941{
4942 struct sccb *currSCCB;
4943
4944 currSCCB = pCurrCard->currentSCCB;
4945
4946 if (currSCCB->Sccb_XferState & F_SG_XFER) {
4947 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
4948 {
4949 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
4950 currSCCB->Sccb_SGoffset = 0x00;
4951 }
4952 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4953
4954 FPT_busMstrSGDataXferStart(port, currSCCB);
4955 }
4956
4957 else {
4958 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) {
4959 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4960
4961 FPT_busMstrDataXferStart(port, currSCCB);
4962 }
4963 }
4964}
4965
4966/*---------------------------------------------------------------------
4967 *
4968 * Function: BusMaster Scatter Gather Data Transfer Start
4969 *
4970 * Description:
4971 *
4972 *---------------------------------------------------------------------*/
4973static void FPT_busMstrSGDataXferStart(unsigned long p_port,
4974 struct sccb *pcurrSCCB)
4975{
4976 unsigned long count, addr, tmpSGCnt;
4977 unsigned int sg_index;
4978 unsigned char sg_count, i;
4979 unsigned long reg_offset;
4980
4981 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4982
4983 count = ((unsigned long)HOST_RD_CMD) << 24;
4984 }
4985
4986 else {
4987 count = ((unsigned long)HOST_WRT_CMD) << 24;
4988 }
4989
4990 sg_count = 0;
4991 tmpSGCnt = 0;
4992 sg_index = pcurrSCCB->Sccb_sgseg;
4993 reg_offset = hp_aramBase;
4994
4995 i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
4996 ~(SGRAM_ARAM | SCATTER_EN));
4997
4998 WR_HARPOON(p_port + hp_page_ctrl, i);
4999
5000 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
5001 ((unsigned long)(sg_index * (unsigned int)SG_ELEMENT_SIZE) <
5002 pcurrSCCB->DataLength)) {
5003
5004 tmpSGCnt += *(((unsigned long *)pcurrSCCB->DataPointer) +
5005 (sg_index * 2));
5006
5007 count |= *(((unsigned long *)pcurrSCCB->DataPointer) +
5008 (sg_index * 2));
5009
5010 addr = *(((unsigned long *)pcurrSCCB->DataPointer) +
5011 ((sg_index * 2) + 1));
5012
5013 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
5014
5015 addr +=
5016 ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
5017 count =
5018 (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
5019
5020 tmpSGCnt = count & 0x00FFFFFFL;
5021 }
5022
5023 WR_HARP32(p_port, reg_offset, addr);
5024 reg_offset += 4;
5025
5026 WR_HARP32(p_port, reg_offset, count);
5027 reg_offset += 4;
5028
5029 count &= 0xFF000000L;
5030 sg_index++;
5031 sg_count++;
5032
5033 } /*End While */
5034
5035 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5036
5037 WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4));
5038
5039 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5040
5041 WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
5042
5043 WR_HARPOON(p_port + hp_portctrl_0,
5044 (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5045 WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5046 }
5047
5048 else {
5049
5050 if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) &&
5051 (tmpSGCnt & 0x000000001)) {
5052
5053 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5054 tmpSGCnt--;
5055 }
5056
5057 WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
5058
5059 WR_HARPOON(p_port + hp_portctrl_0,
5060 (SCSI_PORT | DMA_PORT | DMA_RD));
5061 WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5062 }
5063
5064 WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN));
5065
5066}
5067
5068/*---------------------------------------------------------------------
5069 *
5070 * Function: BusMaster Data Transfer Start
5071 *
5072 * Description:
5073 *
5074 *---------------------------------------------------------------------*/
5075static void FPT_busMstrDataXferStart(unsigned long p_port,
5076 struct sccb *pcurrSCCB)
5077{
5078 unsigned long addr, count;
5079
5080 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5081
5082 count = pcurrSCCB->Sccb_XferCnt;
5083
5084 addr =
5085 (unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5086 }
5087
5088 else {
5089 addr = pcurrSCCB->SensePointer;
5090 count = pcurrSCCB->RequestSenseLength;
5091
5092 }
5093
5094 HP_SETUP_ADDR_CNT(p_port, addr, count);
5095
5096 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5097
5098 WR_HARPOON(p_port + hp_portctrl_0,
5099 (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5100 WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5101
5102 WR_HARPOON(p_port + hp_xfer_cmd,
5103 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5104 }
5105
5106 else {
5107
5108 WR_HARPOON(p_port + hp_portctrl_0,
5109 (SCSI_PORT | DMA_PORT | DMA_RD));
5110 WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5111
5112 WR_HARPOON(p_port + hp_xfer_cmd,
5113 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5114
5115 }
5116}
5117
5118/*---------------------------------------------------------------------
5119 *
5120 * Function: BusMaster Timeout Handler
5121 *
5122 * Description: This function is called after a bus master command busy time
5123 * out is detected. This routines issue halt state machine
5124 * with a software time out for command busy. If command busy
5125 * is still asserted at the end of the time out, it issues
5126 * hard abort with another software time out. It hard abort
5127 * command busy is also time out, it'll just give up.
5128 *
5129 *---------------------------------------------------------------------*/
5130static unsigned char FPT_busMstrTimeOut(unsigned long p_port)
5131{
5132 unsigned long timeout;
5133
5134 timeout = LONG_WAIT;
5135
5136 WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH);
5137
5138 while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED))
5139 && timeout--) {
5140 }
5141
5142 if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5143 WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT);
5144
5145 timeout = LONG_WAIT;
5146 while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY)
5147 && timeout--) {
5148 }
5149 }
5150
5151 RD_HARPOON(p_port + hp_int_status); /*Clear command complete */
5152
5153 if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5154 return 1;
5155 }
5156
5157 else {
5158 return 0;
5159 }
5160}
5161
5162/*---------------------------------------------------------------------
5163 *
5164 * Function: Host Data Transfer Abort
5165 *
5166 * Description: Abort any in progress transfer.
5167 *
5168 *---------------------------------------------------------------------*/
5169static void FPT_hostDataXferAbort(unsigned long port, unsigned char p_card,
5170 struct sccb *pCurrSCCB)
5171{
5172
5173 unsigned long timeout;
5174 unsigned long remain_cnt;
5175 unsigned int sg_ptr;
5176
5177 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5178
5179 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5180
5181 if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) {
5182
5183 WR_HARPOON(port + hp_bm_ctrl,
5184 (RD_HARPOON(port + hp_bm_ctrl) |
5185 FLUSH_XFER_CNTR));
5186 timeout = LONG_WAIT;
5187
5188 while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5189 && timeout--) {
5190 }
5191
5192 WR_HARPOON(port + hp_bm_ctrl,
5193 (RD_HARPOON(port + hp_bm_ctrl) &
5194 ~FLUSH_XFER_CNTR));
5195
5196 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5197
5198 if (FPT_busMstrTimeOut(port)) {
5199
5200 if (pCurrSCCB->HostStatus == 0x00)
5201
5202 pCurrSCCB->HostStatus =
5203 SCCB_BM_ERR;
5204
5205 }
5206
5207 if (RD_HARPOON(port + hp_int_status) &
5208 INT_EXT_STATUS)
5209
5210 if (RD_HARPOON(port + hp_ext_status) &
5211 BAD_EXT_STATUS)
5212
5213 if (pCurrSCCB->HostStatus ==
5214 0x00)
5215 {
5216 pCurrSCCB->HostStatus =
5217 SCCB_BM_ERR;
5218 }
5219 }
5220 }
5221 }
5222
5223 else if (pCurrSCCB->Sccb_XferCnt) {
5224
5225 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5226
5227 WR_HARPOON(port + hp_page_ctrl,
5228 (RD_HARPOON(port + hp_page_ctrl) &
5229 ~SCATTER_EN));
5230
5231 WR_HARPOON(port + hp_sg_addr, 0x00);
5232
5233 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5234
5235 if (sg_ptr >
5236 (unsigned int)(pCurrSCCB->DataLength /
5237 SG_ELEMENT_SIZE)) {
5238
5239 sg_ptr =
5240 (unsigned int)(pCurrSCCB->DataLength /
5241 SG_ELEMENT_SIZE);
5242 }
5243
5244 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5245
5246 while (remain_cnt < 0x01000000L) {
5247
5248 sg_ptr--;
5249
5250 if (remain_cnt >
5251 (unsigned
5252 long)(*(((unsigned long *)pCurrSCCB->
5253 DataPointer) + (sg_ptr * 2)))) {
5254
5255 remain_cnt -=
5256 (unsigned
5257 long)(*(((unsigned long *)
5258 pCurrSCCB->DataPointer) +
5259 (sg_ptr * 2)));
5260 }
5261
5262 else {
5263
5264 break;
5265 }
5266 }
5267
5268 if (remain_cnt < 0x01000000L) {
5269
5270 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5271
5272 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5273
5274 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) ==
5275 pCurrSCCB->DataLength && (remain_cnt == 0))
5276
5277 pCurrSCCB->Sccb_XferState |=
5278 F_ALL_XFERRED;
5279 }
5280
5281 else {
5282
5283 if (pCurrSCCB->HostStatus == 0x00) {
5284
5285 pCurrSCCB->HostStatus =
5286 SCCB_GROSS_FW_ERR;
5287 }
5288 }
5289 }
5290
5291 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5292
5293 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5294
5295 FPT_busMstrTimeOut(port);
5296 }
5297
5298 else {
5299
5300 if (RD_HARPOON(port + hp_int_status) &
5301 INT_EXT_STATUS) {
5302
5303 if (RD_HARPOON(port + hp_ext_status) &
5304 BAD_EXT_STATUS) {
5305
5306 if (pCurrSCCB->HostStatus ==
5307 0x00) {
5308
5309 pCurrSCCB->HostStatus =
5310 SCCB_BM_ERR;
5311 }
5312 }
5313 }
5314
5315 }
5316 }
5317
5318 else {
5319
5320 if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) {
5321
5322 timeout = SHORT_WAIT;
5323
5324 while ((RD_HARPOON(port + hp_ext_status) &
5325 BM_CMD_BUSY)
5326 && ((RD_HARPOON(port + hp_fifo_cnt)) >=
5327 BM_THRESHOLD) && timeout--) {
5328 }
5329 }
5330
5331 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5332
5333 WR_HARPOON(port + hp_bm_ctrl,
5334 (RD_HARPOON(port + hp_bm_ctrl) |
5335 FLUSH_XFER_CNTR));
5336
5337 timeout = LONG_WAIT;
5338
5339 while ((RD_HARPOON(port + hp_ext_status) &
5340 BM_CMD_BUSY) && timeout--) {
5341 }
5342
5343 WR_HARPOON(port + hp_bm_ctrl,
5344 (RD_HARPOON(port + hp_bm_ctrl) &
5345 ~FLUSH_XFER_CNTR));
5346
5347 if (RD_HARPOON(port + hp_ext_status) &
5348 BM_CMD_BUSY) {
5349
5350 if (pCurrSCCB->HostStatus == 0x00) {
5351
5352 pCurrSCCB->HostStatus =
5353 SCCB_BM_ERR;
5354 }
5355
5356 FPT_busMstrTimeOut(port);
5357 }
5358 }
5359
5360 if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5361
5362 if (RD_HARPOON(port + hp_ext_status) &
5363 BAD_EXT_STATUS) {
5364
5365 if (pCurrSCCB->HostStatus == 0x00) {
5366
5367 pCurrSCCB->HostStatus =
5368 SCCB_BM_ERR;
5369 }
5370 }
5371 }
5372 }
5373
5374 }
5375
5376 else {
5377
5378 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5379
5380 timeout = LONG_WAIT;
5381
5382 while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5383 && timeout--) {
5384 }
5385
5386 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5387
5388 if (pCurrSCCB->HostStatus == 0x00) {
5389
5390 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5391 }
5392
5393 FPT_busMstrTimeOut(port);
5394 }
5395 }
5396
5397 if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5398
5399 if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) {
5400
5401 if (pCurrSCCB->HostStatus == 0x00) {
5402
5403 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5404 }
5405 }
5406
5407 }
5408
5409 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5410
5411 WR_HARPOON(port + hp_page_ctrl,
5412 (RD_HARPOON(port + hp_page_ctrl) &
5413 ~SCATTER_EN));
5414
5415 WR_HARPOON(port + hp_sg_addr, 0x00);
5416
5417 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5418
5419 pCurrSCCB->Sccb_SGoffset = 0x00;
5420
5421 if ((unsigned long)(pCurrSCCB->Sccb_sgseg *
5422 SG_ELEMENT_SIZE) >=
5423 pCurrSCCB->DataLength) {
5424
5425 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5426
5427 pCurrSCCB->Sccb_sgseg =
5428 (unsigned short)(pCurrSCCB->DataLength /
5429 SG_ELEMENT_SIZE);
5430
5431 }
5432 }
5433
5434 else {
5435
5436 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5437
5438 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5439 }
5440 }
5441
5442 WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
5443}
5444
5445/*---------------------------------------------------------------------
5446 *
5447 * Function: Host Data Transfer Restart
5448 *
5449 * Description: Reset the available count due to a restore data
5450 * pointers message.
5451 *
5452 *---------------------------------------------------------------------*/
5453static void FPT_hostDataXferRestart(struct sccb *currSCCB)
5454{
5455 unsigned long data_count;
5456 unsigned int sg_index;
5457 unsigned long *sg_ptr;
5458
5459 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5460
5461 currSCCB->Sccb_XferCnt = 0;
5462
5463 sg_index = 0xffff; /*Index by long words into sg list. */
5464 data_count = 0; /*Running count of SG xfer counts. */
5465
5466 sg_ptr = (unsigned long *)currSCCB->DataPointer;
5467
5468 while (data_count < currSCCB->Sccb_ATC) {
5469
5470 sg_index++;
5471 data_count += *(sg_ptr + (sg_index * 2));
5472 }
5473
5474 if (data_count == currSCCB->Sccb_ATC) {
5475
5476 currSCCB->Sccb_SGoffset = 0;
5477 sg_index++;
5478 }
5479
5480 else {
5481 currSCCB->Sccb_SGoffset =
5482 data_count - currSCCB->Sccb_ATC;
5483 }
5484
5485 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5486 }
5487
5488 else {
5489 currSCCB->Sccb_XferCnt =
5490 currSCCB->DataLength - currSCCB->Sccb_ATC;
5491 }
5492}
5493
5494/*---------------------------------------------------------------------
5495 *
5496 * Function: FPT_scini
5497 *
5498 * Description: Setup all data structures necessary for SCAM selection.
5499 *
5500 *---------------------------------------------------------------------*/
5501
5502static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
5503 unsigned char p_power_up)
5504{
5505
5506 unsigned char loser, assigned_id;
5507 unsigned long p_port;
5508
5509 unsigned char i, k, ScamFlg;
5510 struct sccb_card *currCard;
5511 struct nvram_info *pCurrNvRam;
5512
5513 currCard = &FPT_BL_Card[p_card];
5514 p_port = currCard->ioPort;
5515 pCurrNvRam = currCard->pNvRamInfo;
5516
5517 if (pCurrNvRam) {
5518 ScamFlg = pCurrNvRam->niScamConf;
5519 i = pCurrNvRam->niSysConf;
5520 } else {
5521 ScamFlg =
5522 (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2);
5523 i = (unsigned
5524 char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2)));
5525 }
5526 if (!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5527 return;
5528
5529 FPT_inisci(p_card, p_port, p_our_id);
5530
5531 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5532 too slow to return to SCAM selection */
5533
5534 /* if (p_power_up)
5535 FPT_Wait1Second(p_port);
5536 else
5537 FPT_Wait(p_port, TO_250ms); */
5538
5539 FPT_Wait1Second(p_port);
5540
5541 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) {
5542 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5543 }
5544
5545 FPT_scsel(p_port);
5546
5547 do {
5548 FPT_scxferc(p_port, SYNC_PTRN);
5549 FPT_scxferc(p_port, DOM_MSTR);
5550 loser =
5551 FPT_scsendi(p_port,
5552 &FPT_scamInfo[p_our_id].id_string[0]);
5553 } while (loser == 0xFF);
5554
5555 FPT_scbusf(p_port);
5556
5557 if ((p_power_up) && (!loser)) {
5558 FPT_sresb(p_port, p_card);
5559 FPT_Wait(p_port, TO_250ms);
5560
5561 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5562 }
5563
5564 FPT_scsel(p_port);
5565
5566 do {
5567 FPT_scxferc(p_port, SYNC_PTRN);
5568 FPT_scxferc(p_port, DOM_MSTR);
5569 loser =
5570 FPT_scsendi(p_port,
5571 &FPT_scamInfo[p_our_id].
5572 id_string[0]);
5573 } while (loser == 0xFF);
5574
5575 FPT_scbusf(p_port);
5576 }
5577 }
5578
5579 else {
5580 loser = 0;
5581 }
5582
5583 if (!loser) {
5584
5585 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5586
5587 if (ScamFlg & SCAM_ENABLED) {
5588
5589 for (i = 0; i < MAX_SCSI_TAR; i++) {
5590 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5591 (FPT_scamInfo[i].state == ID_UNUSED)) {
5592 if (FPT_scsell(p_port, i)) {
5593 FPT_scamInfo[i].state = LEGACY;
5594 if ((FPT_scamInfo[i].
5595 id_string[0] != 0xFF)
5596 || (FPT_scamInfo[i].
5597 id_string[1] != 0xFA)) {
5598
5599 FPT_scamInfo[i].
5600 id_string[0] = 0xFF;
5601 FPT_scamInfo[i].
5602 id_string[1] = 0xFA;
5603 if (pCurrNvRam == NULL)
5604 currCard->
5605 globalFlags
5606 |=
5607 F_UPDATE_EEPROM;
5608 }
5609 }
5610 }
5611 }
5612
5613 FPT_sresb(p_port, p_card);
5614 FPT_Wait1Second(p_port);
5615 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5616 }
5617 FPT_scsel(p_port);
5618 FPT_scasid(p_card, p_port);
5619 }
5620
5621 }
5622
5623 else if ((loser) && (ScamFlg & SCAM_ENABLED)) {
5624 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5625 assigned_id = 0;
5626 FPT_scwtsel(p_port);
5627
5628 do {
5629 while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) {
5630 }
5631
5632 i = FPT_scxferc(p_port, 0x00);
5633 if (i == ASSIGN_ID) {
5634 if (!
5635 (FPT_scsendi
5636 (p_port,
5637 &FPT_scamInfo[p_our_id].id_string[0]))) {
5638 i = FPT_scxferc(p_port, 0x00);
5639 if (FPT_scvalq(i)) {
5640 k = FPT_scxferc(p_port, 0x00);
5641
5642 if (FPT_scvalq(k)) {
5643 currCard->ourId =
5644 ((unsigned char)(i
5645 <<
5646 3)
5647 +
5648 (k &
5649 (unsigned char)7))
5650 & (unsigned char)
5651 0x3F;
5652 FPT_inisci(p_card,
5653 p_port,
5654 p_our_id);
5655 FPT_scamInfo[currCard->
5656 ourId].
5657 state = ID_ASSIGNED;
5658 FPT_scamInfo[currCard->
5659 ourId].
5660 id_string[0]
5661 = SLV_TYPE_CODE0;
5662 assigned_id = 1;
5663 }
5664 }
5665 }
5666 }
5667
5668 else if (i == SET_P_FLAG) {
5669 if (!(FPT_scsendi(p_port,
5670 &FPT_scamInfo[p_our_id].
5671 id_string[0])))
5672 FPT_scamInfo[p_our_id].id_string[0] |=
5673 0x80;
5674 }
5675 } while (!assigned_id);
5676
5677 while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) {
5678 }
5679 }
5680
5681 if (ScamFlg & SCAM_ENABLED) {
5682 FPT_scbusf(p_port);
5683 if (currCard->globalFlags & F_UPDATE_EEPROM) {
5684 FPT_scsavdi(p_card, p_port);
5685 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5686 }
5687 }
5688
5689/*
5690 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5691 {
5692 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5693 (FPT_scamInfo[i].state == LEGACY))
5694 k++;
5695 }
5696
5697 if (k==2)
5698 currCard->globalFlags |= F_SINGLE_DEVICE;
5699 else
5700 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5701*/
5702}
5703
5704/*---------------------------------------------------------------------
5705 *
5706 * Function: FPT_scarb
5707 *
5708 * Description: Gain control of the bus and wait SCAM select time (250ms)
5709 *
5710 *---------------------------------------------------------------------*/
5711
5712static int FPT_scarb(unsigned long p_port, unsigned char p_sel_type)
5713{
5714 if (p_sel_type == INIT_SELTD) {
5715
5716 while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {
5717 }
5718
5719 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL)
5720 return 0;
5721
5722 if (RD_HARPOON(p_port + hp_scsidata_0) != 00)
5723 return 0;
5724
5725 WR_HARPOON(p_port + hp_scsisig,
5726 (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY));
5727
5728 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) {
5729
5730 WR_HARPOON(p_port + hp_scsisig,
5731 (RD_HARPOON(p_port + hp_scsisig) &
5732 ~SCSI_BSY));
5733 return 0;
5734 }
5735
5736 WR_HARPOON(p_port + hp_scsisig,
5737 (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL));
5738
5739 if (RD_HARPOON(p_port + hp_scsidata_0) != 00) {
5740
5741 WR_HARPOON(p_port + hp_scsisig,
5742 (RD_HARPOON(p_port + hp_scsisig) &
5743 ~(SCSI_BSY | SCSI_SEL)));
5744 return 0;
5745 }
5746 }
5747
5748 WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5749 & ~ACTdeassert));
5750 WR_HARPOON(p_port + hp_scsireset, SCAM_EN);
5751 WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5752 WR_HARPOON(p_port + hp_scsidata_1, 0x00);
5753 WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN);
5754
5755 WR_HARPOON(p_port + hp_scsisig,
5756 (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG));
5757
5758 WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig)
5759 & ~SCSI_BSY));
5760
5761 FPT_Wait(p_port, TO_250ms);
5762
5763 return 1;
5764}
5765
5766/*---------------------------------------------------------------------
5767 *
5768 * Function: FPT_scbusf
5769 *
5770 * Description: Release the SCSI bus and disable SCAM selection.
5771 *
5772 *---------------------------------------------------------------------*/
5773
5774static void FPT_scbusf(unsigned long p_port)
5775{
5776 WR_HARPOON(p_port + hp_page_ctrl,
5777 (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
5778
5779 WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5780
5781 WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0)
5782 & ~SCSI_BUS_EN));
5783
5784 WR_HARPOON(p_port + hp_scsisig, 0x00);
5785
5786 WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset)
5787 & ~SCAM_EN));
5788
5789 WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5790 | ACTdeassert));
5791
5792 WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5793
5794 WR_HARPOON(p_port + hp_page_ctrl,
5795 (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE));
5796}
5797
5798/*---------------------------------------------------------------------
5799 *
5800 * Function: FPT_scasid
5801 *
5802 * Description: Assign an ID to all the SCAM devices.
5803 *
5804 *---------------------------------------------------------------------*/
5805
5806static void FPT_scasid(unsigned char p_card, unsigned long p_port)
5807{
5808 unsigned char temp_id_string[ID_STRING_LENGTH];
5809
5810 unsigned char i, k, scam_id;
5811 unsigned char crcBytes[3];
5812 struct nvram_info *pCurrNvRam;
5813 unsigned short *pCrcBytes;
5814
5815 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
5816
5817 i = 0;
5818
5819 while (!i) {
5820
5821 for (k = 0; k < ID_STRING_LENGTH; k++) {
5822 temp_id_string[k] = (unsigned char)0x00;
5823 }
5824
5825 FPT_scxferc(p_port, SYNC_PTRN);
5826 FPT_scxferc(p_port, ASSIGN_ID);
5827
5828 if (!(FPT_sciso(p_port, &temp_id_string[0]))) {
5829 if (pCurrNvRam) {
5830 pCrcBytes = (unsigned short *)&crcBytes[0];
5831 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
5832 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
5833 temp_id_string[1] = crcBytes[2];
5834 temp_id_string[2] = crcBytes[0];
5835 temp_id_string[3] = crcBytes[1];
5836 for (k = 4; k < ID_STRING_LENGTH; k++)
5837 temp_id_string[k] = (unsigned char)0x00;
5838 }
5839 i = FPT_scmachid(p_card, temp_id_string);
5840
5841 if (i == CLR_PRIORITY) {
5842 FPT_scxferc(p_port, MISC_CODE);
5843 FPT_scxferc(p_port, CLR_P_FLAG);
5844 i = 0; /*Not the last ID yet. */
5845 }
5846
5847 else if (i != NO_ID_AVAIL) {
5848 if (i < 8)
5849 FPT_scxferc(p_port, ID_0_7);
5850 else
5851 FPT_scxferc(p_port, ID_8_F);
5852
5853 scam_id = (i & (unsigned char)0x07);
5854
5855 for (k = 1; k < 0x08; k <<= 1)
5856 if (!(k & i))
5857 scam_id += 0x08; /*Count number of zeros in DB0-3. */
5858
5859 FPT_scxferc(p_port, scam_id);
5860
5861 i = 0; /*Not the last ID yet. */
5862 }
5863 }
5864
5865 else {
5866 i = 1;
5867 }
5868
5869 } /*End while */
5870
5871 FPT_scxferc(p_port, SYNC_PTRN);
5872 FPT_scxferc(p_port, CFG_CMPLT);
5873}
5874
5875/*---------------------------------------------------------------------
5876 *
5877 * Function: FPT_scsel
5878 *
5879 * Description: Select all the SCAM devices.
5880 *
5881 *---------------------------------------------------------------------*/
5882
5883static void FPT_scsel(unsigned long p_port)
5884{
5885
5886 WR_HARPOON(p_port + hp_scsisig, SCSI_SEL);
5887 FPT_scwiros(p_port, SCSI_MSG);
5888
5889 WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY));
5890
5891 WR_HARPOON(p_port + hp_scsisig,
5892 (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5893 WR_HARPOON(p_port + hp_scsidata_0,
5894 (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) |
5895 (unsigned char)(BIT(7) + BIT(6))));
5896
5897 WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5898 FPT_scwiros(p_port, SCSI_SEL);
5899
5900 WR_HARPOON(p_port + hp_scsidata_0,
5901 (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) &
5902 ~(unsigned char)BIT(6)));
5903 FPT_scwirod(p_port, BIT(6));
5904
5905 WR_HARPOON(p_port + hp_scsisig,
5906 (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5907}
5908
5909/*---------------------------------------------------------------------
5910 *
5911 * Function: FPT_scxferc
5912 *
5913 * Description: Handshake the p_data (DB4-0) across the bus.
5914 *
5915 *---------------------------------------------------------------------*/
5916
5917static unsigned char FPT_scxferc(unsigned long p_port, unsigned char p_data)
5918{
5919 unsigned char curr_data, ret_data;
5920
5921 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
5922
5923 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5924
5925 curr_data &= ~BIT(7);
5926
5927 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5928
5929 FPT_scwirod(p_port, BIT(7)); /*Wait for DB7 to be released. */
5930 while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ;
5931
5932 ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F);
5933
5934 curr_data |= BIT(6);
5935
5936 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5937
5938 curr_data &= ~BIT(5);
5939
5940 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5941
5942 FPT_scwirod(p_port, BIT(5)); /*Wait for DB5 to be released. */
5943
5944 curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */
5945 curr_data |= BIT(7);
5946
5947 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5948
5949 curr_data &= ~BIT(6);
5950
5951 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5952
5953 FPT_scwirod(p_port, BIT(6)); /*Wait for DB6 to be released. */
5954
5955 return ret_data;
5956}
5957
5958/*---------------------------------------------------------------------
5959 *
5960 * Function: FPT_scsendi
5961 *
5962 * Description: Transfer our Identification string to determine if we
5963 * will be the dominant master.
5964 *
5965 *---------------------------------------------------------------------*/
5966
5967static unsigned char FPT_scsendi(unsigned long p_port,
5968 unsigned char p_id_string[])
5969{
5970 unsigned char ret_data, byte_cnt, bit_cnt, defer;
5971
5972 defer = 0;
5973
5974 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5975
5976 for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) {
5977
5978 if (defer)
5979 ret_data = FPT_scxferc(p_port, 00);
5980
5981 else if (p_id_string[byte_cnt] & bit_cnt)
5982
5983 ret_data = FPT_scxferc(p_port, 02);
5984
5985 else {
5986
5987 ret_data = FPT_scxferc(p_port, 01);
5988 if (ret_data & 02)
5989 defer = 1;
5990 }
5991
5992 if ((ret_data & 0x1C) == 0x10)
5993 return 0x00; /*End of isolation stage, we won! */
5994
5995 if (ret_data & 0x1C)
5996 return 0xFF;
5997
5998 if ((defer) && (!(ret_data & 0x1F)))
5999 return 0x01; /*End of isolation stage, we lost. */
6000
6001 } /*bit loop */
6002
6003 } /*byte loop */
6004
6005 if (defer)
6006 return 0x01; /*We lost */
6007 else
6008 return 0; /*We WON! Yeeessss! */
6009}
6010
6011/*---------------------------------------------------------------------
6012 *
6013 * Function: FPT_sciso
6014 *
6015 * Description: Transfer the Identification string.
6016 *
6017 *---------------------------------------------------------------------*/
6018
6019static unsigned char FPT_sciso(unsigned long p_port,
6020 unsigned char p_id_string[])
6021{
6022 unsigned char ret_data, the_data, byte_cnt, bit_cnt;
6023
6024 the_data = 0;
6025
6026 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
6027
6028 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
6029
6030 ret_data = FPT_scxferc(p_port, 0);
6031
6032 if (ret_data & 0xFC)
6033 return 0xFF;
6034
6035 else {
6036
6037 the_data <<= 1;
6038 if (ret_data & BIT(1)) {
6039 the_data |= 1;
6040 }
6041 }
6042
6043 if ((ret_data & 0x1F) == 0) {
6044/*
6045 if(bit_cnt != 0 || bit_cnt != 8)
6046 {
6047 byte_cnt = 0;
6048 bit_cnt = 0;
6049 FPT_scxferc(p_port, SYNC_PTRN);
6050 FPT_scxferc(p_port, ASSIGN_ID);
6051 continue;
6052 }
6053*/
6054 if (byte_cnt)
6055 return 0x00;
6056 else
6057 return 0xFF;
6058 }
6059
6060 } /*bit loop */
6061
6062 p_id_string[byte_cnt] = the_data;
6063
6064 } /*byte loop */
6065
6066 return 0;
6067}
6068
6069/*---------------------------------------------------------------------
6070 *
6071 * Function: FPT_scwirod
6072 *
6073 * Description: Sample the SCSI data bus making sure the signal has been
6074 * deasserted for the correct number of consecutive samples.
6075 *
6076 *---------------------------------------------------------------------*/
6077
6078static void FPT_scwirod(unsigned long p_port, unsigned char p_data_bit)
6079{
6080 unsigned char i;
6081
6082 i = 0;
6083 while (i < MAX_SCSI_TAR) {
6084
6085 if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit)
6086
6087 i = 0;
6088
6089 else
6090
6091 i++;
6092
6093 }
6094}
6095
6096/*---------------------------------------------------------------------
6097 *
6098 * Function: FPT_scwiros
6099 *
6100 * Description: Sample the SCSI Signal lines making sure the signal has been
6101 * deasserted for the correct number of consecutive samples.
6102 *
6103 *---------------------------------------------------------------------*/
6104
6105static void FPT_scwiros(unsigned long p_port, unsigned char p_data_bit)
6106{
6107 unsigned char i;
6108
6109 i = 0;
6110 while (i < MAX_SCSI_TAR) {
6111
6112 if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit)
6113
6114 i = 0;
6115
6116 else
6117
6118 i++;
6119
6120 }
6121}
6122
6123/*---------------------------------------------------------------------
6124 *
6125 * Function: FPT_scvalq
6126 *
6127 * Description: Make sure we received a valid data byte.
6128 *
6129 *---------------------------------------------------------------------*/
6130
6131static unsigned char FPT_scvalq(unsigned char p_quintet)
6132{
6133 unsigned char count;
6134
6135 for (count = 1; count < 0x08; count <<= 1) {
6136 if (!(p_quintet & count))
6137 p_quintet -= 0x80;
6138 }
6139
6140 if (p_quintet & 0x18)
6141 return 0;
6142
6143 else
6144 return 1;
6145}
6146
6147/*---------------------------------------------------------------------
6148 *
6149 * Function: FPT_scsell
6150 *
6151 * Description: Select the specified device ID using a selection timeout
6152 * less than 4ms. If somebody responds then it is a legacy
6153 * drive and this ID must be marked as such.
6154 *
6155 *---------------------------------------------------------------------*/
6156
6157static unsigned char FPT_scsell(unsigned long p_port, unsigned char targ_id)
6158{
6159 unsigned long i;
6160
6161 WR_HARPOON(p_port + hp_page_ctrl,
6162 (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
6163
6164 ARAM_ACCESS(p_port);
6165
6166 WR_HARPOON(p_port + hp_addstat,
6167 (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER));
6168 WR_HARPOON(p_port + hp_seltimeout, TO_4ms);
6169
6170 for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) {
6171 WRW_HARPOON(i, (MPM_OP + ACOMMAND));
6172 }
6173 WRW_HARPOON(i, (BRH_OP + ALWAYS + NP));
6174
6175 WRW_HARPOON((p_port + hp_intstat),
6176 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6177
6178 WR_HARPOON(p_port + hp_select_id, targ_id);
6179
6180 WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT);
6181 WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6182 WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6183
6184 while (!(RDW_HARPOON((p_port + hp_intstat)) &
6185 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {
6186 }
6187
6188 if (RDW_HARPOON((p_port + hp_intstat)) & RESET)
6189 FPT_Wait(p_port, TO_250ms);
6190
6191 DISABLE_AUTO(p_port);
6192
6193 WR_HARPOON(p_port + hp_addstat,
6194 (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER));
6195 WR_HARPOON(p_port + hp_seltimeout, TO_290ms);
6196
6197 SGRAM_ACCESS(p_port);
6198
6199 if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) {
6200
6201 WRW_HARPOON((p_port + hp_intstat),
6202 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6203
6204 WR_HARPOON(p_port + hp_page_ctrl,
6205 (RD_HARPOON(p_port + hp_page_ctrl) &
6206 ~G_INT_DISABLE));
6207
6208 return 0; /*No legacy device */
6209 }
6210
6211 else {
6212
6213 while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) {
6214 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) {
6215 WR_HARPOON(p_port + hp_scsisig,
6216 (SCSI_ACK + S_ILL_PH));
6217 ACCEPT_MSG(p_port);
6218 }
6219 }
6220
6221 WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1);
6222
6223 WR_HARPOON(p_port + hp_page_ctrl,
6224 (RD_HARPOON(p_port + hp_page_ctrl) &
6225 ~G_INT_DISABLE));
6226
6227 return 1; /*Found one of them oldies! */
6228 }
6229}
6230
6231/*---------------------------------------------------------------------
6232 *
6233 * Function: FPT_scwtsel
6234 *
6235 * Description: Wait to be selected by another SCAM initiator.
6236 *
6237 *---------------------------------------------------------------------*/
6238
6239static void FPT_scwtsel(unsigned long p_port)
6240{
6241 while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) {
6242 }
6243}
6244
6245/*---------------------------------------------------------------------
6246 *
6247 * Function: FPT_inisci
6248 *
6249 * Description: Setup the data Structure with the info from the EEPROM.
6250 *
6251 *---------------------------------------------------------------------*/
6252
6253static void FPT_inisci(unsigned char p_card, unsigned long p_port,
6254 unsigned char p_our_id)
6255{
6256 unsigned char i, k, max_id;
6257 unsigned short ee_data;
6258 struct nvram_info *pCurrNvRam;
6259
6260 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6261
6262 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6263 max_id = 0x08;
6264
6265 else
6266 max_id = 0x10;
6267
6268 if (pCurrNvRam) {
6269 for (i = 0; i < max_id; i++) {
6270
6271 for (k = 0; k < 4; k++)
6272 FPT_scamInfo[i].id_string[k] =
6273 pCurrNvRam->niScamTbl[i][k];
6274 for (k = 4; k < ID_STRING_LENGTH; k++)
6275 FPT_scamInfo[i].id_string[k] =
6276 (unsigned char)0x00;
6277
6278 if (FPT_scamInfo[i].id_string[0] == 0x00)
6279 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6280 else
6281 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6282
6283 }
6284 } else {
6285 for (i = 0; i < max_id; i++) {
6286 for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6287 ee_data =
6288 FPT_utilEERead(p_port,
6289 (unsigned
6290 short)((EE_SCAMBASE / 2) +
6291 (unsigned short)(i *
6292 ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6293 FPT_scamInfo[i].id_string[k] =
6294 (unsigned char)ee_data;
6295 ee_data >>= 8;
6296 FPT_scamInfo[i].id_string[k + 1] =
6297 (unsigned char)ee_data;
6298 }
6299
6300 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6301 (FPT_scamInfo[i].id_string[0] == 0xFF))
6302
6303 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6304
6305 else
6306 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6307
6308 }
6309 }
6310 for (k = 0; k < ID_STRING_LENGTH; k++)
6311 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6312
6313}
6314
6315/*---------------------------------------------------------------------
6316 *
6317 * Function: FPT_scmachid
6318 *
6319 * Description: Match the Device ID string with our values stored in
6320 * the EEPROM.
6321 *
6322 *---------------------------------------------------------------------*/
6323
6324static unsigned char FPT_scmachid(unsigned char p_card,
6325 unsigned char p_id_string[])
6326{
6327
6328 unsigned char i, k, match;
6329
6330 for (i = 0; i < MAX_SCSI_TAR; i++) {
6331
6332 match = 1;
6333
6334 for (k = 0; k < ID_STRING_LENGTH; k++) {
6335 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6336 match = 0;
6337 }
6338
6339 if (match) {
6340 FPT_scamInfo[i].state = ID_ASSIGNED;
6341 return i;
6342 }
6343
6344 }
6345
6346 if (p_id_string[0] & BIT(5))
6347 i = 8;
6348 else
6349 i = MAX_SCSI_TAR;
6350
6351 if (((p_id_string[0] & 0x06) == 0x02)
6352 || ((p_id_string[0] & 0x06) == 0x04))
6353 match = p_id_string[1] & (unsigned char)0x1F;
6354 else
6355 match = 7;
6356
6357 while (i > 0) {
6358 i--;
6359
6360 if (FPT_scamInfo[match].state == ID_UNUSED) {
6361 for (k = 0; k < ID_STRING_LENGTH; k++) {
6362 FPT_scamInfo[match].id_string[k] =
6363 p_id_string[k];
6364 }
6365
6366 FPT_scamInfo[match].state = ID_ASSIGNED;
6367
6368 if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6369 FPT_BL_Card[p_card].globalFlags |=
6370 F_UPDATE_EEPROM;
6371 return match;
6372
6373 }
6374
6375 match--;
6376
6377 if (match == 0xFF) {
6378 if (p_id_string[0] & BIT(5))
6379 match = 7;
6380 else
6381 match = MAX_SCSI_TAR - 1;
6382 }
6383 }
6384
6385 if (p_id_string[0] & BIT(7)) {
6386 return CLR_PRIORITY;
6387 }
6388
6389 if (p_id_string[0] & BIT(5))
6390 i = 8;
6391 else
6392 i = MAX_SCSI_TAR;
6393
6394 if (((p_id_string[0] & 0x06) == 0x02)
6395 || ((p_id_string[0] & 0x06) == 0x04))
6396 match = p_id_string[1] & (unsigned char)0x1F;
6397 else
6398 match = 7;
6399
6400 while (i > 0) {
6401
6402 i--;
6403
6404 if (FPT_scamInfo[match].state == ID_UNASSIGNED) {
6405 for (k = 0; k < ID_STRING_LENGTH; k++) {
6406 FPT_scamInfo[match].id_string[k] =
6407 p_id_string[k];
6408 }
6409
6410 FPT_scamInfo[match].id_string[0] |= BIT(7);
6411 FPT_scamInfo[match].state = ID_ASSIGNED;
6412 if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6413 FPT_BL_Card[p_card].globalFlags |=
6414 F_UPDATE_EEPROM;
6415 return match;
6416
6417 }
6418
6419 match--;
6420
6421 if (match == 0xFF) {
6422 if (p_id_string[0] & BIT(5))
6423 match = 7;
6424 else
6425 match = MAX_SCSI_TAR - 1;
6426 }
6427 }
6428
6429 return NO_ID_AVAIL;
6430}
6431
6432/*---------------------------------------------------------------------
6433 *
6434 * Function: FPT_scsavdi
6435 *
6436 * Description: Save off the device SCAM ID strings.
6437 *
6438 *---------------------------------------------------------------------*/
6439
6440static void FPT_scsavdi(unsigned char p_card, unsigned long p_port)
6441{
6442 unsigned char i, k, max_id;
6443 unsigned short ee_data, sum_data;
6444
6445 sum_data = 0x0000;
6446
6447 for (i = 1; i < EE_SCAMBASE / 2; i++) {
6448 sum_data += FPT_utilEERead(p_port, i);
6449 }
6450
6451 FPT_utilEEWriteOnOff(p_port, 1); /* Enable write access to the EEPROM */
6452
6453 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6454 max_id = 0x08;
6455
6456 else
6457 max_id = 0x10;
6458
6459 for (i = 0; i < max_id; i++) {
6460
6461 for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6462 ee_data = FPT_scamInfo[i].id_string[k + 1];
6463 ee_data <<= 8;
6464 ee_data |= FPT_scamInfo[i].id_string[k];
6465 sum_data += ee_data;
6466 FPT_utilEEWrite(p_port, ee_data,
6467 (unsigned short)((EE_SCAMBASE / 2) +
6468 (unsigned short)(i *
6469 ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6470 }
6471 }
6472
6473 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2);
6474 FPT_utilEEWriteOnOff(p_port, 0); /* Turn off write access */
6475}
6476
6477/*---------------------------------------------------------------------
6478 *
6479 * Function: FPT_XbowInit
6480 *
6481 * Description: Setup the Xbow for normal operation.
6482 *
6483 *---------------------------------------------------------------------*/
6484
6485static void FPT_XbowInit(unsigned long port, unsigned char ScamFlg)
6486{
6487 unsigned char i;
6488
6489 i = RD_HARPOON(port + hp_page_ctrl);
6490 WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE));
6491
6492 WR_HARPOON(port + hp_scsireset, 0x00);
6493 WR_HARPOON(port + hp_portctrl_1, HOST_MODE8);
6494
6495 WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET |
6496 FIFO_CLR));
6497
6498 WR_HARPOON(port + hp_scsireset, SCSI_INI);
6499
6500 WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT);
6501
6502 WR_HARPOON(port + hp_scsisig, 0x00); /* Clear any signals we might */
6503 WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
6504
6505 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
6506
6507 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6508 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6509
6510 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6511 FPT_default_intena |= SCAM_SEL;
6512
6513 WRW_HARPOON((port + hp_intena), FPT_default_intena);
6514
6515 WR_HARPOON(port + hp_seltimeout, TO_290ms);
6516
6517 /* Turn on SCSI_MODE8 for narrow cards to fix the
6518 strapping issue with the DUAL CHANNEL card */
6519 if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD)
6520 WR_HARPOON(port + hp_addstat, SCSI_MODE8);
6521
6522 WR_HARPOON(port + hp_page_ctrl, i);
6523
6524}
6525
6526/*---------------------------------------------------------------------
6527 *
6528 * Function: FPT_BusMasterInit
6529 *
6530 * Description: Initialize the BusMaster for normal operations.
6531 *
6532 *---------------------------------------------------------------------*/
6533
6534static void FPT_BusMasterInit(unsigned long p_port)
6535{
6536
6537 WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST);
6538 WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
6539
6540 WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64);
6541
6542 WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT));
6543
6544 WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H));
6545
6546 RD_HARPOON(p_port + hp_int_status); /*Clear interrupts. */
6547 WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6548 WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) &
6549 ~SCATTER_EN));
6550}
6551
6552/*---------------------------------------------------------------------
6553 *
6554 * Function: FPT_DiagEEPROM
6555 *
6556 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6557 * necessary.
6558 *
6559 *---------------------------------------------------------------------*/
6560
6561static void FPT_DiagEEPROM(unsigned long p_port)
6562{
6563 unsigned short index, temp, max_wd_cnt;
6564
6565 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6566 max_wd_cnt = EEPROM_WD_CNT;
6567 else
6568 max_wd_cnt = EEPROM_WD_CNT * 2;
6569
6570 temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2);
6571
6572 if (temp == 0x4641) {
6573
6574 for (index = 2; index < max_wd_cnt; index++) {
6575
6576 temp += FPT_utilEERead(p_port, index);
6577
6578 }
6579
6580 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) {
6581
6582 return; /*EEPROM is Okay so return now! */
6583 }
6584 }
6585
6586 FPT_utilEEWriteOnOff(p_port, (unsigned char)1);
6587
6588 for (index = 0; index < max_wd_cnt; index++) {
6589
6590 FPT_utilEEWrite(p_port, 0x0000, index);
6591 }
6592
6593 temp = 0;
6594
6595 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2);
6596 temp += 0x4641;
6597 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2);
6598 temp += 0x3920;
6599 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2);
6600 temp += 0x3033;
6601 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2);
6602 temp += 0x2020;
6603 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2);
6604 temp += 0x70D3;
6605 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2);
6606 temp += 0x0010;
6607 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2);
6608 temp += 0x0003;
6609 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2);
6610 temp += 0x0007;
6611
6612 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2);
6613 temp += 0x0000;
6614 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2);
6615 temp += 0x0000;
6616 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2);
6617 temp += 0x0000;
6618
6619 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2);
6620 temp += 0x4242;
6621 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2);
6622 temp += 0x4242;
6623 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2);
6624 temp += 0x4242;
6625 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2);
6626 temp += 0x4242;
6627 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2);
6628 temp += 0x4242;
6629 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2);
6630 temp += 0x4242;
6631 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2);
6632 temp += 0x4242;
6633 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2);
6634 temp += 0x4242;
6635
6636 FPT_utilEEWrite(p_port, 0x6C46, 64 / 2); /*PRODUCT ID */
6637 temp += 0x6C46;
6638 FPT_utilEEWrite(p_port, 0x7361, 66 / 2); /* FlashPoint LT */
6639 temp += 0x7361;
6640 FPT_utilEEWrite(p_port, 0x5068, 68 / 2);
6641 temp += 0x5068;
6642 FPT_utilEEWrite(p_port, 0x696F, 70 / 2);
6643 temp += 0x696F;
6644 FPT_utilEEWrite(p_port, 0x746E, 72 / 2);
6645 temp += 0x746E;
6646 FPT_utilEEWrite(p_port, 0x4C20, 74 / 2);
6647 temp += 0x4C20;
6648 FPT_utilEEWrite(p_port, 0x2054, 76 / 2);
6649 temp += 0x2054;
6650 FPT_utilEEWrite(p_port, 0x2020, 78 / 2);
6651 temp += 0x2020;
6652
6653 index = ((EE_SCAMBASE / 2) + (7 * 16));
6654 FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index);
6655 temp += (0x0700 + TYPE_CODE0);
6656 index++;
6657 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6658 temp += 0x5542; /* BUSLOGIC */
6659 index++;
6660 FPT_utilEEWrite(p_port, 0x4C53, index);
6661 temp += 0x4C53;
6662 index++;
6663 FPT_utilEEWrite(p_port, 0x474F, index);
6664 temp += 0x474F;
6665 index++;
6666 FPT_utilEEWrite(p_port, 0x4349, index);
6667 temp += 0x4349;
6668 index++;
6669 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6670 temp += 0x5442; /* BT- 930 */
6671 index++;
6672 FPT_utilEEWrite(p_port, 0x202D, index);
6673 temp += 0x202D;
6674 index++;
6675 FPT_utilEEWrite(p_port, 0x3339, index);
6676 temp += 0x3339;
6677 index++; /*Serial # */
6678 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6679 temp += 0x2030;
6680 index++;
6681 FPT_utilEEWrite(p_port, 0x5453, index);
6682 temp += 0x5453;
6683 index++;
6684 FPT_utilEEWrite(p_port, 0x5645, index);
6685 temp += 0x5645;
6686 index++;
6687 FPT_utilEEWrite(p_port, 0x2045, index);
6688 temp += 0x2045;
6689 index++;
6690 FPT_utilEEWrite(p_port, 0x202F, index);
6691 temp += 0x202F;
6692 index++;
6693 FPT_utilEEWrite(p_port, 0x4F4A, index);
6694 temp += 0x4F4A;
6695 index++;
6696 FPT_utilEEWrite(p_port, 0x204E, index);
6697 temp += 0x204E;
6698 index++;
6699 FPT_utilEEWrite(p_port, 0x3539, index);
6700 temp += 0x3539;
6701
6702 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2);
6703
6704 FPT_utilEEWriteOnOff(p_port, (unsigned char)0);
6705
6706}
6707
6708/*---------------------------------------------------------------------
6709 *
6710 * Function: Queue Search Select
6711 *
6712 * Description: Try to find a new command to execute.
6713 *
6714 *---------------------------------------------------------------------*/
6715
6716static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
6717 unsigned char p_card)
6718{
6719 unsigned char scan_ptr, lun;
6720 struct sccb_mgr_tar_info *currTar_Info;
6721 struct sccb *pOldSccb;
6722
6723 scan_ptr = pCurrCard->scanIndex;
6724 do {
6725 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6726 if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
6727 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6728 TAG_Q_TRYING)) {
6729 if (currTar_Info->TarSelQ_Cnt != 0) {
6730
6731 scan_ptr++;
6732 if (scan_ptr == MAX_SCSI_TAR)
6733 scan_ptr = 0;
6734
6735 for (lun = 0; lun < MAX_LUN; lun++) {
6736 if (currTar_Info->TarLUNBusy[lun] == 0) {
6737
6738 pCurrCard->currentSCCB =
6739 currTar_Info->TarSelQ_Head;
6740 pOldSccb = NULL;
6741
6742 while ((pCurrCard->
6743 currentSCCB != NULL)
6744 && (lun !=
6745 pCurrCard->
6746 currentSCCB->Lun)) {
6747 pOldSccb =
6748 pCurrCard->
6749 currentSCCB;
6750 pCurrCard->currentSCCB =
6751 (struct sccb
6752 *)(pCurrCard->
6753 currentSCCB)->
6754 Sccb_forwardlink;
6755 }
6756 if (pCurrCard->currentSCCB ==
6757 NULL)
6758 continue;
6759 if (pOldSccb != NULL) {
6760 pOldSccb->
6761 Sccb_forwardlink =
6762 (struct sccb
6763 *)(pCurrCard->
6764 currentSCCB)->
6765 Sccb_forwardlink;
6766 pOldSccb->
6767 Sccb_backlink =
6768 (struct sccb
6769 *)(pCurrCard->
6770 currentSCCB)->
6771 Sccb_backlink;
6772 currTar_Info->
6773 TarSelQ_Cnt--;
6774 } else {
6775 currTar_Info->
6776 TarSelQ_Head =
6777 (struct sccb
6778 *)(pCurrCard->
6779 currentSCCB)->
6780 Sccb_forwardlink;
6781
6782 if (currTar_Info->
6783 TarSelQ_Head ==
6784 NULL) {
6785 currTar_Info->
6786 TarSelQ_Tail
6787 = NULL;
6788 currTar_Info->
6789 TarSelQ_Cnt
6790 = 0;
6791 } else {
6792 currTar_Info->
6793 TarSelQ_Cnt--;
6794 currTar_Info->
6795 TarSelQ_Head->
6796 Sccb_backlink
6797 =
6798 (struct sccb
6799 *)NULL;
6800 }
6801 }
6802 pCurrCard->scanIndex = scan_ptr;
6803
6804 pCurrCard->globalFlags |=
6805 F_NEW_SCCB_CMD;
6806
6807 break;
6808 }
6809 }
6810 }
6811
6812 else {
6813 scan_ptr++;
6814 if (scan_ptr == MAX_SCSI_TAR) {
6815 scan_ptr = 0;
6816 }
6817 }
6818
6819 } else {
6820 if ((currTar_Info->TarSelQ_Cnt != 0) &&
6821 (currTar_Info->TarLUNBusy[0] == 0)) {
6822
6823 pCurrCard->currentSCCB =
6824 currTar_Info->TarSelQ_Head;
6825
6826 currTar_Info->TarSelQ_Head =
6827 (struct sccb *)(pCurrCard->currentSCCB)->
6828 Sccb_forwardlink;
6829
6830 if (currTar_Info->TarSelQ_Head == NULL) {
6831 currTar_Info->TarSelQ_Tail = NULL;
6832 currTar_Info->TarSelQ_Cnt = 0;
6833 } else {
6834 currTar_Info->TarSelQ_Cnt--;
6835 currTar_Info->TarSelQ_Head->
6836 Sccb_backlink = (struct sccb *)NULL;
6837 }
6838
6839 scan_ptr++;
6840 if (scan_ptr == MAX_SCSI_TAR)
6841 scan_ptr = 0;
6842
6843 pCurrCard->scanIndex = scan_ptr;
6844
6845 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6846
6847 break;
6848 }
6849
6850 else {
6851 scan_ptr++;
6852 if (scan_ptr == MAX_SCSI_TAR) {
6853 scan_ptr = 0;
6854 }
6855 }
6856 }
6857 } while (scan_ptr != pCurrCard->scanIndex);
6858}
6859
6860/*---------------------------------------------------------------------
6861 *
6862 * Function: Queue Select Fail
6863 *
6864 * Description: Add the current SCCB to the head of the Queue.
6865 *
6866 *---------------------------------------------------------------------*/
6867
6868static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
6869 unsigned char p_card)
6870{
6871 unsigned char thisTarg;
6872 struct sccb_mgr_tar_info *currTar_Info;
6873
6874 if (pCurrCard->currentSCCB != NULL) {
6875 thisTarg =
6876 (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->
6877 TargID);
6878 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6879
6880 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
6881
6882 pCurrCard->currentSCCB->Sccb_forwardlink =
6883 currTar_Info->TarSelQ_Head;
6884
6885 if (currTar_Info->TarSelQ_Cnt == 0) {
6886 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
6887 }
6888
6889 else {
6890 currTar_Info->TarSelQ_Head->Sccb_backlink =
6891 pCurrCard->currentSCCB;
6892 }
6893
6894 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
6895
6896 pCurrCard->currentSCCB = NULL;
6897 currTar_Info->TarSelQ_Cnt++;
6898 }
6899}
6900
6901/*---------------------------------------------------------------------
6902 *
6903 * Function: Queue Command Complete
6904 *
6905 * Description: Call the callback function with the current SCCB.
6906 *
6907 *---------------------------------------------------------------------*/
6908
6909static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
6910 struct sccb *p_sccb, unsigned char p_card)
6911{
6912
6913 unsigned char i, SCSIcmd;
6914 CALL_BK_FN callback;
6915 struct sccb_mgr_tar_info *currTar_Info;
6916
6917 SCSIcmd = p_sccb->Cdb[0];
6918
6919 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
6920
6921 if ((p_sccb->
6922 ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN))
6923 && (p_sccb->HostStatus == SCCB_COMPLETE)
6924 && (p_sccb->TargetStatus != SSCHECK))
6925
6926 if ((SCSIcmd == SCSI_READ) ||
6927 (SCSIcmd == SCSI_WRITE) ||
6928 (SCSIcmd == SCSI_READ_EXTENDED) ||
6929 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
6930 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
6931 (SCSIcmd == SCSI_START_STOP_UNIT) ||
6932 (pCurrCard->globalFlags & F_NO_FILTER)
6933 )
6934 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
6935 }
6936
6937 if (p_sccb->SccbStatus == SCCB_IN_PROCESS) {
6938 if (p_sccb->HostStatus || p_sccb->TargetStatus)
6939 p_sccb->SccbStatus = SCCB_ERROR;
6940 else
6941 p_sccb->SccbStatus = SCCB_SUCCESS;
6942 }
6943
6944 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
6945
6946 p_sccb->CdbLength = p_sccb->Save_CdbLen;
6947 for (i = 0; i < 6; i++) {
6948 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
6949 }
6950 }
6951
6952 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
6953 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
6954
6955 FPT_utilUpdateResidual(p_sccb);
6956 }
6957
6958 pCurrCard->cmdCounter--;
6959 if (!pCurrCard->cmdCounter) {
6960
6961 if (pCurrCard->globalFlags & F_GREEN_PC) {
6962 WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0,
6963 (PWR_DWN | CLKCTRL_DEFAULT));
6964 WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK);
6965 }
6966
6967 WR_HARPOON(pCurrCard->ioPort + hp_semaphore,
6968 (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) &
6969 ~SCCB_MGR_ACTIVE));
6970
6971 }
6972
6973 if (pCurrCard->discQCount != 0) {
6974 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6975 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
6976 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6977 TAG_Q_TRYING))) {
6978 pCurrCard->discQCount--;
6979 pCurrCard->discQ_Tbl[currTar_Info->
6980 LunDiscQ_Idx[p_sccb->Lun]] = NULL;
6981 } else {
6982 if (p_sccb->Sccb_tag) {
6983 pCurrCard->discQCount--;
6984 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
6985 } else {
6986 pCurrCard->discQCount--;
6987 pCurrCard->discQ_Tbl[currTar_Info->
6988 LunDiscQ_Idx[0]] = NULL;
6989 }
6990 }
6991
6992 }
6993
6994 callback = (CALL_BK_FN) p_sccb->SccbCallback;
6995 callback(p_sccb);
6996 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6997 pCurrCard->currentSCCB = NULL;
6998}
6999
7000/*---------------------------------------------------------------------
7001 *
7002 * Function: Queue Disconnect
7003 *
7004 * Description: Add SCCB to our disconnect array.
7005 *
7006 *---------------------------------------------------------------------*/
7007static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card)
7008{
7009 struct sccb_mgr_tar_info *currTar_Info;
7010
7011 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
7012
7013 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
7014 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
7015 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
7016 LunDiscQ_Idx[p_sccb->Lun]] =
7017 p_sccb;
7018 } else {
7019 if (p_sccb->Sccb_tag) {
7020 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] =
7021 p_sccb;
7022 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] =
7023 0;
7024 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
7025 } else {
7026 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
7027 LunDiscQ_Idx[0]] = p_sccb;
7028 }
7029 }
7030 FPT_BL_Card[p_card].currentSCCB = NULL;
7031}
7032
7033/*---------------------------------------------------------------------
7034 *
7035 * Function: Queue Flush SCCB
7036 *
7037 * Description: Flush all SCCB's back to the host driver for this target.
7038 *
7039 *---------------------------------------------------------------------*/
7040
7041static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
7042{
7043 unsigned char qtag, thisTarg;
7044 struct sccb *currSCCB;
7045 struct sccb_mgr_tar_info *currTar_Info;
7046
7047 currSCCB = FPT_BL_Card[p_card].currentSCCB;
7048 if (currSCCB != NULL) {
7049 thisTarg = (unsigned char)currSCCB->TargID;
7050 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7051
7052 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7053
7054 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7055 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
7056 thisTarg)) {
7057
7058 FPT_BL_Card[p_card].discQ_Tbl[qtag]->
7059 HostStatus = (unsigned char)error_code;
7060
7061 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7062 FPT_BL_Card[p_card].
7063 discQ_Tbl[qtag], p_card);
7064
7065 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7066 currTar_Info->TarTagQ_Cnt--;
7067
7068 }
7069 }
7070 }
7071
7072}
7073
7074/*---------------------------------------------------------------------
7075 *
7076 * Function: Queue Flush Target SCCB
7077 *
7078 * Description: Flush all SCCB's back to the host driver for this target.
7079 *
7080 *---------------------------------------------------------------------*/
7081
7082static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7083 unsigned char error_code)
7084{
7085 unsigned char qtag;
7086 struct sccb_mgr_tar_info *currTar_Info;
7087
7088 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7089
7090 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7091
7092 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7093 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) {
7094
7095 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus =
7096 (unsigned char)error_code;
7097
7098 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7099 FPT_BL_Card[p_card].
7100 discQ_Tbl[qtag], p_card);
7101
7102 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7103 currTar_Info->TarTagQ_Cnt--;
7104
7105 }
7106 }
7107
7108}
7109
7110static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card)
7111{
7112 struct sccb_mgr_tar_info *currTar_Info;
7113 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7114
7115 p_SCCB->Sccb_forwardlink = NULL;
7116
7117 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7118
7119 if (currTar_Info->TarSelQ_Cnt == 0) {
7120
7121 currTar_Info->TarSelQ_Head = p_SCCB;
7122 }
7123
7124 else {
7125
7126 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7127 }
7128
7129 currTar_Info->TarSelQ_Tail = p_SCCB;
7130 currTar_Info->TarSelQ_Cnt++;
7131}
7132
7133/*---------------------------------------------------------------------
7134 *
7135 * Function: Queue Find SCCB
7136 *
7137 * Description: Search the target select Queue for this SCCB, and
7138 * remove it if found.
7139 *
7140 *---------------------------------------------------------------------*/
7141
7142static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
7143 unsigned char p_card)
7144{
7145 struct sccb *q_ptr;
7146 struct sccb_mgr_tar_info *currTar_Info;
7147
7148 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7149
7150 q_ptr = currTar_Info->TarSelQ_Head;
7151
7152 while (q_ptr != NULL) {
7153
7154 if (q_ptr == p_SCCB) {
7155
7156 if (currTar_Info->TarSelQ_Head == q_ptr) {
7157
7158 currTar_Info->TarSelQ_Head =
7159 q_ptr->Sccb_forwardlink;
7160 }
7161
7162 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7163
7164 currTar_Info->TarSelQ_Tail =
7165 q_ptr->Sccb_backlink;
7166 }
7167
7168 if (q_ptr->Sccb_forwardlink != NULL) {
7169 q_ptr->Sccb_forwardlink->Sccb_backlink =
7170 q_ptr->Sccb_backlink;
7171 }
7172
7173 if (q_ptr->Sccb_backlink != NULL) {
7174 q_ptr->Sccb_backlink->Sccb_forwardlink =
7175 q_ptr->Sccb_forwardlink;
7176 }
7177
7178 currTar_Info->TarSelQ_Cnt--;
7179
7180 return 1;
7181 }
7182
7183 else {
7184 q_ptr = q_ptr->Sccb_forwardlink;
7185 }
7186 }
7187
7188 return 0;
7189
7190}
7191
7192/*---------------------------------------------------------------------
7193 *
7194 * Function: Utility Update Residual Count
7195 *
7196 * Description: Update the XferCnt to the remaining byte count.
7197 * If we transferred all the data then just write zero.
7198 * If Non-SG transfer then report Total Cnt - Actual Transfer
7199 * Cnt. For SG transfers add the count fields of all
7200 * remaining SG elements, as well as any partial remaining
7201 * element.
7202 *
7203 *---------------------------------------------------------------------*/
7204
7205static void FPT_utilUpdateResidual(struct sccb *p_SCCB)
7206{
7207 unsigned long partial_cnt;
7208 unsigned int sg_index;
7209 unsigned long *sg_ptr;
7210
7211 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7212
7213 p_SCCB->DataLength = 0x0000;
7214 }
7215
7216 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7217
7218 partial_cnt = 0x0000;
7219
7220 sg_index = p_SCCB->Sccb_sgseg;
7221
7222 sg_ptr = (unsigned long *)p_SCCB->DataPointer;
7223
7224 if (p_SCCB->Sccb_SGoffset) {
7225
7226 partial_cnt = p_SCCB->Sccb_SGoffset;
7227 sg_index++;
7228 }
7229
7230 while (((unsigned long)sg_index *
7231 (unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) {
7232
7233 partial_cnt += *(sg_ptr + (sg_index * 2));
7234 sg_index++;
7235 }
7236
7237 p_SCCB->DataLength = partial_cnt;
7238 }
7239
7240 else {
7241
7242 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7243 }
7244}
7245
7246/*---------------------------------------------------------------------
7247 *
7248 * Function: Wait 1 Second
7249 *
7250 * Description: Wait for 1 second.
7251 *
7252 *---------------------------------------------------------------------*/
7253
7254static void FPT_Wait1Second(unsigned long p_port)
7255{
7256 unsigned char i;
7257
7258 for (i = 0; i < 4; i++) {
7259
7260 FPT_Wait(p_port, TO_250ms);
7261
7262 if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7263 break;
7264
7265 if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7266 break;
7267 }
7268}
7269
7270/*---------------------------------------------------------------------
7271 *
7272 * Function: FPT_Wait
7273 *
7274 * Description: Wait the desired delay.
7275 *
7276 *---------------------------------------------------------------------*/
7277
7278static void FPT_Wait(unsigned long p_port, unsigned char p_delay)
7279{
7280 unsigned char old_timer;
7281 unsigned char green_flag;
7282
7283 old_timer = RD_HARPOON(p_port + hp_seltimeout);
7284
7285 green_flag = RD_HARPOON(p_port + hp_clkctrl_0);
7286 WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
7287
7288 WR_HARPOON(p_port + hp_seltimeout, p_delay);
7289 WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7290 WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT));
7291
7292 WR_HARPOON(p_port + hp_portctrl_0,
7293 (RD_HARPOON(p_port + hp_portctrl_0) | START_TO));
7294
7295 while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) {
7296
7297 if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7298 break;
7299
7300 if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7301 break;
7302 }
7303
7304 WR_HARPOON(p_port + hp_portctrl_0,
7305 (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO));
7306
7307 WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7308 WRW_HARPOON((p_port + hp_intena), FPT_default_intena);
7309
7310 WR_HARPOON(p_port + hp_clkctrl_0, green_flag);
7311
7312 WR_HARPOON(p_port + hp_seltimeout, old_timer);
7313}
7314
7315/*---------------------------------------------------------------------
7316 *
7317 * Function: Enable/Disable Write to EEPROM
7318 *
7319 * Description: The EEPROM must first be enabled for writes
7320 * A total of 9 clocks are needed.
7321 *
7322 *---------------------------------------------------------------------*/
7323
7324static void FPT_utilEEWriteOnOff(unsigned long p_port, unsigned char p_mode)
7325{
7326 unsigned char ee_value;
7327
7328 ee_value =
7329 (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
7330 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7331
7332 if (p_mode)
7333
7334 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7335
7336 else
7337
7338 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7339
7340 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7341 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
7342}
7343
7344/*---------------------------------------------------------------------
7345 *
7346 * Function: Write EEPROM
7347 *
7348 * Description: Write a word to the EEPROM at the specified
7349 * address.
7350 *
7351 *---------------------------------------------------------------------*/
7352
7353static void FPT_utilEEWrite(unsigned long p_port, unsigned short ee_data,
7354 unsigned short ee_addr)
7355{
7356
7357 unsigned char ee_value;
7358 unsigned short i;
7359
7360 ee_value =
7361 (unsigned
7362 char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7363 (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7364
7365 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7366
7367 ee_value |= (SEE_MS + SEE_CS);
7368
7369 for (i = 0x8000; i != 0; i >>= 1) {
7370
7371 if (i & ee_data)
7372 ee_value |= SEE_DO;
7373 else
7374 ee_value &= ~SEE_DO;
7375
7376 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7377 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7378 ee_value |= SEE_CLK; /* Clock data! */
7379 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7380 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7381 ee_value &= ~SEE_CLK;
7382 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7383 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7384 }
7385 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7386 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));
7387
7388 FPT_Wait(p_port, TO_10ms);
7389
7390 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7391 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7392 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /* Turn off Master Select */
7393}
7394
7395/*---------------------------------------------------------------------
7396 *
7397 * Function: Read EEPROM
7398 *
7399 * Description: Read a word from the EEPROM at the desired
7400 * address.
7401 *
7402 *---------------------------------------------------------------------*/
7403
7404static unsigned short FPT_utilEERead(unsigned long p_port,
7405 unsigned short ee_addr)
7406{
7407 unsigned short i, ee_data1, ee_data2;
7408
7409 i = 0;
7410 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7411 do {
7412 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7413
7414 if (ee_data1 == ee_data2)
7415 return ee_data1;
7416
7417 ee_data1 = ee_data2;
7418 i++;
7419
7420 } while (i < 4);
7421
7422 return ee_data1;
7423}
7424
7425/*---------------------------------------------------------------------
7426 *
7427 * Function: Read EEPROM Original
7428 *
7429 * Description: Read a word from the EEPROM at the desired
7430 * address.
7431 *
7432 *---------------------------------------------------------------------*/
7433
7434static unsigned short FPT_utilEEReadOrg(unsigned long p_port,
7435 unsigned short ee_addr)
7436{
7437
7438 unsigned char ee_value;
7439 unsigned short i, ee_data;
7440
7441 ee_value =
7442 (unsigned
7443 char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7444 (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7445
7446 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7447
7448 ee_value |= (SEE_MS + SEE_CS);
7449 ee_data = 0;
7450
7451 for (i = 1; i <= 16; i++) {
7452
7453 ee_value |= SEE_CLK; /* Clock data! */
7454 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7455 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7456 ee_value &= ~SEE_CLK;
7457 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7458 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7459
7460 ee_data <<= 1;
7461
7462 if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI)
7463 ee_data |= 1;
7464 }
7465
7466 ee_value &= ~(SEE_MS + SEE_CS);
7467 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7468 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
7469
7470 return ee_data;
7471}
7472
7473/*---------------------------------------------------------------------
7474 *
7475 * Function: Send EE command and Address to the EEPROM
7476 *
7477 * Description: Transfers the correct command and sends the address
7478 * to the eeprom.
7479 *
7480 *---------------------------------------------------------------------*/
7481
7482static void FPT_utilEESendCmdAddr(unsigned long p_port, unsigned char ee_cmd,
7483 unsigned short ee_addr)
7484{
7485 unsigned char ee_value;
7486 unsigned char narrow_flg;
7487
7488 unsigned short i;
7489
7490 narrow_flg =
7491 (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
7492 NARROW_SCSI_CARD);
7493
7494 ee_value = SEE_MS;
7495 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7496
7497 ee_value |= SEE_CS; /* Set CS to EEPROM */
7498 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7499
7500 for (i = 0x04; i != 0; i >>= 1) {
7501
7502 if (i & ee_cmd)
7503 ee_value |= SEE_DO;
7504 else
7505 ee_value &= ~SEE_DO;
7506
7507 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7508 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7509 ee_value |= SEE_CLK; /* Clock data! */
7510 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7511 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7512 ee_value &= ~SEE_CLK;
7513 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7514 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7515 }
7516
7517 if (narrow_flg)
7518 i = 0x0080;
7519
7520 else
7521 i = 0x0200;
7522
7523 while (i != 0) {
7524
7525 if (i & ee_addr)
7526 ee_value |= SEE_DO;
7527 else
7528 ee_value &= ~SEE_DO;
7529
7530 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7531 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7532 ee_value |= SEE_CLK; /* Clock data! */
7533 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7534 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7535 ee_value &= ~SEE_CLK;
7536 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7537 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7538
7539 i >>= 1;
7540 }
7541}
7542
7543static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7544{
7545 unsigned short crc = 0;
7546 int i, j;
7547 unsigned short ch;
7548 for (i = 0; i < ID_STRING_LENGTH; i++) {
7549 ch = (unsigned short)buffer[i];
7550 for (j = 0; j < 8; j++) {
7551 if ((crc ^ ch) & 1)
7552 crc = (crc >> 1) ^ CRCMASK;
7553 else
7554 crc >>= 1;
7555 ch >>= 1;
7556 }
7557 }
7558 return crc;
7559}
7560
7561static unsigned char FPT_CalcLrc(unsigned char buffer[])
7562{
7563 int i;
7564 unsigned char lrc;
7565 lrc = 0;
7566 for (i = 0; i < ID_STRING_LENGTH; i++)
7567 lrc ^= buffer[i];
7568 return lrc;
7569}
7570
7571/*
7572 The following inline definitions avoid type conflicts.
7573*/
7574
7575static inline unsigned char
7576FlashPoint__ProbeHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7577{
7578 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *)
7579 FlashPointInfo);
7580}
7581
7582static inline FlashPoint_CardHandle_T
7583FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info *FlashPointInfo)
7584{
7585 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *)
7586 FlashPointInfo);
7587}
7588
7589static inline void
7590FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle)
7591{
7592 FlashPoint_ReleaseHostAdapter(CardHandle);
7593}
7594
7595static inline void
7596FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle,
7597 struct BusLogic_CCB *CCB)
7598{
7599 FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB);
7600}
7601
7602static inline void
7603FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle,
7604 struct BusLogic_CCB *CCB)
7605{
7606 FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
7607}
7608
7609static inline bool
7610FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle)
7611{
7612 return FlashPoint_InterruptPending(CardHandle);
7613}
7614
7615static inline int
7616FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
7617{
7618 return FlashPoint_HandleInterrupt(CardHandle);
7619}
7620
7621#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7622#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7623#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7624#define FlashPoint_StartCCB FlashPoint__StartCCB
7625#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7626#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7627#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7628
7629#else /* !CONFIG_SCSI_FLASHPOINT */
7630
7631/*
7632 Define prototypes for the FlashPoint SCCB Manager Functions.
7633*/
7634
7635extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info *);
7636extern FlashPoint_CardHandle_T
7637FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info *);
7638extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7639extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T, struct BusLogic_CCB *);
7640extern bool FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
7641extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
7642extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
7643
7644#endif /* CONFIG_SCSI_FLASHPOINT */
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()
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 WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN)); /*JUMP IF NOT STATUS PHZ. */
4603 map_addr += 2;
4604 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0)); /*GET STATUS BYTE */
4605 map_addr += 2;
4606 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC)); /*ERROR IF NOT MSG IN PHZ */
4607 map_addr += 2;
4608 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4609 map_addr += 2;
4610 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4611 map_addr += 2;
4612 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*GET CMD COMPLETE MSG */
4613 map_addr += 2;
4614 WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP)); /*END OF COMMAND */
4615 map_addr += 2;
4616
4617 WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4618 map_addr += 2;
4619 WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4620 map_addr += 2;
4621 WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4622 map_addr += 2;
4623 WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4624 map_addr += 2; /* DIDN'T GET ONE */
4625 WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG)); /* comp SCSI SEL ID & AR3 */
4626 map_addr += 2;
4627 WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00)); /*SEL ID OK then Conti. */
4628 map_addr += 2;
4629 WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4630
4631 SGRAM_ACCESS(p_port);
4632}
4633
4634/*---------------------------------------------------------------------
4635 *
4636 * Function: Auto Command Complete
4637 *
4638 * Description: Post command back to host and find another command
4639 * to execute.
4640 *
4641 *---------------------------------------------------------------------*/
4642
4643static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
4644{
4645 struct sccb *currSCCB;
4646 unsigned char status_byte;
4647
4648 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4649
4650 status_byte = RD_HARPOON(p_port + hp_gp_reg_0);
4651
4652 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4653
4654 if (status_byte != SSGOOD) {
4655
4656 if (status_byte == SSQ_FULL) {
4657
4658 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4659 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4660 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4661 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4662 TarLUNBusy[currSCCB->Lun] = 1;
4663 if (FPT_BL_Card[p_card].discQCount != 0)
4664 FPT_BL_Card[p_card].discQCount--;
4665 FPT_BL_Card[p_card].
4666 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4667 [currSCCB->TargID].
4668 LunDiscQ_Idx[currSCCB->Lun]] =
4669 NULL;
4670 } else {
4671 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4672 TarLUNBusy[0] = 1;
4673 if (currSCCB->Sccb_tag) {
4674 if (FPT_BL_Card[p_card].discQCount != 0)
4675 FPT_BL_Card[p_card].
4676 discQCount--;
4677 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4678 Sccb_tag]
4679 = NULL;
4680 } else {
4681 if (FPT_BL_Card[p_card].discQCount != 0)
4682 FPT_BL_Card[p_card].
4683 discQCount--;
4684 FPT_BL_Card[p_card].
4685 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4686 [currSCCB->TargID].
4687 LunDiscQ_Idx[0]] = NULL;
4688 }
4689 }
4690
4691 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4692
4693 FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
4694
4695 return;
4696 }
4697
4698 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4699 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4700 (unsigned char)SYNC_SUPPORTED;
4701
4702 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4703 ~EE_SYNC_MASK;
4704 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4705
4706 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4707 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4708 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4709 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4710 TarLUNBusy[currSCCB->Lun] = 1;
4711 if (FPT_BL_Card[p_card].discQCount != 0)
4712 FPT_BL_Card[p_card].discQCount--;
4713 FPT_BL_Card[p_card].
4714 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4715 [currSCCB->TargID].
4716 LunDiscQ_Idx[currSCCB->Lun]] =
4717 NULL;
4718 } else {
4719 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4720 TarLUNBusy[0] = 1;
4721 if (currSCCB->Sccb_tag) {
4722 if (FPT_BL_Card[p_card].discQCount != 0)
4723 FPT_BL_Card[p_card].
4724 discQCount--;
4725 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4726 Sccb_tag]
4727 = NULL;
4728 } else {
4729 if (FPT_BL_Card[p_card].discQCount != 0)
4730 FPT_BL_Card[p_card].
4731 discQCount--;
4732 FPT_BL_Card[p_card].
4733 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4734 [currSCCB->TargID].
4735 LunDiscQ_Idx[0]] = NULL;
4736 }
4737 }
4738 return;
4739
4740 }
4741
4742 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4743
4744 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4745 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4746 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4747
4748 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4749 ~EE_WIDE_SCSI;
4750 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4751
4752 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4753 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4754 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4755 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4756 TarLUNBusy[currSCCB->Lun] = 1;
4757 if (FPT_BL_Card[p_card].discQCount != 0)
4758 FPT_BL_Card[p_card].discQCount--;
4759 FPT_BL_Card[p_card].
4760 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4761 [currSCCB->TargID].
4762 LunDiscQ_Idx[currSCCB->Lun]] =
4763 NULL;
4764 } else {
4765 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4766 TarLUNBusy[0] = 1;
4767 if (currSCCB->Sccb_tag) {
4768 if (FPT_BL_Card[p_card].discQCount != 0)
4769 FPT_BL_Card[p_card].
4770 discQCount--;
4771 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4772 Sccb_tag]
4773 = NULL;
4774 } else {
4775 if (FPT_BL_Card[p_card].discQCount != 0)
4776 FPT_BL_Card[p_card].
4777 discQCount--;
4778 FPT_BL_Card[p_card].
4779 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4780 [currSCCB->TargID].
4781 LunDiscQ_Idx[0]] = NULL;
4782 }
4783 }
4784 return;
4785
4786 }
4787
4788 if (status_byte == SSCHECK) {
4789 if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) {
4790 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4791 TarEEValue & EE_SYNC_MASK) {
4792 FPT_sccbMgrTbl[p_card][currSCCB->
4793 TargID].
4794 TarStatus &= ~TAR_SYNC_MASK;
4795 }
4796 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4797 TarEEValue & EE_WIDE_SCSI) {
4798 FPT_sccbMgrTbl[p_card][currSCCB->
4799 TargID].
4800 TarStatus &= ~TAR_WIDE_MASK;
4801 }
4802 }
4803 }
4804
4805 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
4806
4807 currSCCB->SccbStatus = SCCB_ERROR;
4808 currSCCB->TargetStatus = status_byte;
4809
4810 if (status_byte == SSCHECK) {
4811
4812 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4813 TarLUN_CA = 1;
4814
4815 if (currSCCB->RequestSenseLength !=
4816 NO_AUTO_REQUEST_SENSE) {
4817
4818 if (currSCCB->RequestSenseLength == 0)
4819 currSCCB->RequestSenseLength =
4820 14;
4821
4822 FPT_ssenss(&FPT_BL_Card[p_card]);
4823 FPT_BL_Card[p_card].globalFlags |=
4824 F_NEW_SCCB_CMD;
4825
4826 if (((FPT_BL_Card[p_card].
4827 globalFlags & F_CONLUN_IO)
4828 &&
4829 ((FPT_sccbMgrTbl[p_card]
4830 [currSCCB->TargID].
4831 TarStatus & TAR_TAG_Q_MASK) !=
4832 TAG_Q_TRYING))) {
4833 FPT_sccbMgrTbl[p_card]
4834 [currSCCB->TargID].
4835 TarLUNBusy[currSCCB->Lun] =
4836 1;
4837 if (FPT_BL_Card[p_card].
4838 discQCount != 0)
4839 FPT_BL_Card[p_card].
4840 discQCount--;
4841 FPT_BL_Card[p_card].
4842 discQ_Tbl[FPT_sccbMgrTbl
4843 [p_card]
4844 [currSCCB->
4845 TargID].
4846 LunDiscQ_Idx
4847 [currSCCB->Lun]] =
4848 NULL;
4849 } else {
4850 FPT_sccbMgrTbl[p_card]
4851 [currSCCB->TargID].
4852 TarLUNBusy[0] = 1;
4853 if (currSCCB->Sccb_tag) {
4854 if (FPT_BL_Card[p_card].
4855 discQCount != 0)
4856 FPT_BL_Card
4857 [p_card].
4858 discQCount--;
4859 FPT_BL_Card[p_card].
4860 discQ_Tbl[currSCCB->
4861 Sccb_tag]
4862 = NULL;
4863 } else {
4864 if (FPT_BL_Card[p_card].
4865 discQCount != 0)
4866 FPT_BL_Card
4867 [p_card].
4868 discQCount--;
4869 FPT_BL_Card[p_card].
4870 discQ_Tbl
4871 [FPT_sccbMgrTbl
4872 [p_card][currSCCB->
4873 TargID].
4874 LunDiscQ_Idx[0]] =
4875 NULL;
4876 }
4877 }
4878 return;
4879 }
4880 }
4881 }
4882 }
4883
4884 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4885 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4886 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4887 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->
4888 Lun] = 0;
4889 else
4890 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4891
4892 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4893}
4894
4895#define SHORT_WAIT 0x0000000F
4896#define LONG_WAIT 0x0000FFFFL
4897
4898/*---------------------------------------------------------------------
4899 *
4900 * Function: Data Transfer Processor
4901 *
4902 * Description: This routine performs two tasks.
4903 * (1) Start data transfer by calling HOST_DATA_XFER_START
4904 * function. Once data transfer is started, (2) Depends
4905 * on the type of data transfer mode Scatter/Gather mode
4906 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
4907 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
4908 * data transfer done. In Scatter/Gather mode, this routine
4909 * checks bus master command complete and dual rank busy
4910 * bit to keep chaining SC transfer command. Similarly,
4911 * in Scatter/Gather mode, it checks Sccb_MGRFlag
4912 * (F_HOST_XFER_ACT bit) for data transfer done.
4913 *
4914 *---------------------------------------------------------------------*/
4915
4916static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard)
4917{
4918 struct sccb *currSCCB;
4919
4920 currSCCB = pCurrCard->currentSCCB;
4921
4922 if (currSCCB->Sccb_XferState & F_SG_XFER) {
4923 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
4924 {
4925 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
4926 currSCCB->Sccb_SGoffset = 0x00;
4927 }
4928 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4929
4930 FPT_busMstrSGDataXferStart(port, currSCCB);
4931 }
4932
4933 else {
4934 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) {
4935 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4936
4937 FPT_busMstrDataXferStart(port, currSCCB);
4938 }
4939 }
4940}
4941
4942/*---------------------------------------------------------------------
4943 *
4944 * Function: BusMaster Scatter Gather Data Transfer Start
4945 *
4946 * Description:
4947 *
4948 *---------------------------------------------------------------------*/
4949static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
4950{
4951 u32 count, addr, tmpSGCnt;
4952 unsigned int sg_index;
4953 unsigned char sg_count, i;
4954 u32 reg_offset;
4955 struct blogic_sg_seg *segp;
4956
4957 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)
4958 count = ((u32)HOST_RD_CMD) << 24;
4959 else
4960 count = ((u32)HOST_WRT_CMD) << 24;
4961
4962 sg_count = 0;
4963 tmpSGCnt = 0;
4964 sg_index = pcurrSCCB->Sccb_sgseg;
4965 reg_offset = hp_aramBase;
4966
4967 i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
4968 ~(SGRAM_ARAM | SCATTER_EN));
4969
4970 WR_HARPOON(p_port + hp_page_ctrl, i);
4971
4972 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
4973 ((sg_index * (unsigned int)SG_ELEMENT_SIZE) <
4974 pcurrSCCB->DataLength)) {
4975
4976 segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) +
4977 sg_index;
4978 tmpSGCnt += segp->segbytes;
4979 count |= segp->segbytes;
4980 addr = segp->segdata;
4981
4982 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
4983 addr +=
4984 ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
4985 count =
4986 (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
4987 tmpSGCnt = count & 0x00FFFFFFL;
4988 }
4989
4990 WR_HARP32(p_port, reg_offset, addr);
4991 reg_offset += 4;
4992
4993 WR_HARP32(p_port, reg_offset, count);
4994 reg_offset += 4;
4995
4996 count &= 0xFF000000L;
4997 sg_index++;
4998 sg_count++;
4999
5000 } /*End While */
5001
5002 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5003
5004 WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4));
5005
5006 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5007
5008 WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
5009
5010 WR_HARPOON(p_port + hp_portctrl_0,
5011 (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5012 WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5013 }
5014
5015 else {
5016
5017 if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) &&
5018 (tmpSGCnt & 0x000000001)) {
5019
5020 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5021 tmpSGCnt--;
5022 }
5023
5024 WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
5025
5026 WR_HARPOON(p_port + hp_portctrl_0,
5027 (SCSI_PORT | DMA_PORT | DMA_RD));
5028 WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5029 }
5030
5031 WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN));
5032
5033}
5034
5035/*---------------------------------------------------------------------
5036 *
5037 * Function: BusMaster Data Transfer Start
5038 *
5039 * Description:
5040 *
5041 *---------------------------------------------------------------------*/
5042static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
5043{
5044 u32 addr, count;
5045
5046 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5047
5048 count = pcurrSCCB->Sccb_XferCnt;
5049
5050 addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5051 }
5052
5053 else {
5054 addr = pcurrSCCB->SensePointer;
5055 count = pcurrSCCB->RequestSenseLength;
5056
5057 }
5058
5059 HP_SETUP_ADDR_CNT(p_port, addr, count);
5060
5061 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5062
5063 WR_HARPOON(p_port + hp_portctrl_0,
5064 (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5065 WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5066
5067 WR_HARPOON(p_port + hp_xfer_cmd,
5068 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5069 }
5070
5071 else {
5072
5073 WR_HARPOON(p_port + hp_portctrl_0,
5074 (SCSI_PORT | DMA_PORT | DMA_RD));
5075 WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5076
5077 WR_HARPOON(p_port + hp_xfer_cmd,
5078 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5079
5080 }
5081}
5082
5083/*---------------------------------------------------------------------
5084 *
5085 * Function: BusMaster Timeout Handler
5086 *
5087 * Description: This function is called after a bus master command busy time
5088 * out is detected. This routines issue halt state machine
5089 * with a software time out for command busy. If command busy
5090 * is still asserted at the end of the time out, it issues
5091 * hard abort with another software time out. It hard abort
5092 * command busy is also time out, it'll just give up.
5093 *
5094 *---------------------------------------------------------------------*/
5095static unsigned char FPT_busMstrTimeOut(u32 p_port)
5096{
5097 unsigned long timeout;
5098
5099 timeout = LONG_WAIT;
5100
5101 WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH);
5102
5103 while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED))
5104 && timeout--) {
5105 }
5106
5107 if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5108 WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT);
5109
5110 timeout = LONG_WAIT;
5111 while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY)
5112 && timeout--) {
5113 }
5114 }
5115
5116 RD_HARPOON(p_port + hp_int_status); /*Clear command complete */
5117
5118 if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5119 return 1;
5120 }
5121
5122 else {
5123 return 0;
5124 }
5125}
5126
5127/*---------------------------------------------------------------------
5128 *
5129 * Function: Host Data Transfer Abort
5130 *
5131 * Description: Abort any in progress transfer.
5132 *
5133 *---------------------------------------------------------------------*/
5134static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
5135 struct sccb *pCurrSCCB)
5136{
5137
5138 unsigned long timeout;
5139 unsigned long remain_cnt;
5140 u32 sg_ptr;
5141 struct blogic_sg_seg *segp;
5142
5143 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5144
5145 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5146
5147 if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) {
5148
5149 WR_HARPOON(port + hp_bm_ctrl,
5150 (RD_HARPOON(port + hp_bm_ctrl) |
5151 FLUSH_XFER_CNTR));
5152 timeout = LONG_WAIT;
5153
5154 while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5155 && timeout--) {
5156 }
5157
5158 WR_HARPOON(port + hp_bm_ctrl,
5159 (RD_HARPOON(port + hp_bm_ctrl) &
5160 ~FLUSH_XFER_CNTR));
5161
5162 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5163
5164 if (FPT_busMstrTimeOut(port)) {
5165
5166 if (pCurrSCCB->HostStatus == 0x00)
5167
5168 pCurrSCCB->HostStatus =
5169 SCCB_BM_ERR;
5170
5171 }
5172
5173 if (RD_HARPOON(port + hp_int_status) &
5174 INT_EXT_STATUS)
5175
5176 if (RD_HARPOON(port + hp_ext_status) &
5177 BAD_EXT_STATUS)
5178
5179 if (pCurrSCCB->HostStatus ==
5180 0x00)
5181 {
5182 pCurrSCCB->HostStatus =
5183 SCCB_BM_ERR;
5184 }
5185 }
5186 }
5187 }
5188
5189 else if (pCurrSCCB->Sccb_XferCnt) {
5190
5191 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5192
5193 WR_HARPOON(port + hp_page_ctrl,
5194 (RD_HARPOON(port + hp_page_ctrl) &
5195 ~SCATTER_EN));
5196
5197 WR_HARPOON(port + hp_sg_addr, 0x00);
5198
5199 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5200
5201 if (sg_ptr >
5202 (unsigned int)(pCurrSCCB->DataLength /
5203 SG_ELEMENT_SIZE)) {
5204
5205 sg_ptr = (u32)(pCurrSCCB->DataLength /
5206 SG_ELEMENT_SIZE);
5207 }
5208
5209 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5210
5211 while (remain_cnt < 0x01000000L) {
5212
5213 sg_ptr--;
5214 segp = (struct blogic_sg_seg *)(pCurrSCCB->
5215 DataPointer) + (sg_ptr * 2);
5216 if (remain_cnt > (unsigned long)segp->segbytes)
5217 remain_cnt -=
5218 (unsigned long)segp->segbytes;
5219 else
5220 break;
5221 }
5222
5223 if (remain_cnt < 0x01000000L) {
5224
5225 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5226
5227 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5228
5229 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) ==
5230 pCurrSCCB->DataLength && (remain_cnt == 0))
5231
5232 pCurrSCCB->Sccb_XferState |=
5233 F_ALL_XFERRED;
5234 }
5235
5236 else {
5237
5238 if (pCurrSCCB->HostStatus == 0x00) {
5239
5240 pCurrSCCB->HostStatus =
5241 SCCB_GROSS_FW_ERR;
5242 }
5243 }
5244 }
5245
5246 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5247
5248 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5249
5250 FPT_busMstrTimeOut(port);
5251 }
5252
5253 else {
5254
5255 if (RD_HARPOON(port + hp_int_status) &
5256 INT_EXT_STATUS) {
5257
5258 if (RD_HARPOON(port + hp_ext_status) &
5259 BAD_EXT_STATUS) {
5260
5261 if (pCurrSCCB->HostStatus ==
5262 0x00) {
5263
5264 pCurrSCCB->HostStatus =
5265 SCCB_BM_ERR;
5266 }
5267 }
5268 }
5269
5270 }
5271 }
5272
5273 else {
5274
5275 if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) {
5276
5277 timeout = SHORT_WAIT;
5278
5279 while ((RD_HARPOON(port + hp_ext_status) &
5280 BM_CMD_BUSY)
5281 && ((RD_HARPOON(port + hp_fifo_cnt)) >=
5282 BM_THRESHOLD) && timeout--) {
5283 }
5284 }
5285
5286 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5287
5288 WR_HARPOON(port + hp_bm_ctrl,
5289 (RD_HARPOON(port + hp_bm_ctrl) |
5290 FLUSH_XFER_CNTR));
5291
5292 timeout = LONG_WAIT;
5293
5294 while ((RD_HARPOON(port + hp_ext_status) &
5295 BM_CMD_BUSY) && timeout--) {
5296 }
5297
5298 WR_HARPOON(port + hp_bm_ctrl,
5299 (RD_HARPOON(port + hp_bm_ctrl) &
5300 ~FLUSH_XFER_CNTR));
5301
5302 if (RD_HARPOON(port + hp_ext_status) &
5303 BM_CMD_BUSY) {
5304
5305 if (pCurrSCCB->HostStatus == 0x00) {
5306
5307 pCurrSCCB->HostStatus =
5308 SCCB_BM_ERR;
5309 }
5310
5311 FPT_busMstrTimeOut(port);
5312 }
5313 }
5314
5315 if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5316
5317 if (RD_HARPOON(port + hp_ext_status) &
5318 BAD_EXT_STATUS) {
5319
5320 if (pCurrSCCB->HostStatus == 0x00) {
5321
5322 pCurrSCCB->HostStatus =
5323 SCCB_BM_ERR;
5324 }
5325 }
5326 }
5327 }
5328
5329 }
5330
5331 else {
5332
5333 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5334
5335 timeout = LONG_WAIT;
5336
5337 while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5338 && timeout--) {
5339 }
5340
5341 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5342
5343 if (pCurrSCCB->HostStatus == 0x00) {
5344
5345 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5346 }
5347
5348 FPT_busMstrTimeOut(port);
5349 }
5350 }
5351
5352 if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5353
5354 if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) {
5355
5356 if (pCurrSCCB->HostStatus == 0x00) {
5357
5358 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5359 }
5360 }
5361
5362 }
5363
5364 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5365
5366 WR_HARPOON(port + hp_page_ctrl,
5367 (RD_HARPOON(port + hp_page_ctrl) &
5368 ~SCATTER_EN));
5369
5370 WR_HARPOON(port + hp_sg_addr, 0x00);
5371
5372 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5373
5374 pCurrSCCB->Sccb_SGoffset = 0x00;
5375
5376 if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5377 pCurrSCCB->DataLength) {
5378
5379 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5380 pCurrSCCB->Sccb_sgseg =
5381 (unsigned short)(pCurrSCCB->DataLength /
5382 SG_ELEMENT_SIZE);
5383 }
5384 }
5385
5386 else {
5387 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5388 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5389 }
5390 }
5391
5392 WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
5393}
5394
5395/*---------------------------------------------------------------------
5396 *
5397 * Function: Host Data Transfer Restart
5398 *
5399 * Description: Reset the available count due to a restore data
5400 * pointers message.
5401 *
5402 *---------------------------------------------------------------------*/
5403static void FPT_hostDataXferRestart(struct sccb *currSCCB)
5404{
5405 unsigned long data_count;
5406 unsigned int sg_index;
5407 struct blogic_sg_seg *segp;
5408
5409 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5410
5411 currSCCB->Sccb_XferCnt = 0;
5412
5413 sg_index = 0xffff; /*Index by long words into sg list. */
5414 data_count = 0; /*Running count of SG xfer counts. */
5415
5416
5417 while (data_count < currSCCB->Sccb_ATC) {
5418
5419 sg_index++;
5420 segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) +
5421 (sg_index * 2);
5422 data_count += segp->segbytes;
5423 }
5424
5425 if (data_count == currSCCB->Sccb_ATC) {
5426
5427 currSCCB->Sccb_SGoffset = 0;
5428 sg_index++;
5429 }
5430
5431 else {
5432 currSCCB->Sccb_SGoffset =
5433 data_count - currSCCB->Sccb_ATC;
5434 }
5435
5436 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5437 }
5438
5439 else {
5440 currSCCB->Sccb_XferCnt =
5441 currSCCB->DataLength - currSCCB->Sccb_ATC;
5442 }
5443}
5444
5445/*---------------------------------------------------------------------
5446 *
5447 * Function: FPT_scini
5448 *
5449 * Description: Setup all data structures necessary for SCAM selection.
5450 *
5451 *---------------------------------------------------------------------*/
5452
5453static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
5454 unsigned char p_power_up)
5455{
5456
5457 unsigned char loser, assigned_id;
5458 u32 p_port;
5459
5460 unsigned char i, k, ScamFlg;
5461 struct sccb_card *currCard;
5462 struct nvram_info *pCurrNvRam;
5463
5464 currCard = &FPT_BL_Card[p_card];
5465 p_port = currCard->ioPort;
5466 pCurrNvRam = currCard->pNvRamInfo;
5467
5468 if (pCurrNvRam) {
5469 ScamFlg = pCurrNvRam->niScamConf;
5470 i = pCurrNvRam->niSysConf;
5471 } else {
5472 ScamFlg =
5473 (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2);
5474 i = (unsigned
5475 char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2)));
5476 }
5477 if (!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5478 return;
5479
5480 FPT_inisci(p_card, p_port, p_our_id);
5481
5482 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5483 too slow to return to SCAM selection */
5484
5485 /* if (p_power_up)
5486 FPT_Wait1Second(p_port);
5487 else
5488 FPT_Wait(p_port, TO_250ms); */
5489
5490 FPT_Wait1Second(p_port);
5491
5492 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) {
5493 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5494 }
5495
5496 FPT_scsel(p_port);
5497
5498 do {
5499 FPT_scxferc(p_port, SYNC_PTRN);
5500 FPT_scxferc(p_port, DOM_MSTR);
5501 loser =
5502 FPT_scsendi(p_port,
5503 &FPT_scamInfo[p_our_id].id_string[0]);
5504 } while (loser == 0xFF);
5505
5506 FPT_scbusf(p_port);
5507
5508 if ((p_power_up) && (!loser)) {
5509 FPT_sresb(p_port, p_card);
5510 FPT_Wait(p_port, TO_250ms);
5511
5512 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5513 }
5514
5515 FPT_scsel(p_port);
5516
5517 do {
5518 FPT_scxferc(p_port, SYNC_PTRN);
5519 FPT_scxferc(p_port, DOM_MSTR);
5520 loser =
5521 FPT_scsendi(p_port,
5522 &FPT_scamInfo[p_our_id].
5523 id_string[0]);
5524 } while (loser == 0xFF);
5525
5526 FPT_scbusf(p_port);
5527 }
5528 }
5529
5530 else {
5531 loser = 0;
5532 }
5533
5534 if (!loser) {
5535
5536 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5537
5538 if (ScamFlg & SCAM_ENABLED) {
5539
5540 for (i = 0; i < MAX_SCSI_TAR; i++) {
5541 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5542 (FPT_scamInfo[i].state == ID_UNUSED)) {
5543 if (FPT_scsell(p_port, i)) {
5544 FPT_scamInfo[i].state = LEGACY;
5545 if ((FPT_scamInfo[i].
5546 id_string[0] != 0xFF)
5547 || (FPT_scamInfo[i].
5548 id_string[1] != 0xFA)) {
5549
5550 FPT_scamInfo[i].
5551 id_string[0] = 0xFF;
5552 FPT_scamInfo[i].
5553 id_string[1] = 0xFA;
5554 if (pCurrNvRam == NULL)
5555 currCard->
5556 globalFlags
5557 |=
5558 F_UPDATE_EEPROM;
5559 }
5560 }
5561 }
5562 }
5563
5564 FPT_sresb(p_port, p_card);
5565 FPT_Wait1Second(p_port);
5566 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5567 }
5568 FPT_scsel(p_port);
5569 FPT_scasid(p_card, p_port);
5570 }
5571
5572 }
5573
5574 else if ((loser) && (ScamFlg & SCAM_ENABLED)) {
5575 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5576 assigned_id = 0;
5577 FPT_scwtsel(p_port);
5578
5579 do {
5580 while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) {
5581 }
5582
5583 i = FPT_scxferc(p_port, 0x00);
5584 if (i == ASSIGN_ID) {
5585 if (!
5586 (FPT_scsendi
5587 (p_port,
5588 &FPT_scamInfo[p_our_id].id_string[0]))) {
5589 i = FPT_scxferc(p_port, 0x00);
5590 if (FPT_scvalq(i)) {
5591 k = FPT_scxferc(p_port, 0x00);
5592
5593 if (FPT_scvalq(k)) {
5594 currCard->ourId =
5595 ((unsigned char)(i
5596 <<
5597 3)
5598 +
5599 (k &
5600 (unsigned char)7))
5601 & (unsigned char)
5602 0x3F;
5603 FPT_inisci(p_card,
5604 p_port,
5605 p_our_id);
5606 FPT_scamInfo[currCard->
5607 ourId].
5608 state = ID_ASSIGNED;
5609 FPT_scamInfo[currCard->
5610 ourId].
5611 id_string[0]
5612 = SLV_TYPE_CODE0;
5613 assigned_id = 1;
5614 }
5615 }
5616 }
5617 }
5618
5619 else if (i == SET_P_FLAG) {
5620 if (!(FPT_scsendi(p_port,
5621 &FPT_scamInfo[p_our_id].
5622 id_string[0])))
5623 FPT_scamInfo[p_our_id].id_string[0] |=
5624 0x80;
5625 }
5626 } while (!assigned_id);
5627
5628 while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) {
5629 }
5630 }
5631
5632 if (ScamFlg & SCAM_ENABLED) {
5633 FPT_scbusf(p_port);
5634 if (currCard->globalFlags & F_UPDATE_EEPROM) {
5635 FPT_scsavdi(p_card, p_port);
5636 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5637 }
5638 }
5639
5640/*
5641 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5642 {
5643 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5644 (FPT_scamInfo[i].state == LEGACY))
5645 k++;
5646 }
5647
5648 if (k==2)
5649 currCard->globalFlags |= F_SINGLE_DEVICE;
5650 else
5651 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5652*/
5653}
5654
5655/*---------------------------------------------------------------------
5656 *
5657 * Function: FPT_scarb
5658 *
5659 * Description: Gain control of the bus and wait SCAM select time (250ms)
5660 *
5661 *---------------------------------------------------------------------*/
5662
5663static int FPT_scarb(u32 p_port, unsigned char p_sel_type)
5664{
5665 if (p_sel_type == INIT_SELTD) {
5666
5667 while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {
5668 }
5669
5670 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL)
5671 return 0;
5672
5673 if (RD_HARPOON(p_port + hp_scsidata_0) != 00)
5674 return 0;
5675
5676 WR_HARPOON(p_port + hp_scsisig,
5677 (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY));
5678
5679 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) {
5680
5681 WR_HARPOON(p_port + hp_scsisig,
5682 (RD_HARPOON(p_port + hp_scsisig) &
5683 ~SCSI_BSY));
5684 return 0;
5685 }
5686
5687 WR_HARPOON(p_port + hp_scsisig,
5688 (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL));
5689
5690 if (RD_HARPOON(p_port + hp_scsidata_0) != 00) {
5691
5692 WR_HARPOON(p_port + hp_scsisig,
5693 (RD_HARPOON(p_port + hp_scsisig) &
5694 ~(SCSI_BSY | SCSI_SEL)));
5695 return 0;
5696 }
5697 }
5698
5699 WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5700 & ~ACTdeassert));
5701 WR_HARPOON(p_port + hp_scsireset, SCAM_EN);
5702 WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5703 WR_HARPOON(p_port + hp_scsidata_1, 0x00);
5704 WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN);
5705
5706 WR_HARPOON(p_port + hp_scsisig,
5707 (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG));
5708
5709 WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig)
5710 & ~SCSI_BSY));
5711
5712 FPT_Wait(p_port, TO_250ms);
5713
5714 return 1;
5715}
5716
5717/*---------------------------------------------------------------------
5718 *
5719 * Function: FPT_scbusf
5720 *
5721 * Description: Release the SCSI bus and disable SCAM selection.
5722 *
5723 *---------------------------------------------------------------------*/
5724
5725static void FPT_scbusf(u32 p_port)
5726{
5727 WR_HARPOON(p_port + hp_page_ctrl,
5728 (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
5729
5730 WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5731
5732 WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0)
5733 & ~SCSI_BUS_EN));
5734
5735 WR_HARPOON(p_port + hp_scsisig, 0x00);
5736
5737 WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset)
5738 & ~SCAM_EN));
5739
5740 WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5741 | ACTdeassert));
5742
5743 WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5744
5745 WR_HARPOON(p_port + hp_page_ctrl,
5746 (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE));
5747}
5748
5749/*---------------------------------------------------------------------
5750 *
5751 * Function: FPT_scasid
5752 *
5753 * Description: Assign an ID to all the SCAM devices.
5754 *
5755 *---------------------------------------------------------------------*/
5756
5757static void FPT_scasid(unsigned char p_card, u32 p_port)
5758{
5759 unsigned char temp_id_string[ID_STRING_LENGTH];
5760
5761 unsigned char i, k, scam_id;
5762 unsigned char crcBytes[3];
5763 struct nvram_info *pCurrNvRam;
5764 unsigned short *pCrcBytes;
5765
5766 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
5767
5768 i = 0;
5769
5770 while (!i) {
5771
5772 for (k = 0; k < ID_STRING_LENGTH; k++) {
5773 temp_id_string[k] = (unsigned char)0x00;
5774 }
5775
5776 FPT_scxferc(p_port, SYNC_PTRN);
5777 FPT_scxferc(p_port, ASSIGN_ID);
5778
5779 if (!(FPT_sciso(p_port, &temp_id_string[0]))) {
5780 if (pCurrNvRam) {
5781 pCrcBytes = (unsigned short *)&crcBytes[0];
5782 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
5783 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
5784 temp_id_string[1] = crcBytes[2];
5785 temp_id_string[2] = crcBytes[0];
5786 temp_id_string[3] = crcBytes[1];
5787 for (k = 4; k < ID_STRING_LENGTH; k++)
5788 temp_id_string[k] = (unsigned char)0x00;
5789 }
5790 i = FPT_scmachid(p_card, temp_id_string);
5791
5792 if (i == CLR_PRIORITY) {
5793 FPT_scxferc(p_port, MISC_CODE);
5794 FPT_scxferc(p_port, CLR_P_FLAG);
5795 i = 0; /*Not the last ID yet. */
5796 }
5797
5798 else if (i != NO_ID_AVAIL) {
5799 if (i < 8)
5800 FPT_scxferc(p_port, ID_0_7);
5801 else
5802 FPT_scxferc(p_port, ID_8_F);
5803
5804 scam_id = (i & (unsigned char)0x07);
5805
5806 for (k = 1; k < 0x08; k <<= 1)
5807 if (!(k & i))
5808 scam_id += 0x08; /*Count number of zeros in DB0-3. */
5809
5810 FPT_scxferc(p_port, scam_id);
5811
5812 i = 0; /*Not the last ID yet. */
5813 }
5814 }
5815
5816 else {
5817 i = 1;
5818 }
5819
5820 } /*End while */
5821
5822 FPT_scxferc(p_port, SYNC_PTRN);
5823 FPT_scxferc(p_port, CFG_CMPLT);
5824}
5825
5826/*---------------------------------------------------------------------
5827 *
5828 * Function: FPT_scsel
5829 *
5830 * Description: Select all the SCAM devices.
5831 *
5832 *---------------------------------------------------------------------*/
5833
5834static void FPT_scsel(u32 p_port)
5835{
5836
5837 WR_HARPOON(p_port + hp_scsisig, SCSI_SEL);
5838 FPT_scwiros(p_port, SCSI_MSG);
5839
5840 WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY));
5841
5842 WR_HARPOON(p_port + hp_scsisig,
5843 (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5844 WR_HARPOON(p_port + hp_scsidata_0,
5845 (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) |
5846 (unsigned char)(BIT(7) + BIT(6))));
5847
5848 WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5849 FPT_scwiros(p_port, SCSI_SEL);
5850
5851 WR_HARPOON(p_port + hp_scsidata_0,
5852 (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) &
5853 ~(unsigned char)BIT(6)));
5854 FPT_scwirod(p_port, BIT(6));
5855
5856 WR_HARPOON(p_port + hp_scsisig,
5857 (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5858}
5859
5860/*---------------------------------------------------------------------
5861 *
5862 * Function: FPT_scxferc
5863 *
5864 * Description: Handshake the p_data (DB4-0) across the bus.
5865 *
5866 *---------------------------------------------------------------------*/
5867
5868static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data)
5869{
5870 unsigned char curr_data, ret_data;
5871
5872 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
5873
5874 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5875
5876 curr_data &= ~BIT(7);
5877
5878 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5879
5880 FPT_scwirod(p_port, BIT(7)); /*Wait for DB7 to be released. */
5881 while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ;
5882
5883 ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F);
5884
5885 curr_data |= BIT(6);
5886
5887 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5888
5889 curr_data &= ~BIT(5);
5890
5891 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5892
5893 FPT_scwirod(p_port, BIT(5)); /*Wait for DB5 to be released. */
5894
5895 curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */
5896 curr_data |= BIT(7);
5897
5898 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5899
5900 curr_data &= ~BIT(6);
5901
5902 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5903
5904 FPT_scwirod(p_port, BIT(6)); /*Wait for DB6 to be released. */
5905
5906 return ret_data;
5907}
5908
5909/*---------------------------------------------------------------------
5910 *
5911 * Function: FPT_scsendi
5912 *
5913 * Description: Transfer our Identification string to determine if we
5914 * will be the dominant master.
5915 *
5916 *---------------------------------------------------------------------*/
5917
5918static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[])
5919{
5920 unsigned char ret_data, byte_cnt, bit_cnt, defer;
5921
5922 defer = 0;
5923
5924 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5925
5926 for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) {
5927
5928 if (defer)
5929 ret_data = FPT_scxferc(p_port, 00);
5930
5931 else if (p_id_string[byte_cnt] & bit_cnt)
5932
5933 ret_data = FPT_scxferc(p_port, 02);
5934
5935 else {
5936
5937 ret_data = FPT_scxferc(p_port, 01);
5938 if (ret_data & 02)
5939 defer = 1;
5940 }
5941
5942 if ((ret_data & 0x1C) == 0x10)
5943 return 0x00; /*End of isolation stage, we won! */
5944
5945 if (ret_data & 0x1C)
5946 return 0xFF;
5947
5948 if ((defer) && (!(ret_data & 0x1F)))
5949 return 0x01; /*End of isolation stage, we lost. */
5950
5951 } /*bit loop */
5952
5953 } /*byte loop */
5954
5955 if (defer)
5956 return 0x01; /*We lost */
5957 else
5958 return 0; /*We WON! Yeeessss! */
5959}
5960
5961/*---------------------------------------------------------------------
5962 *
5963 * Function: FPT_sciso
5964 *
5965 * Description: Transfer the Identification string.
5966 *
5967 *---------------------------------------------------------------------*/
5968
5969static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[])
5970{
5971 unsigned char ret_data, the_data, byte_cnt, bit_cnt;
5972
5973 the_data = 0;
5974
5975 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5976
5977 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
5978
5979 ret_data = FPT_scxferc(p_port, 0);
5980
5981 if (ret_data & 0xFC)
5982 return 0xFF;
5983
5984 else {
5985
5986 the_data <<= 1;
5987 if (ret_data & BIT(1)) {
5988 the_data |= 1;
5989 }
5990 }
5991
5992 if ((ret_data & 0x1F) == 0) {
5993/*
5994 if(bit_cnt != 0 || bit_cnt != 8)
5995 {
5996 byte_cnt = 0;
5997 bit_cnt = 0;
5998 FPT_scxferc(p_port, SYNC_PTRN);
5999 FPT_scxferc(p_port, ASSIGN_ID);
6000 continue;
6001 }
6002*/
6003 if (byte_cnt)
6004 return 0x00;
6005 else
6006 return 0xFF;
6007 }
6008
6009 } /*bit loop */
6010
6011 p_id_string[byte_cnt] = the_data;
6012
6013 } /*byte loop */
6014
6015 return 0;
6016}
6017
6018/*---------------------------------------------------------------------
6019 *
6020 * Function: FPT_scwirod
6021 *
6022 * Description: Sample the SCSI data bus making sure the signal has been
6023 * deasserted for the correct number of consecutive samples.
6024 *
6025 *---------------------------------------------------------------------*/
6026
6027static void FPT_scwirod(u32 p_port, unsigned char p_data_bit)
6028{
6029 unsigned char i;
6030
6031 i = 0;
6032 while (i < MAX_SCSI_TAR) {
6033
6034 if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit)
6035
6036 i = 0;
6037
6038 else
6039
6040 i++;
6041
6042 }
6043}
6044
6045/*---------------------------------------------------------------------
6046 *
6047 * Function: FPT_scwiros
6048 *
6049 * Description: Sample the SCSI Signal lines making sure the signal has been
6050 * deasserted for the correct number of consecutive samples.
6051 *
6052 *---------------------------------------------------------------------*/
6053
6054static void FPT_scwiros(u32 p_port, unsigned char p_data_bit)
6055{
6056 unsigned char i;
6057
6058 i = 0;
6059 while (i < MAX_SCSI_TAR) {
6060
6061 if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit)
6062
6063 i = 0;
6064
6065 else
6066
6067 i++;
6068
6069 }
6070}
6071
6072/*---------------------------------------------------------------------
6073 *
6074 * Function: FPT_scvalq
6075 *
6076 * Description: Make sure we received a valid data byte.
6077 *
6078 *---------------------------------------------------------------------*/
6079
6080static unsigned char FPT_scvalq(unsigned char p_quintet)
6081{
6082 unsigned char count;
6083
6084 for (count = 1; count < 0x08; count <<= 1) {
6085 if (!(p_quintet & count))
6086 p_quintet -= 0x80;
6087 }
6088
6089 if (p_quintet & 0x18)
6090 return 0;
6091
6092 else
6093 return 1;
6094}
6095
6096/*---------------------------------------------------------------------
6097 *
6098 * Function: FPT_scsell
6099 *
6100 * Description: Select the specified device ID using a selection timeout
6101 * less than 4ms. If somebody responds then it is a legacy
6102 * drive and this ID must be marked as such.
6103 *
6104 *---------------------------------------------------------------------*/
6105
6106static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id)
6107{
6108 unsigned long i;
6109
6110 WR_HARPOON(p_port + hp_page_ctrl,
6111 (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
6112
6113 ARAM_ACCESS(p_port);
6114
6115 WR_HARPOON(p_port + hp_addstat,
6116 (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER));
6117 WR_HARPOON(p_port + hp_seltimeout, TO_4ms);
6118
6119 for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) {
6120 WRW_HARPOON(i, (MPM_OP + ACOMMAND));
6121 }
6122 WRW_HARPOON(i, (BRH_OP + ALWAYS + NP));
6123
6124 WRW_HARPOON((p_port + hp_intstat),
6125 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6126
6127 WR_HARPOON(p_port + hp_select_id, targ_id);
6128
6129 WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT);
6130 WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6131 WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6132
6133 while (!(RDW_HARPOON((p_port + hp_intstat)) &
6134 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {
6135 }
6136
6137 if (RDW_HARPOON((p_port + hp_intstat)) & RESET)
6138 FPT_Wait(p_port, TO_250ms);
6139
6140 DISABLE_AUTO(p_port);
6141
6142 WR_HARPOON(p_port + hp_addstat,
6143 (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER));
6144 WR_HARPOON(p_port + hp_seltimeout, TO_290ms);
6145
6146 SGRAM_ACCESS(p_port);
6147
6148 if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) {
6149
6150 WRW_HARPOON((p_port + hp_intstat),
6151 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6152
6153 WR_HARPOON(p_port + hp_page_ctrl,
6154 (RD_HARPOON(p_port + hp_page_ctrl) &
6155 ~G_INT_DISABLE));
6156
6157 return 0; /*No legacy device */
6158 }
6159
6160 else {
6161
6162 while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) {
6163 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) {
6164 WR_HARPOON(p_port + hp_scsisig,
6165 (SCSI_ACK + S_ILL_PH));
6166 ACCEPT_MSG(p_port);
6167 }
6168 }
6169
6170 WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1);
6171
6172 WR_HARPOON(p_port + hp_page_ctrl,
6173 (RD_HARPOON(p_port + hp_page_ctrl) &
6174 ~G_INT_DISABLE));
6175
6176 return 1; /*Found one of them oldies! */
6177 }
6178}
6179
6180/*---------------------------------------------------------------------
6181 *
6182 * Function: FPT_scwtsel
6183 *
6184 * Description: Wait to be selected by another SCAM initiator.
6185 *
6186 *---------------------------------------------------------------------*/
6187
6188static void FPT_scwtsel(u32 p_port)
6189{
6190 while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) {
6191 }
6192}
6193
6194/*---------------------------------------------------------------------
6195 *
6196 * Function: FPT_inisci
6197 *
6198 * Description: Setup the data Structure with the info from the EEPROM.
6199 *
6200 *---------------------------------------------------------------------*/
6201
6202static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id)
6203{
6204 unsigned char i, k, max_id;
6205 unsigned short ee_data;
6206 struct nvram_info *pCurrNvRam;
6207
6208 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6209
6210 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6211 max_id = 0x08;
6212
6213 else
6214 max_id = 0x10;
6215
6216 if (pCurrNvRam) {
6217 for (i = 0; i < max_id; i++) {
6218
6219 for (k = 0; k < 4; k++)
6220 FPT_scamInfo[i].id_string[k] =
6221 pCurrNvRam->niScamTbl[i][k];
6222 for (k = 4; k < ID_STRING_LENGTH; k++)
6223 FPT_scamInfo[i].id_string[k] =
6224 (unsigned char)0x00;
6225
6226 if (FPT_scamInfo[i].id_string[0] == 0x00)
6227 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6228 else
6229 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6230
6231 }
6232 } else {
6233 for (i = 0; i < max_id; i++) {
6234 for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6235 ee_data =
6236 FPT_utilEERead(p_port,
6237 (unsigned
6238 short)((EE_SCAMBASE / 2) +
6239 (unsigned short)(i *
6240 ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6241 FPT_scamInfo[i].id_string[k] =
6242 (unsigned char)ee_data;
6243 ee_data >>= 8;
6244 FPT_scamInfo[i].id_string[k + 1] =
6245 (unsigned char)ee_data;
6246 }
6247
6248 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6249 (FPT_scamInfo[i].id_string[0] == 0xFF))
6250
6251 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6252
6253 else
6254 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6255
6256 }
6257 }
6258 for (k = 0; k < ID_STRING_LENGTH; k++)
6259 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6260
6261}
6262
6263/*---------------------------------------------------------------------
6264 *
6265 * Function: FPT_scmachid
6266 *
6267 * Description: Match the Device ID string with our values stored in
6268 * the EEPROM.
6269 *
6270 *---------------------------------------------------------------------*/
6271
6272static unsigned char FPT_scmachid(unsigned char p_card,
6273 unsigned char p_id_string[])
6274{
6275
6276 unsigned char i, k, match;
6277
6278 for (i = 0; i < MAX_SCSI_TAR; i++) {
6279
6280 match = 1;
6281
6282 for (k = 0; k < ID_STRING_LENGTH; k++) {
6283 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6284 match = 0;
6285 }
6286
6287 if (match) {
6288 FPT_scamInfo[i].state = ID_ASSIGNED;
6289 return i;
6290 }
6291
6292 }
6293
6294 if (p_id_string[0] & BIT(5))
6295 i = 8;
6296 else
6297 i = MAX_SCSI_TAR;
6298
6299 if (((p_id_string[0] & 0x06) == 0x02)
6300 || ((p_id_string[0] & 0x06) == 0x04))
6301 match = p_id_string[1] & (unsigned char)0x1F;
6302 else
6303 match = 7;
6304
6305 while (i > 0) {
6306 i--;
6307
6308 if (FPT_scamInfo[match].state == ID_UNUSED) {
6309 for (k = 0; k < ID_STRING_LENGTH; k++) {
6310 FPT_scamInfo[match].id_string[k] =
6311 p_id_string[k];
6312 }
6313
6314 FPT_scamInfo[match].state = ID_ASSIGNED;
6315
6316 if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6317 FPT_BL_Card[p_card].globalFlags |=
6318 F_UPDATE_EEPROM;
6319 return match;
6320
6321 }
6322
6323 match--;
6324
6325 if (match == 0xFF) {
6326 if (p_id_string[0] & BIT(5))
6327 match = 7;
6328 else
6329 match = MAX_SCSI_TAR - 1;
6330 }
6331 }
6332
6333 if (p_id_string[0] & BIT(7)) {
6334 return CLR_PRIORITY;
6335 }
6336
6337 if (p_id_string[0] & BIT(5))
6338 i = 8;
6339 else
6340 i = MAX_SCSI_TAR;
6341
6342 if (((p_id_string[0] & 0x06) == 0x02)
6343 || ((p_id_string[0] & 0x06) == 0x04))
6344 match = p_id_string[1] & (unsigned char)0x1F;
6345 else
6346 match = 7;
6347
6348 while (i > 0) {
6349
6350 i--;
6351
6352 if (FPT_scamInfo[match].state == ID_UNASSIGNED) {
6353 for (k = 0; k < ID_STRING_LENGTH; k++) {
6354 FPT_scamInfo[match].id_string[k] =
6355 p_id_string[k];
6356 }
6357
6358 FPT_scamInfo[match].id_string[0] |= BIT(7);
6359 FPT_scamInfo[match].state = ID_ASSIGNED;
6360 if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6361 FPT_BL_Card[p_card].globalFlags |=
6362 F_UPDATE_EEPROM;
6363 return match;
6364
6365 }
6366
6367 match--;
6368
6369 if (match == 0xFF) {
6370 if (p_id_string[0] & BIT(5))
6371 match = 7;
6372 else
6373 match = MAX_SCSI_TAR - 1;
6374 }
6375 }
6376
6377 return NO_ID_AVAIL;
6378}
6379
6380/*---------------------------------------------------------------------
6381 *
6382 * Function: FPT_scsavdi
6383 *
6384 * Description: Save off the device SCAM ID strings.
6385 *
6386 *---------------------------------------------------------------------*/
6387
6388static void FPT_scsavdi(unsigned char p_card, u32 p_port)
6389{
6390 unsigned char i, k, max_id;
6391 unsigned short ee_data, sum_data;
6392
6393 sum_data = 0x0000;
6394
6395 for (i = 1; i < EE_SCAMBASE / 2; i++) {
6396 sum_data += FPT_utilEERead(p_port, i);
6397 }
6398
6399 FPT_utilEEWriteOnOff(p_port, 1); /* Enable write access to the EEPROM */
6400
6401 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6402 max_id = 0x08;
6403
6404 else
6405 max_id = 0x10;
6406
6407 for (i = 0; i < max_id; i++) {
6408
6409 for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6410 ee_data = FPT_scamInfo[i].id_string[k + 1];
6411 ee_data <<= 8;
6412 ee_data |= FPT_scamInfo[i].id_string[k];
6413 sum_data += ee_data;
6414 FPT_utilEEWrite(p_port, ee_data,
6415 (unsigned short)((EE_SCAMBASE / 2) +
6416 (unsigned short)(i *
6417 ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6418 }
6419 }
6420
6421 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2);
6422 FPT_utilEEWriteOnOff(p_port, 0); /* Turn off write access */
6423}
6424
6425/*---------------------------------------------------------------------
6426 *
6427 * Function: FPT_XbowInit
6428 *
6429 * Description: Setup the Xbow for normal operation.
6430 *
6431 *---------------------------------------------------------------------*/
6432
6433static void FPT_XbowInit(u32 port, unsigned char ScamFlg)
6434{
6435 unsigned char i;
6436
6437 i = RD_HARPOON(port + hp_page_ctrl);
6438 WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE));
6439
6440 WR_HARPOON(port + hp_scsireset, 0x00);
6441 WR_HARPOON(port + hp_portctrl_1, HOST_MODE8);
6442
6443 WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET |
6444 FIFO_CLR));
6445
6446 WR_HARPOON(port + hp_scsireset, SCSI_INI);
6447
6448 WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT);
6449
6450 WR_HARPOON(port + hp_scsisig, 0x00); /* Clear any signals we might */
6451 WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
6452
6453 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
6454
6455 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6456 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6457
6458 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6459 FPT_default_intena |= SCAM_SEL;
6460
6461 WRW_HARPOON((port + hp_intena), FPT_default_intena);
6462
6463 WR_HARPOON(port + hp_seltimeout, TO_290ms);
6464
6465 /* Turn on SCSI_MODE8 for narrow cards to fix the
6466 strapping issue with the DUAL CHANNEL card */
6467 if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD)
6468 WR_HARPOON(port + hp_addstat, SCSI_MODE8);
6469
6470 WR_HARPOON(port + hp_page_ctrl, i);
6471
6472}
6473
6474/*---------------------------------------------------------------------
6475 *
6476 * Function: FPT_BusMasterInit
6477 *
6478 * Description: Initialize the BusMaster for normal operations.
6479 *
6480 *---------------------------------------------------------------------*/
6481
6482static void FPT_BusMasterInit(u32 p_port)
6483{
6484
6485 WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST);
6486 WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
6487
6488 WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64);
6489
6490 WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT));
6491
6492 WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H));
6493
6494 RD_HARPOON(p_port + hp_int_status); /*Clear interrupts. */
6495 WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6496 WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) &
6497 ~SCATTER_EN));
6498}
6499
6500/*---------------------------------------------------------------------
6501 *
6502 * Function: FPT_DiagEEPROM
6503 *
6504 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6505 * necessary.
6506 *
6507 *---------------------------------------------------------------------*/
6508
6509static void FPT_DiagEEPROM(u32 p_port)
6510{
6511 unsigned short index, temp, max_wd_cnt;
6512
6513 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6514 max_wd_cnt = EEPROM_WD_CNT;
6515 else
6516 max_wd_cnt = EEPROM_WD_CNT * 2;
6517
6518 temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2);
6519
6520 if (temp == 0x4641) {
6521
6522 for (index = 2; index < max_wd_cnt; index++) {
6523
6524 temp += FPT_utilEERead(p_port, index);
6525
6526 }
6527
6528 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) {
6529
6530 return; /*EEPROM is Okay so return now! */
6531 }
6532 }
6533
6534 FPT_utilEEWriteOnOff(p_port, (unsigned char)1);
6535
6536 for (index = 0; index < max_wd_cnt; index++) {
6537
6538 FPT_utilEEWrite(p_port, 0x0000, index);
6539 }
6540
6541 temp = 0;
6542
6543 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2);
6544 temp += 0x4641;
6545 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2);
6546 temp += 0x3920;
6547 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2);
6548 temp += 0x3033;
6549 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2);
6550 temp += 0x2020;
6551 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2);
6552 temp += 0x70D3;
6553 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2);
6554 temp += 0x0010;
6555 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2);
6556 temp += 0x0003;
6557 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2);
6558 temp += 0x0007;
6559
6560 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2);
6561 temp += 0x0000;
6562 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2);
6563 temp += 0x0000;
6564 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2);
6565 temp += 0x0000;
6566
6567 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2);
6568 temp += 0x4242;
6569 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2);
6570 temp += 0x4242;
6571 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2);
6572 temp += 0x4242;
6573 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2);
6574 temp += 0x4242;
6575 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2);
6576 temp += 0x4242;
6577 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2);
6578 temp += 0x4242;
6579 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2);
6580 temp += 0x4242;
6581 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2);
6582 temp += 0x4242;
6583
6584 FPT_utilEEWrite(p_port, 0x6C46, 64 / 2); /*PRODUCT ID */
6585 temp += 0x6C46;
6586 FPT_utilEEWrite(p_port, 0x7361, 66 / 2); /* FlashPoint LT */
6587 temp += 0x7361;
6588 FPT_utilEEWrite(p_port, 0x5068, 68 / 2);
6589 temp += 0x5068;
6590 FPT_utilEEWrite(p_port, 0x696F, 70 / 2);
6591 temp += 0x696F;
6592 FPT_utilEEWrite(p_port, 0x746E, 72 / 2);
6593 temp += 0x746E;
6594 FPT_utilEEWrite(p_port, 0x4C20, 74 / 2);
6595 temp += 0x4C20;
6596 FPT_utilEEWrite(p_port, 0x2054, 76 / 2);
6597 temp += 0x2054;
6598 FPT_utilEEWrite(p_port, 0x2020, 78 / 2);
6599 temp += 0x2020;
6600
6601 index = ((EE_SCAMBASE / 2) + (7 * 16));
6602 FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index);
6603 temp += (0x0700 + TYPE_CODE0);
6604 index++;
6605 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6606 temp += 0x5542; /* BUSLOGIC */
6607 index++;
6608 FPT_utilEEWrite(p_port, 0x4C53, index);
6609 temp += 0x4C53;
6610 index++;
6611 FPT_utilEEWrite(p_port, 0x474F, index);
6612 temp += 0x474F;
6613 index++;
6614 FPT_utilEEWrite(p_port, 0x4349, index);
6615 temp += 0x4349;
6616 index++;
6617 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6618 temp += 0x5442; /* BT- 930 */
6619 index++;
6620 FPT_utilEEWrite(p_port, 0x202D, index);
6621 temp += 0x202D;
6622 index++;
6623 FPT_utilEEWrite(p_port, 0x3339, index);
6624 temp += 0x3339;
6625 index++; /*Serial # */
6626 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6627 temp += 0x2030;
6628 index++;
6629 FPT_utilEEWrite(p_port, 0x5453, index);
6630 temp += 0x5453;
6631 index++;
6632 FPT_utilEEWrite(p_port, 0x5645, index);
6633 temp += 0x5645;
6634 index++;
6635 FPT_utilEEWrite(p_port, 0x2045, index);
6636 temp += 0x2045;
6637 index++;
6638 FPT_utilEEWrite(p_port, 0x202F, index);
6639 temp += 0x202F;
6640 index++;
6641 FPT_utilEEWrite(p_port, 0x4F4A, index);
6642 temp += 0x4F4A;
6643 index++;
6644 FPT_utilEEWrite(p_port, 0x204E, index);
6645 temp += 0x204E;
6646 index++;
6647 FPT_utilEEWrite(p_port, 0x3539, index);
6648 temp += 0x3539;
6649
6650 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2);
6651
6652 FPT_utilEEWriteOnOff(p_port, (unsigned char)0);
6653
6654}
6655
6656/*---------------------------------------------------------------------
6657 *
6658 * Function: Queue Search Select
6659 *
6660 * Description: Try to find a new command to execute.
6661 *
6662 *---------------------------------------------------------------------*/
6663
6664static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
6665 unsigned char p_card)
6666{
6667 unsigned char scan_ptr, lun;
6668 struct sccb_mgr_tar_info *currTar_Info;
6669 struct sccb *pOldSccb;
6670
6671 scan_ptr = pCurrCard->scanIndex;
6672 do {
6673 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6674 if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
6675 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6676 TAG_Q_TRYING)) {
6677 if (currTar_Info->TarSelQ_Cnt != 0) {
6678
6679 scan_ptr++;
6680 if (scan_ptr == MAX_SCSI_TAR)
6681 scan_ptr = 0;
6682
6683 for (lun = 0; lun < MAX_LUN; lun++) {
6684 if (currTar_Info->TarLUNBusy[lun] == 0) {
6685
6686 pCurrCard->currentSCCB =
6687 currTar_Info->TarSelQ_Head;
6688 pOldSccb = NULL;
6689
6690 while ((pCurrCard->
6691 currentSCCB != NULL)
6692 && (lun !=
6693 pCurrCard->
6694 currentSCCB->Lun)) {
6695 pOldSccb =
6696 pCurrCard->
6697 currentSCCB;
6698 pCurrCard->currentSCCB =
6699 (struct sccb
6700 *)(pCurrCard->
6701 currentSCCB)->
6702 Sccb_forwardlink;
6703 }
6704 if (pCurrCard->currentSCCB ==
6705 NULL)
6706 continue;
6707 if (pOldSccb != NULL) {
6708 pOldSccb->
6709 Sccb_forwardlink =
6710 (struct sccb
6711 *)(pCurrCard->
6712 currentSCCB)->
6713 Sccb_forwardlink;
6714 pOldSccb->
6715 Sccb_backlink =
6716 (struct sccb
6717 *)(pCurrCard->
6718 currentSCCB)->
6719 Sccb_backlink;
6720 currTar_Info->
6721 TarSelQ_Cnt--;
6722 } else {
6723 currTar_Info->
6724 TarSelQ_Head =
6725 (struct sccb
6726 *)(pCurrCard->
6727 currentSCCB)->
6728 Sccb_forwardlink;
6729
6730 if (currTar_Info->
6731 TarSelQ_Head ==
6732 NULL) {
6733 currTar_Info->
6734 TarSelQ_Tail
6735 = NULL;
6736 currTar_Info->
6737 TarSelQ_Cnt
6738 = 0;
6739 } else {
6740 currTar_Info->
6741 TarSelQ_Cnt--;
6742 currTar_Info->
6743 TarSelQ_Head->
6744 Sccb_backlink
6745 =
6746 (struct sccb
6747 *)NULL;
6748 }
6749 }
6750 pCurrCard->scanIndex = scan_ptr;
6751
6752 pCurrCard->globalFlags |=
6753 F_NEW_SCCB_CMD;
6754
6755 break;
6756 }
6757 }
6758 }
6759
6760 else {
6761 scan_ptr++;
6762 if (scan_ptr == MAX_SCSI_TAR) {
6763 scan_ptr = 0;
6764 }
6765 }
6766
6767 } else {
6768 if ((currTar_Info->TarSelQ_Cnt != 0) &&
6769 (currTar_Info->TarLUNBusy[0] == 0)) {
6770
6771 pCurrCard->currentSCCB =
6772 currTar_Info->TarSelQ_Head;
6773
6774 currTar_Info->TarSelQ_Head =
6775 (struct sccb *)(pCurrCard->currentSCCB)->
6776 Sccb_forwardlink;
6777
6778 if (currTar_Info->TarSelQ_Head == NULL) {
6779 currTar_Info->TarSelQ_Tail = NULL;
6780 currTar_Info->TarSelQ_Cnt = 0;
6781 } else {
6782 currTar_Info->TarSelQ_Cnt--;
6783 currTar_Info->TarSelQ_Head->
6784 Sccb_backlink = (struct sccb *)NULL;
6785 }
6786
6787 scan_ptr++;
6788 if (scan_ptr == MAX_SCSI_TAR)
6789 scan_ptr = 0;
6790
6791 pCurrCard->scanIndex = scan_ptr;
6792
6793 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6794
6795 break;
6796 }
6797
6798 else {
6799 scan_ptr++;
6800 if (scan_ptr == MAX_SCSI_TAR) {
6801 scan_ptr = 0;
6802 }
6803 }
6804 }
6805 } while (scan_ptr != pCurrCard->scanIndex);
6806}
6807
6808/*---------------------------------------------------------------------
6809 *
6810 * Function: Queue Select Fail
6811 *
6812 * Description: Add the current SCCB to the head of the Queue.
6813 *
6814 *---------------------------------------------------------------------*/
6815
6816static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
6817 unsigned char p_card)
6818{
6819 unsigned char thisTarg;
6820 struct sccb_mgr_tar_info *currTar_Info;
6821
6822 if (pCurrCard->currentSCCB != NULL) {
6823 thisTarg =
6824 (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->
6825 TargID);
6826 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6827
6828 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
6829
6830 pCurrCard->currentSCCB->Sccb_forwardlink =
6831 currTar_Info->TarSelQ_Head;
6832
6833 if (currTar_Info->TarSelQ_Cnt == 0) {
6834 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
6835 }
6836
6837 else {
6838 currTar_Info->TarSelQ_Head->Sccb_backlink =
6839 pCurrCard->currentSCCB;
6840 }
6841
6842 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
6843
6844 pCurrCard->currentSCCB = NULL;
6845 currTar_Info->TarSelQ_Cnt++;
6846 }
6847}
6848
6849/*---------------------------------------------------------------------
6850 *
6851 * Function: Queue Command Complete
6852 *
6853 * Description: Call the callback function with the current SCCB.
6854 *
6855 *---------------------------------------------------------------------*/
6856
6857static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
6858 struct sccb *p_sccb, unsigned char p_card)
6859{
6860
6861 unsigned char i, SCSIcmd;
6862 CALL_BK_FN callback;
6863 struct sccb_mgr_tar_info *currTar_Info;
6864
6865 SCSIcmd = p_sccb->Cdb[0];
6866
6867 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
6868
6869 if ((p_sccb->
6870 ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN))
6871 && (p_sccb->HostStatus == SCCB_COMPLETE)
6872 && (p_sccb->TargetStatus != SSCHECK))
6873
6874 if ((SCSIcmd == SCSI_READ) ||
6875 (SCSIcmd == SCSI_WRITE) ||
6876 (SCSIcmd == SCSI_READ_EXTENDED) ||
6877 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
6878 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
6879 (SCSIcmd == SCSI_START_STOP_UNIT) ||
6880 (pCurrCard->globalFlags & F_NO_FILTER)
6881 )
6882 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
6883 }
6884
6885 if (p_sccb->SccbStatus == SCCB_IN_PROCESS) {
6886 if (p_sccb->HostStatus || p_sccb->TargetStatus)
6887 p_sccb->SccbStatus = SCCB_ERROR;
6888 else
6889 p_sccb->SccbStatus = SCCB_SUCCESS;
6890 }
6891
6892 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
6893
6894 p_sccb->CdbLength = p_sccb->Save_CdbLen;
6895 for (i = 0; i < 6; i++) {
6896 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
6897 }
6898 }
6899
6900 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
6901 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
6902
6903 FPT_utilUpdateResidual(p_sccb);
6904 }
6905
6906 pCurrCard->cmdCounter--;
6907 if (!pCurrCard->cmdCounter) {
6908
6909 if (pCurrCard->globalFlags & F_GREEN_PC) {
6910 WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0,
6911 (PWR_DWN | CLKCTRL_DEFAULT));
6912 WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK);
6913 }
6914
6915 WR_HARPOON(pCurrCard->ioPort + hp_semaphore,
6916 (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) &
6917 ~SCCB_MGR_ACTIVE));
6918
6919 }
6920
6921 if (pCurrCard->discQCount != 0) {
6922 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6923 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
6924 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6925 TAG_Q_TRYING))) {
6926 pCurrCard->discQCount--;
6927 pCurrCard->discQ_Tbl[currTar_Info->
6928 LunDiscQ_Idx[p_sccb->Lun]] = NULL;
6929 } else {
6930 if (p_sccb->Sccb_tag) {
6931 pCurrCard->discQCount--;
6932 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
6933 } else {
6934 pCurrCard->discQCount--;
6935 pCurrCard->discQ_Tbl[currTar_Info->
6936 LunDiscQ_Idx[0]] = NULL;
6937 }
6938 }
6939
6940 }
6941
6942 callback = (CALL_BK_FN) p_sccb->SccbCallback;
6943 callback(p_sccb);
6944 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6945 pCurrCard->currentSCCB = NULL;
6946}
6947
6948/*---------------------------------------------------------------------
6949 *
6950 * Function: Queue Disconnect
6951 *
6952 * Description: Add SCCB to our disconnect array.
6953 *
6954 *---------------------------------------------------------------------*/
6955static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card)
6956{
6957 struct sccb_mgr_tar_info *currTar_Info;
6958
6959 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6960
6961 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
6962 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
6963 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6964 LunDiscQ_Idx[p_sccb->Lun]] =
6965 p_sccb;
6966 } else {
6967 if (p_sccb->Sccb_tag) {
6968 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] =
6969 p_sccb;
6970 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] =
6971 0;
6972 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
6973 } else {
6974 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6975 LunDiscQ_Idx[0]] = p_sccb;
6976 }
6977 }
6978 FPT_BL_Card[p_card].currentSCCB = NULL;
6979}
6980
6981/*---------------------------------------------------------------------
6982 *
6983 * Function: Queue Flush SCCB
6984 *
6985 * Description: Flush all SCCB's back to the host driver for this target.
6986 *
6987 *---------------------------------------------------------------------*/
6988
6989static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
6990{
6991 unsigned char qtag, thisTarg;
6992 struct sccb *currSCCB;
6993 struct sccb_mgr_tar_info *currTar_Info;
6994
6995 currSCCB = FPT_BL_Card[p_card].currentSCCB;
6996 if (currSCCB != NULL) {
6997 thisTarg = (unsigned char)currSCCB->TargID;
6998 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6999
7000 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7001
7002 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7003 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
7004 thisTarg)) {
7005
7006 FPT_BL_Card[p_card].discQ_Tbl[qtag]->
7007 HostStatus = (unsigned char)error_code;
7008
7009 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7010 FPT_BL_Card[p_card].
7011 discQ_Tbl[qtag], p_card);
7012
7013 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7014 currTar_Info->TarTagQ_Cnt--;
7015
7016 }
7017 }
7018 }
7019
7020}
7021
7022/*---------------------------------------------------------------------
7023 *
7024 * Function: Queue Flush Target SCCB
7025 *
7026 * Description: Flush all SCCB's back to the host driver for this target.
7027 *
7028 *---------------------------------------------------------------------*/
7029
7030static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7031 unsigned char error_code)
7032{
7033 unsigned char qtag;
7034 struct sccb_mgr_tar_info *currTar_Info;
7035
7036 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7037
7038 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7039
7040 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7041 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) {
7042
7043 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus =
7044 (unsigned char)error_code;
7045
7046 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7047 FPT_BL_Card[p_card].
7048 discQ_Tbl[qtag], p_card);
7049
7050 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7051 currTar_Info->TarTagQ_Cnt--;
7052
7053 }
7054 }
7055
7056}
7057
7058static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card)
7059{
7060 struct sccb_mgr_tar_info *currTar_Info;
7061 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7062
7063 p_SCCB->Sccb_forwardlink = NULL;
7064
7065 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7066
7067 if (currTar_Info->TarSelQ_Cnt == 0) {
7068
7069 currTar_Info->TarSelQ_Head = p_SCCB;
7070 }
7071
7072 else {
7073
7074 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7075 }
7076
7077 currTar_Info->TarSelQ_Tail = p_SCCB;
7078 currTar_Info->TarSelQ_Cnt++;
7079}
7080
7081/*---------------------------------------------------------------------
7082 *
7083 * Function: Queue Find SCCB
7084 *
7085 * Description: Search the target select Queue for this SCCB, and
7086 * remove it if found.
7087 *
7088 *---------------------------------------------------------------------*/
7089
7090static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
7091 unsigned char p_card)
7092{
7093 struct sccb *q_ptr;
7094 struct sccb_mgr_tar_info *currTar_Info;
7095
7096 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7097
7098 q_ptr = currTar_Info->TarSelQ_Head;
7099
7100 while (q_ptr != NULL) {
7101
7102 if (q_ptr == p_SCCB) {
7103
7104 if (currTar_Info->TarSelQ_Head == q_ptr) {
7105
7106 currTar_Info->TarSelQ_Head =
7107 q_ptr->Sccb_forwardlink;
7108 }
7109
7110 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7111
7112 currTar_Info->TarSelQ_Tail =
7113 q_ptr->Sccb_backlink;
7114 }
7115
7116 if (q_ptr->Sccb_forwardlink != NULL) {
7117 q_ptr->Sccb_forwardlink->Sccb_backlink =
7118 q_ptr->Sccb_backlink;
7119 }
7120
7121 if (q_ptr->Sccb_backlink != NULL) {
7122 q_ptr->Sccb_backlink->Sccb_forwardlink =
7123 q_ptr->Sccb_forwardlink;
7124 }
7125
7126 currTar_Info->TarSelQ_Cnt--;
7127
7128 return 1;
7129 }
7130
7131 else {
7132 q_ptr = q_ptr->Sccb_forwardlink;
7133 }
7134 }
7135
7136 return 0;
7137
7138}
7139
7140/*---------------------------------------------------------------------
7141 *
7142 * Function: Utility Update Residual Count
7143 *
7144 * Description: Update the XferCnt to the remaining byte count.
7145 * If we transferred all the data then just write zero.
7146 * If Non-SG transfer then report Total Cnt - Actual Transfer
7147 * Cnt. For SG transfers add the count fields of all
7148 * remaining SG elements, as well as any partial remaining
7149 * element.
7150 *
7151 *---------------------------------------------------------------------*/
7152
7153static void FPT_utilUpdateResidual(struct sccb *p_SCCB)
7154{
7155 unsigned long partial_cnt;
7156 unsigned int sg_index;
7157 struct blogic_sg_seg *segp;
7158
7159 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7160
7161 p_SCCB->DataLength = 0x0000;
7162 }
7163
7164 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7165
7166 partial_cnt = 0x0000;
7167
7168 sg_index = p_SCCB->Sccb_sgseg;
7169
7170
7171 if (p_SCCB->Sccb_SGoffset) {
7172
7173 partial_cnt = p_SCCB->Sccb_SGoffset;
7174 sg_index++;
7175 }
7176
7177 while (((unsigned long)sg_index *
7178 (unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) {
7179 segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) +
7180 (sg_index * 2);
7181 partial_cnt += segp->segbytes;
7182 sg_index++;
7183 }
7184
7185 p_SCCB->DataLength = partial_cnt;
7186 }
7187
7188 else {
7189
7190 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7191 }
7192}
7193
7194/*---------------------------------------------------------------------
7195 *
7196 * Function: Wait 1 Second
7197 *
7198 * Description: Wait for 1 second.
7199 *
7200 *---------------------------------------------------------------------*/
7201
7202static void FPT_Wait1Second(u32 p_port)
7203{
7204 unsigned char i;
7205
7206 for (i = 0; i < 4; i++) {
7207
7208 FPT_Wait(p_port, TO_250ms);
7209
7210 if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7211 break;
7212
7213 if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7214 break;
7215 }
7216}
7217
7218/*---------------------------------------------------------------------
7219 *
7220 * Function: FPT_Wait
7221 *
7222 * Description: Wait the desired delay.
7223 *
7224 *---------------------------------------------------------------------*/
7225
7226static void FPT_Wait(u32 p_port, unsigned char p_delay)
7227{
7228 unsigned char old_timer;
7229 unsigned char green_flag;
7230
7231 old_timer = RD_HARPOON(p_port + hp_seltimeout);
7232
7233 green_flag = RD_HARPOON(p_port + hp_clkctrl_0);
7234 WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
7235
7236 WR_HARPOON(p_port + hp_seltimeout, p_delay);
7237 WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7238 WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT));
7239
7240 WR_HARPOON(p_port + hp_portctrl_0,
7241 (RD_HARPOON(p_port + hp_portctrl_0) | START_TO));
7242
7243 while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) {
7244
7245 if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7246 break;
7247
7248 if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7249 break;
7250 }
7251
7252 WR_HARPOON(p_port + hp_portctrl_0,
7253 (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO));
7254
7255 WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7256 WRW_HARPOON((p_port + hp_intena), FPT_default_intena);
7257
7258 WR_HARPOON(p_port + hp_clkctrl_0, green_flag);
7259
7260 WR_HARPOON(p_port + hp_seltimeout, old_timer);
7261}
7262
7263/*---------------------------------------------------------------------
7264 *
7265 * Function: Enable/Disable Write to EEPROM
7266 *
7267 * Description: The EEPROM must first be enabled for writes
7268 * A total of 9 clocks are needed.
7269 *
7270 *---------------------------------------------------------------------*/
7271
7272static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode)
7273{
7274 unsigned char ee_value;
7275
7276 ee_value =
7277 (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
7278 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7279
7280 if (p_mode)
7281
7282 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7283
7284 else
7285
7286 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7287
7288 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7289 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
7290}
7291
7292/*---------------------------------------------------------------------
7293 *
7294 * Function: Write EEPROM
7295 *
7296 * Description: Write a word to the EEPROM at the specified
7297 * address.
7298 *
7299 *---------------------------------------------------------------------*/
7300
7301static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
7302 unsigned short ee_addr)
7303{
7304
7305 unsigned char ee_value;
7306 unsigned short i;
7307
7308 ee_value =
7309 (unsigned
7310 char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7311 (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7312
7313 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7314
7315 ee_value |= (SEE_MS + SEE_CS);
7316
7317 for (i = 0x8000; i != 0; i >>= 1) {
7318
7319 if (i & ee_data)
7320 ee_value |= SEE_DO;
7321 else
7322 ee_value &= ~SEE_DO;
7323
7324 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7325 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7326 ee_value |= SEE_CLK; /* Clock data! */
7327 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7328 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7329 ee_value &= ~SEE_CLK;
7330 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7331 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7332 }
7333 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7334 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));
7335
7336 FPT_Wait(p_port, TO_10ms);
7337
7338 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7339 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7340 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /* Turn off Master Select */
7341}
7342
7343/*---------------------------------------------------------------------
7344 *
7345 * Function: Read EEPROM
7346 *
7347 * Description: Read a word from the EEPROM at the desired
7348 * address.
7349 *
7350 *---------------------------------------------------------------------*/
7351
7352static unsigned short FPT_utilEERead(u32 p_port,
7353 unsigned short ee_addr)
7354{
7355 unsigned short i, ee_data1, ee_data2;
7356
7357 i = 0;
7358 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7359 do {
7360 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7361
7362 if (ee_data1 == ee_data2)
7363 return ee_data1;
7364
7365 ee_data1 = ee_data2;
7366 i++;
7367
7368 } while (i < 4);
7369
7370 return ee_data1;
7371}
7372
7373/*---------------------------------------------------------------------
7374 *
7375 * Function: Read EEPROM Original
7376 *
7377 * Description: Read a word from the EEPROM at the desired
7378 * address.
7379 *
7380 *---------------------------------------------------------------------*/
7381
7382static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr)
7383{
7384
7385 unsigned char ee_value;
7386 unsigned short i, ee_data;
7387
7388 ee_value =
7389 (unsigned
7390 char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7391 (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7392
7393 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7394
7395 ee_value |= (SEE_MS + SEE_CS);
7396 ee_data = 0;
7397
7398 for (i = 1; i <= 16; i++) {
7399
7400 ee_value |= SEE_CLK; /* Clock data! */
7401 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7402 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7403 ee_value &= ~SEE_CLK;
7404 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7405 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7406
7407 ee_data <<= 1;
7408
7409 if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI)
7410 ee_data |= 1;
7411 }
7412
7413 ee_value &= ~(SEE_MS + SEE_CS);
7414 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7415 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
7416
7417 return ee_data;
7418}
7419
7420/*---------------------------------------------------------------------
7421 *
7422 * Function: Send EE command and Address to the EEPROM
7423 *
7424 * Description: Transfers the correct command and sends the address
7425 * to the eeprom.
7426 *
7427 *---------------------------------------------------------------------*/
7428
7429static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
7430 unsigned short ee_addr)
7431{
7432 unsigned char ee_value;
7433 unsigned char narrow_flg;
7434
7435 unsigned short i;
7436
7437 narrow_flg =
7438 (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
7439 NARROW_SCSI_CARD);
7440
7441 ee_value = SEE_MS;
7442 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7443
7444 ee_value |= SEE_CS; /* Set CS to EEPROM */
7445 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7446
7447 for (i = 0x04; i != 0; i >>= 1) {
7448
7449 if (i & ee_cmd)
7450 ee_value |= SEE_DO;
7451 else
7452 ee_value &= ~SEE_DO;
7453
7454 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7455 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7456 ee_value |= SEE_CLK; /* Clock data! */
7457 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7458 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7459 ee_value &= ~SEE_CLK;
7460 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7461 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7462 }
7463
7464 if (narrow_flg)
7465 i = 0x0080;
7466
7467 else
7468 i = 0x0200;
7469
7470 while (i != 0) {
7471
7472 if (i & ee_addr)
7473 ee_value |= SEE_DO;
7474 else
7475 ee_value &= ~SEE_DO;
7476
7477 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7478 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7479 ee_value |= SEE_CLK; /* Clock data! */
7480 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7481 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7482 ee_value &= ~SEE_CLK;
7483 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7484 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7485
7486 i >>= 1;
7487 }
7488}
7489
7490static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7491{
7492 unsigned short crc = 0;
7493 int i, j;
7494 unsigned short ch;
7495 for (i = 0; i < ID_STRING_LENGTH; i++) {
7496 ch = (unsigned short)buffer[i];
7497 for (j = 0; j < 8; j++) {
7498 if ((crc ^ ch) & 1)
7499 crc = (crc >> 1) ^ CRCMASK;
7500 else
7501 crc >>= 1;
7502 ch >>= 1;
7503 }
7504 }
7505 return crc;
7506}
7507
7508static unsigned char FPT_CalcLrc(unsigned char buffer[])
7509{
7510 int i;
7511 unsigned char lrc;
7512 lrc = 0;
7513 for (i = 0; i < ID_STRING_LENGTH; i++)
7514 lrc ^= buffer[i];
7515 return lrc;
7516}
7517
7518/*
7519 The following inline definitions avoid type conflicts.
7520*/
7521
7522static inline unsigned char
7523FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo)
7524{
7525 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *)
7526 FlashPointInfo);
7527}
7528
7529static inline void *
7530FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo)
7531{
7532 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *)
7533 FlashPointInfo);
7534}
7535
7536static inline void
7537FlashPoint__ReleaseHostAdapter(void *CardHandle)
7538{
7539 FlashPoint_ReleaseHostAdapter(CardHandle);
7540}
7541
7542static inline void
7543FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB)
7544{
7545 FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB);
7546}
7547
7548static inline void
7549FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB)
7550{
7551 FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
7552}
7553
7554static inline bool
7555FlashPoint__InterruptPending(void *CardHandle)
7556{
7557 return FlashPoint_InterruptPending(CardHandle);
7558}
7559
7560static inline int
7561FlashPoint__HandleInterrupt(void *CardHandle)
7562{
7563 return FlashPoint_HandleInterrupt(CardHandle);
7564}
7565
7566#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7567#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7568#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7569#define FlashPoint_StartCCB FlashPoint__StartCCB
7570#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7571#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7572#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7573
7574#else /* !CONFIG_SCSI_FLASHPOINT */
7575
7576/*
7577 Define prototypes for the FlashPoint SCCB Manager Functions.
7578*/
7579
7580extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *);
7581extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *);
7582extern void FlashPoint_StartCCB(void *, struct blogic_ccb *);
7583extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *);
7584extern bool FlashPoint_InterruptPending(void *);
7585extern int FlashPoint_HandleInterrupt(void *);
7586extern void FlashPoint_ReleaseHostAdapter(void *);
7587
7588#endif /* CONFIG_SCSI_FLASHPOINT */