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 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_mflags;
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
308#define SMIDENT 0x80
309#define DISC_PRIV 0x40
310
311#define SM8BIT 0x00
312#define SM16BIT 0x01
313
314#define SIX_BYTE_CMD 0x06
315#define TWELVE_BYTE_CMD 0x0C
316
317#define ASYNC 0x00
318#define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
319
320#define EEPROM_WD_CNT 256
321
322#define EEPROM_CHECK_SUM 0
323#define FW_SIGNATURE 2
324#define MODEL_NUMB_0 4
325#define MODEL_NUMB_2 6
326#define MODEL_NUMB_4 8
327#define SYSTEM_CONFIG 16
328#define SCSI_CONFIG 17
329#define BIOS_CONFIG 18
330#define SCAM_CONFIG 20
331#define ADAPTER_SCSI_ID 24
332
333#define IGNORE_B_SCAN 32
334#define SEND_START_ENA 34
335#define DEVICE_ENABLE 36
336
337#define SYNC_RATE_TBL 38
338#define SYNC_RATE_TBL01 38
339#define SYNC_RATE_TBL23 40
340#define SYNC_RATE_TBL45 42
341#define SYNC_RATE_TBL67 44
342#define SYNC_RATE_TBL89 46
343#define SYNC_RATE_TBLab 48
344#define SYNC_RATE_TBLcd 50
345#define SYNC_RATE_TBLef 52
346
347#define EE_SCAMBASE 256
348
349#define SCAM_ENABLED BIT(2)
350#define SCAM_LEVEL2 BIT(3)
351
352#define RENEGO_ENA BIT(10)
353#define CONNIO_ENA BIT(11)
354#define GREEN_PC_ENA BIT(12)
355
356#define AUTO_RATE_00 00
357#define AUTO_RATE_05 01
358#define AUTO_RATE_10 02
359#define AUTO_RATE_20 03
360
361#define WIDE_NEGO_BIT BIT(7)
362#define DISC_ENABLE_BIT BIT(6)
363
364#define hp_vendor_id_0 0x00 /* LSB */
365#define ORION_VEND_0 0x4B
366
367#define hp_vendor_id_1 0x01 /* MSB */
368#define ORION_VEND_1 0x10
369
370#define hp_device_id_0 0x02 /* LSB */
371#define ORION_DEV_0 0x30
372
373#define hp_device_id_1 0x03 /* MSB */
374#define ORION_DEV_1 0x81
375
376 /* Sub Vendor ID and Sub Device ID only available in
377 Harpoon Version 2 and higher */
378
379#define hp_sub_device_id_0 0x06 /* LSB */
380
381#define hp_semaphore 0x0C
382#define SCCB_MGR_ACTIVE BIT(0)
383#define TICKLE_ME BIT(1)
384#define SCCB_MGR_PRESENT BIT(3)
385#define BIOS_IN_USE BIT(4)
386
387#define hp_sys_ctrl 0x0F
388
389#define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
390#define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
391#define HALT_MACH BIT(3) /*Halt State Machine */
392#define HARD_ABORT BIT(4) /*Hard Abort */
393
394#define hp_host_blk_cnt 0x13
395
396#define XFER_BLK64 0x06 /* 1 1 0 64 byte per block */
397
398#define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes */
399
400#define hp_int_mask 0x17
401
402#define INT_CMD_COMPL BIT(0) /* DMA command complete */
403#define INT_EXT_STATUS BIT(1) /* Extended Status Set */
404
405#define hp_xfer_cnt_lo 0x18
406#define hp_xfer_cnt_hi 0x1A
407#define hp_xfer_cmd 0x1B
408
409#define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
410#define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
411
412#define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
413
414#define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
415
416#define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
417
418#define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
419#define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
420
421#define hp_host_addr_lo 0x1C
422#define hp_host_addr_hmi 0x1E
423
424#define hp_ee_ctrl 0x22
425
426#define EXT_ARB_ACK BIT(7)
427#define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
428#define SEE_MS BIT(5)
429#define SEE_CS BIT(3)
430#define SEE_CLK BIT(2)
431#define SEE_DO BIT(1)
432#define SEE_DI BIT(0)
433
434#define EE_READ 0x06
435#define EE_WRITE 0x05
436#define EWEN 0x04
437#define EWEN_ADDR 0x03C0
438#define EWDS 0x04
439#define EWDS_ADDR 0x0000
440
441#define hp_bm_ctrl 0x26
442
443#define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
444#define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
445#define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
446#define FAST_SINGLE BIT(6) /*?? */
447
448#define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
449
450#define hp_sg_addr 0x28
451#define hp_page_ctrl 0x29
452
453#define SCATTER_EN BIT(0)
454#define SGRAM_ARAM BIT(1)
455#define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
456#define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
457
458#define hp_pci_stat_cfg 0x2D
459
460#define REC_MASTER_ABORT BIT(5) /*received Master abort */
461
462#define hp_rev_num 0x33
463
464#define hp_stack_data 0x34
465#define hp_stack_addr 0x35
466
467#define hp_ext_status 0x36
468
469#define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
470#define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
471#define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
472#define CMD_ABORTED BIT(4) /*Command aborted */
473#define BM_PARITY_ERR BIT(5) /*parity error on data received */
474#define PIO_OVERRUN BIT(6) /*Slave data overrun */
475#define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
476#define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
477 BM_PARITY_ERR | PIO_OVERRUN)
478
479#define hp_int_status 0x37
480
481#define EXT_STATUS_ON BIT(1) /*Extended status is valid */
482#define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
483#define INT_ASSERTED BIT(5) /* */
484
485#define hp_fifo_cnt 0x38
486
487#define hp_intena 0x40
488
489#define RESET BIT(7)
490#define PROG_HLT BIT(6)
491#define PARITY BIT(5)
492#define FIFO BIT(4)
493#define SEL BIT(3)
494#define SCAM_SEL BIT(2)
495#define RSEL BIT(1)
496#define TIMEOUT BIT(0)
497#define BUS_FREE BIT(15)
498#define XFER_CNT_0 BIT(14)
499#define PHASE BIT(13)
500#define IUNKWN BIT(12)
501#define ICMD_COMP BIT(11)
502#define ITICKLE BIT(10)
503#define IDO_STRT BIT(9)
504#define ITAR_DISC BIT(8)
505#define AUTO_INT (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
506#define CLR_ALL_INT 0xFFFF
507#define CLR_ALL_INT_1 0xFF00
508
509#define hp_intstat 0x42
510
511#define hp_scsisig 0x44
512
513#define SCSI_SEL BIT(7)
514#define SCSI_BSY BIT(6)
515#define SCSI_REQ BIT(5)
516#define SCSI_ACK BIT(4)
517#define SCSI_ATN BIT(3)
518#define SCSI_CD BIT(2)
519#define SCSI_MSG BIT(1)
520#define SCSI_IOBIT BIT(0)
521
522#define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
523#define S_MSGO_PH (BIT(2)+BIT(1) )
524#define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
525#define S_DATAI_PH ( BIT(0))
526#define S_DATAO_PH 0x00
527#define S_ILL_PH ( BIT(1) )
528
529#define hp_scsictrl_0 0x45
530
531#define SEL_TAR BIT(6)
532#define ENA_ATN BIT(4)
533#define ENA_RESEL BIT(2)
534#define SCSI_RST BIT(1)
535#define ENA_SCAM_SEL BIT(0)
536
537#define hp_portctrl_0 0x46
538
539#define SCSI_PORT BIT(7)
540#define SCSI_INBIT BIT(6)
541#define DMA_PORT BIT(5)
542#define DMA_RD BIT(4)
543#define HOST_PORT BIT(3)
544#define HOST_WRT BIT(2)
545#define SCSI_BUS_EN BIT(1)
546#define START_TO BIT(0)
547
548#define hp_scsireset 0x47
549
550#define SCSI_INI BIT(6)
551#define SCAM_EN BIT(5)
552#define DMA_RESET BIT(3)
553#define HPSCSI_RESET BIT(2)
554#define PROG_RESET BIT(1)
555#define FIFO_CLR BIT(0)
556
557#define hp_xfercnt_0 0x48
558#define hp_xfercnt_2 0x4A
559
560#define hp_fifodata_0 0x4C
561#define hp_addstat 0x4E
562
563#define SCAM_TIMER BIT(7)
564#define SCSI_MODE8 BIT(3)
565#define SCSI_PAR_ERR BIT(0)
566
567#define hp_prgmcnt_0 0x4F
568
569#define hp_selfid_0 0x50
570#define hp_selfid_1 0x51
571#define hp_arb_id 0x52
572
573#define hp_select_id 0x53
574
575#define hp_synctarg_base 0x54
576#define hp_synctarg_12 0x54
577#define hp_synctarg_13 0x55
578#define hp_synctarg_14 0x56
579#define hp_synctarg_15 0x57
580
581#define hp_synctarg_8 0x58
582#define hp_synctarg_9 0x59
583#define hp_synctarg_10 0x5A
584#define hp_synctarg_11 0x5B
585
586#define hp_synctarg_4 0x5C
587#define hp_synctarg_5 0x5D
588#define hp_synctarg_6 0x5E
589#define hp_synctarg_7 0x5F
590
591#define hp_synctarg_0 0x60
592#define hp_synctarg_1 0x61
593#define hp_synctarg_2 0x62
594#define hp_synctarg_3 0x63
595
596#define NARROW_SCSI BIT(4)
597#define DEFAULT_OFFSET 0x0F
598
599#define hp_autostart_0 0x64
600#define hp_autostart_1 0x65
601#define hp_autostart_3 0x67
602
603#define AUTO_IMMED BIT(5)
604#define SELECT BIT(6)
605#define END_DATA (BIT(7)+BIT(6))
606
607#define hp_gp_reg_0 0x68
608#define hp_gp_reg_1 0x69
609#define hp_gp_reg_3 0x6B
610
611#define hp_seltimeout 0x6C
612
613#define TO_4ms 0x67 /* 3.9959ms */
614
615#define TO_5ms 0x03 /* 4.9152ms */
616#define TO_10ms 0x07 /* 11.xxxms */
617#define TO_250ms 0x99 /* 250.68ms */
618#define TO_290ms 0xB1 /* 289.99ms */
619
620#define hp_clkctrl_0 0x6D
621
622#define PWR_DWN BIT(6)
623#define ACTdeassert BIT(4)
624#define CLK_40MHZ (BIT(1) + BIT(0))
625
626#define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
627
628#define hp_fiforead 0x6E
629#define hp_fifowrite 0x6F
630
631#define hp_offsetctr 0x70
632#define hp_xferstat 0x71
633
634#define FIFO_EMPTY BIT(6)
635
636#define hp_portctrl_1 0x72
637
638#define CHK_SCSI_P BIT(3)
639#define HOST_MODE8 BIT(0)
640
641#define hp_xfer_pad 0x73
642
643#define ID_UNLOCK BIT(3)
644
645#define hp_scsidata_0 0x74
646#define hp_scsidata_1 0x75
647
648#define hp_aramBase 0x80
649#define BIOS_DATA_OFFSET 0x60
650#define BIOS_RELATIVE_CARD 0x64
651
652#define AR3 (BIT(9) + BIT(8))
653#define SDATA BIT(10)
654
655#define CRD_OP BIT(11) /* Cmp Reg. w/ Data */
656
657#define CRR_OP BIT(12) /* Cmp Reg. w. Reg. */
658
659#define CPE_OP (BIT(14)+BIT(11)) /* Cmp SCSI phs & Branch EQ */
660
661#define CPN_OP (BIT(14)+BIT(12)) /* Cmp SCSI phs & Branch NOT EQ */
662
663#define ADATA_OUT 0x00
664#define ADATA_IN BIT(8)
665#define ACOMMAND BIT(10)
666#define ASTATUS (BIT(10)+BIT(8))
667#define AMSG_OUT (BIT(10)+BIT(9))
668#define AMSG_IN (BIT(10)+BIT(9)+BIT(8))
669
670#define BRH_OP BIT(13) /* Branch */
671
672#define ALWAYS 0x00
673#define EQUAL BIT(8)
674#define NOT_EQ BIT(9)
675
676#define TCB_OP (BIT(13)+BIT(11)) /* Test condition & branch */
677
678#define FIFO_0 BIT(10)
679
680#define MPM_OP BIT(15) /* Match phase and move data */
681
682#define MRR_OP BIT(14) /* Move DReg. to Reg. */
683
684#define S_IDREG (BIT(2)+BIT(1)+BIT(0))
685
686#define D_AR0 0x00
687#define D_AR1 BIT(0)
688#define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
689
690#define RAT_OP (BIT(14)+BIT(13)+BIT(11))
691
692#define SSI_OP (BIT(15)+BIT(11))
693
694#define SSI_ITAR_DISC (ITAR_DISC >> 8)
695#define SSI_IDO_STRT (IDO_STRT >> 8)
696
697#define SSI_ICMD_COMP (ICMD_COMP >> 8)
698#define SSI_ITICKLE (ITICKLE >> 8)
699
700#define SSI_IUNKWN (IUNKWN >> 8)
701#define SSI_INO_CC (IUNKWN >> 8)
702#define SSI_IRFAIL (IUNKWN >> 8)
703
704#define NP 0x10 /*Next Phase */
705#define NTCMD 0x02 /*Non- Tagged Command start */
706#define CMDPZ 0x04 /*Command phase */
707#define DINT 0x12 /*Data Out/In interrupt */
708#define DI 0x13 /*Data Out */
709#define DC 0x19 /*Disconnect Message */
710#define ST 0x1D /*Status Phase */
711#define UNKNWN 0x24 /*Unknown bus action */
712#define CC 0x25 /*Command Completion failure */
713#define TICK 0x26 /*New target reselected us. */
714#define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
715
716#define ID_MSG_STRT hp_aramBase + 0x00
717#define NON_TAG_ID_MSG hp_aramBase + 0x06
718#define CMD_STRT hp_aramBase + 0x08
719#define SYNC_MSGS hp_aramBase + 0x08
720
721#define TAG_STRT 0x00
722#define DISCONNECT_START 0x10/2
723#define END_DATA_START 0x14/2
724#define CMD_ONLY_STRT CMDPZ/2
725#define SELCHK_STRT SELCHK/2
726
727#define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
728/* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
729 xfercnt <<= 16,\
730 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
731 */
732#define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
733 addr >>= 16,\
734 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
735 WR_HARP32(port,hp_xfercnt_0,count),\
736 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
737 count >>= 16,\
738 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
739
740#define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
741 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
742
743#define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
744 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
745
746#define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
747 WR_HARPOON(port+hp_scsireset, 0x00))
748
749#define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
750 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
751
752#define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
753 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
754
755#define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
756 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
757
758#define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
759 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
760
761static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
762 unsigned char syncFlag);
763static void FPT_ssel(u32 port, unsigned char p_card);
764static void FPT_sres(u32 port, unsigned char p_card,
765 struct sccb_card *pCurrCard);
766static void FPT_shandem(u32 port, unsigned char p_card,
767 struct sccb *pCurrSCCB);
768static void FPT_stsyncn(u32 port, unsigned char p_card);
769static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
770 unsigned char offset);
771static void FPT_sssyncv(u32 p_port, unsigned char p_id,
772 unsigned char p_sync_value,
773 struct sccb_mgr_tar_info *currTar_Info);
774static void FPT_sresb(u32 port, unsigned char p_card);
775static void FPT_sxfrp(u32 p_port, unsigned char p_card);
776static void FPT_schkdd(u32 port, unsigned char p_card);
777static unsigned char FPT_RdStack(u32 port, unsigned char index);
778static void FPT_WrStack(u32 portBase, unsigned char index,
779 unsigned char data);
780static unsigned char FPT_ChkIfChipInitialized(u32 ioPort);
781
782static void FPT_SendMsg(u32 port, unsigned char message);
783static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
784 unsigned char error_code);
785
786static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card);
787static void FPT_RNVRamData(struct nvram_info *pNvRamInfo);
788
789static unsigned char FPT_siwidn(u32 port, unsigned char p_card);
790static void FPT_stwidn(u32 port, unsigned char p_card);
791static void FPT_siwidr(u32 port, unsigned char width);
792
793static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
794 unsigned char p_card);
795static void FPT_queueDisconnect(struct sccb *p_SCCB, unsigned char p_card);
796static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
797 struct sccb *p_SCCB, unsigned char p_card);
798static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
799 unsigned char p_card);
800static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
801static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char card);
802static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
803 unsigned char p_card);
804static void FPT_utilUpdateResidual(struct sccb *p_SCCB);
805static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
806static unsigned char FPT_CalcLrc(unsigned char buffer[]);
807
808static void FPT_Wait1Second(u32 p_port);
809static void FPT_Wait(u32 p_port, unsigned char p_delay);
810static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode);
811static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
812 unsigned short ee_addr);
813static unsigned short FPT_utilEERead(u32 p_port,
814 unsigned short ee_addr);
815static unsigned short FPT_utilEEReadOrg(u32 p_port,
816 unsigned short ee_addr);
817static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
818 unsigned short ee_addr);
819
820static void FPT_phaseDataOut(u32 port, unsigned char p_card);
821static void FPT_phaseDataIn(u32 port, unsigned char p_card);
822static void FPT_phaseCommand(u32 port, unsigned char p_card);
823static void FPT_phaseStatus(u32 port, unsigned char p_card);
824static void FPT_phaseMsgOut(u32 port, unsigned char p_card);
825static void FPT_phaseMsgIn(u32 port, unsigned char p_card);
826static void FPT_phaseIllegal(u32 port, unsigned char p_card);
827
828static void FPT_phaseDecode(u32 port, unsigned char p_card);
829static void FPT_phaseChkFifo(u32 port, unsigned char p_card);
830static void FPT_phaseBusFree(u32 p_port, unsigned char p_card);
831
832static void FPT_XbowInit(u32 port, unsigned char scamFlg);
833static void FPT_BusMasterInit(u32 p_port);
834static void FPT_DiagEEPROM(u32 p_port);
835
836static void FPT_dataXferProcessor(u32 port,
837 struct sccb_card *pCurrCard);
838static void FPT_busMstrSGDataXferStart(u32 port,
839 struct sccb *pCurrSCCB);
840static void FPT_busMstrDataXferStart(u32 port,
841 struct sccb *pCurrSCCB);
842static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
843 struct sccb *pCurrSCCB);
844static void FPT_hostDataXferRestart(struct sccb *currSCCB);
845
846static unsigned char FPT_SccbMgr_bad_isr(u32 p_port,
847 unsigned char p_card,
848 struct sccb_card *pCurrCard,
849 unsigned short p_int);
850
851static void FPT_SccbMgrTableInitAll(void);
852static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
853 unsigned char p_card);
854static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
855 unsigned char target);
856
857static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
858 unsigned char p_power_up);
859
860static int FPT_scarb(u32 p_port, unsigned char p_sel_type);
861static void FPT_scbusf(u32 p_port);
862static void FPT_scsel(u32 p_port);
863static void FPT_scasid(unsigned char p_card, u32 p_port);
864static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data);
865static unsigned char FPT_scsendi(u32 p_port,
866 unsigned char p_id_string[]);
867static unsigned char FPT_sciso(u32 p_port,
868 unsigned char p_id_string[]);
869static void FPT_scwirod(u32 p_port, unsigned char p_data_bit);
870static void FPT_scwiros(u32 p_port, unsigned char p_data_bit);
871static unsigned char FPT_scvalq(unsigned char p_quintet);
872static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id);
873static void FPT_scwtsel(u32 p_port);
874static void FPT_inisci(unsigned char p_card, u32 p_port,
875 unsigned char p_our_id);
876static void FPT_scsavdi(unsigned char p_card, u32 p_port);
877static unsigned char FPT_scmachid(unsigned char p_card,
878 unsigned char p_id_string[]);
879
880static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card);
881static void FPT_autoLoadDefaultMap(u32 p_port);
882
883static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] =
884 { {{0}} };
885static struct sccb_card FPT_BL_Card[MAX_CARDS] = { {0} };
886static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { {{0}} };
887static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { {0} };
888
889static unsigned char FPT_mbCards = 0;
890static unsigned char FPT_scamHAString[] =
891 { 0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C',
892 ' ', 'B', 'T', '-', '9', '3', '0',
893 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
894 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
895};
896
897static unsigned short FPT_default_intena = 0;
898
899static void (*FPT_s_PhaseTbl[8]) (u32, unsigned char) = {
9000};
901
902/*---------------------------------------------------------------------
903 *
904 * Function: FlashPoint_ProbeHostAdapter
905 *
906 * Description: Setup and/or Search for cards and return info to caller.
907 *
908 *---------------------------------------------------------------------*/
909
910static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo)
911{
912 static unsigned char first_time = 1;
913
914 unsigned char i, j, id, ScamFlg;
915 unsigned short temp, temp2, temp3, temp4, temp5, temp6;
916 u32 ioport;
917 struct nvram_info *pCurrNvRam;
918
919 ioport = pCardInfo->si_baseaddr;
920
921 if (RD_HARPOON(ioport + hp_vendor_id_0) != ORION_VEND_0)
922 return (int)FAILURE;
923
924 if ((RD_HARPOON(ioport + hp_vendor_id_1) != ORION_VEND_1))
925 return (int)FAILURE;
926
927 if ((RD_HARPOON(ioport + hp_device_id_0) != ORION_DEV_0))
928 return (int)FAILURE;
929
930 if ((RD_HARPOON(ioport + hp_device_id_1) != ORION_DEV_1))
931 return (int)FAILURE;
932
933 if (RD_HARPOON(ioport + hp_rev_num) != 0x0f) {
934
935/* For new Harpoon then check for sub_device ID LSB
936 the bits(0-3) must be all ZERO for compatible with
937 current version of SCCBMgr, else skip this Harpoon
938 device. */
939
940 if (RD_HARPOON(ioport + hp_sub_device_id_0) & 0x0f)
941 return (int)FAILURE;
942 }
943
944 if (first_time) {
945 FPT_SccbMgrTableInitAll();
946 first_time = 0;
947 FPT_mbCards = 0;
948 }
949
950 if (FPT_RdStack(ioport, 0) != 0x00) {
951 if (FPT_ChkIfChipInitialized(ioport) == 0) {
952 pCurrNvRam = NULL;
953 WR_HARPOON(ioport + hp_semaphore, 0x00);
954 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
955 FPT_DiagEEPROM(ioport);
956 } else {
957 if (FPT_mbCards < MAX_MB_CARDS) {
958 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
959 FPT_mbCards++;
960 pCurrNvRam->niBaseAddr = ioport;
961 FPT_RNVRamData(pCurrNvRam);
962 } else
963 return (int)FAILURE;
964 }
965 } else
966 pCurrNvRam = NULL;
967
968 WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
969 WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
970
971 if (pCurrNvRam)
972 pCardInfo->si_id = pCurrNvRam->niAdapId;
973 else
974 pCardInfo->si_id =
975 (unsigned
976 char)(FPT_utilEERead(ioport,
977 (ADAPTER_SCSI_ID /
978 2)) & (unsigned char)0x0FF);
979
980 pCardInfo->si_lun = 0x00;
981 pCardInfo->si_fw_revision = ORION_FW_REV;
982 temp2 = 0x0000;
983 temp3 = 0x0000;
984 temp4 = 0x0000;
985 temp5 = 0x0000;
986 temp6 = 0x0000;
987
988 for (id = 0; id < (16 / 2); id++) {
989
990 if (pCurrNvRam) {
991 temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
992 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
993 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
994 } else
995 temp =
996 FPT_utilEERead(ioport,
997 (unsigned short)((SYNC_RATE_TBL / 2)
998 + id));
999
1000 for (i = 0; i < 2; temp >>= 8, i++) {
1001
1002 temp2 >>= 1;
1003 temp3 >>= 1;
1004 temp4 >>= 1;
1005 temp5 >>= 1;
1006 temp6 >>= 1;
1007 switch (temp & 0x3) {
1008 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1009 temp6 |= 0x8000;
1010 fallthrough;
1011 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1012 temp5 |= 0x8000;
1013 fallthrough;
1014 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1015 temp2 |= 0x8000;
1016 fallthrough;
1017 case AUTO_RATE_00: /* Asynchronous */
1018 break;
1019 }
1020
1021 if (temp & DISC_ENABLE_BIT)
1022 temp3 |= 0x8000;
1023
1024 if (temp & WIDE_NEGO_BIT)
1025 temp4 |= 0x8000;
1026
1027 }
1028 }
1029
1030 pCardInfo->si_per_targ_init_sync = temp2;
1031 pCardInfo->si_per_targ_no_disc = temp3;
1032 pCardInfo->si_per_targ_wide_nego = temp4;
1033 pCardInfo->si_per_targ_fast_nego = temp5;
1034 pCardInfo->si_per_targ_ultra_nego = temp6;
1035
1036 if (pCurrNvRam)
1037 i = pCurrNvRam->niSysConf;
1038 else
1039 i = (unsigned
1040 char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)));
1041
1042 if (pCurrNvRam)
1043 ScamFlg = pCurrNvRam->niScamConf;
1044 else
1045 ScamFlg =
1046 (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1047
1048 pCardInfo->si_mflags = 0x0000;
1049
1050 if (i & 0x01)
1051 pCardInfo->si_mflags |= SCSI_PARITY_ENA;
1052
1053 if (!(i & 0x02))
1054 pCardInfo->si_mflags |= SOFT_RESET;
1055
1056 if (i & 0x10)
1057 pCardInfo->si_mflags |= EXTENDED_TRANSLATION;
1058
1059 if (ScamFlg & SCAM_ENABLED)
1060 pCardInfo->si_mflags |= FLAG_SCAM_ENABLED;
1061
1062 if (ScamFlg & SCAM_LEVEL2)
1063 pCardInfo->si_mflags |= FLAG_SCAM_LEVEL2;
1064
1065 j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1066 if (i & 0x04) {
1067 j |= SCSI_TERM_ENA_L;
1068 }
1069 WR_HARPOON(ioport + hp_bm_ctrl, j);
1070
1071 j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1072 if (i & 0x08) {
1073 j |= SCSI_TERM_ENA_H;
1074 }
1075 WR_HARPOON(ioport + hp_ee_ctrl, j);
1076
1077 if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD))
1078
1079 pCardInfo->si_mflags |= SUPPORT_16TAR_32LUN;
1080
1081 pCardInfo->si_card_family = HARPOON_FAMILY;
1082 pCardInfo->si_bustype = BUSTYPE_PCI;
1083
1084 if (pCurrNvRam) {
1085 pCardInfo->si_card_model[0] = '9';
1086 switch (pCurrNvRam->niModel & 0x0f) {
1087 case MODEL_LT:
1088 pCardInfo->si_card_model[1] = '3';
1089 pCardInfo->si_card_model[2] = '0';
1090 break;
1091 case MODEL_LW:
1092 pCardInfo->si_card_model[1] = '5';
1093 pCardInfo->si_card_model[2] = '0';
1094 break;
1095 case MODEL_DL:
1096 pCardInfo->si_card_model[1] = '3';
1097 pCardInfo->si_card_model[2] = '2';
1098 break;
1099 case MODEL_DW:
1100 pCardInfo->si_card_model[1] = '5';
1101 pCardInfo->si_card_model[2] = '2';
1102 break;
1103 }
1104 } else {
1105 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0 / 2));
1106 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1107 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2 / 2));
1108
1109 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1110 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1111 }
1112
1113 if (pCardInfo->si_card_model[1] == '3') {
1114 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1115 pCardInfo->si_mflags |= LOW_BYTE_TERM;
1116 } else if (pCardInfo->si_card_model[2] == '0') {
1117 temp = RD_HARPOON(ioport + hp_xfer_pad);
1118 WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4)));
1119 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1120 pCardInfo->si_mflags |= LOW_BYTE_TERM;
1121 WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4)));
1122 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1123 pCardInfo->si_mflags |= HIGH_BYTE_TERM;
1124 WR_HARPOON(ioport + hp_xfer_pad, temp);
1125 } else {
1126 temp = RD_HARPOON(ioport + hp_ee_ctrl);
1127 temp2 = RD_HARPOON(ioport + hp_xfer_pad);
1128 WR_HARPOON(ioport + hp_ee_ctrl, (temp | SEE_CS));
1129 WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1130 temp3 = 0;
1131 for (i = 0; i < 8; i++) {
1132 temp3 <<= 1;
1133 if (!(RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)))
1134 temp3 |= 1;
1135 WR_HARPOON(ioport + hp_xfer_pad, (temp2 & ~BIT(4)));
1136 WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1137 }
1138 WR_HARPOON(ioport + hp_ee_ctrl, temp);
1139 WR_HARPOON(ioport + hp_xfer_pad, temp2);
1140 if (!(temp3 & BIT(7)))
1141 pCardInfo->si_mflags |= LOW_BYTE_TERM;
1142 if (!(temp3 & BIT(6)))
1143 pCardInfo->si_mflags |= HIGH_BYTE_TERM;
1144 }
1145
1146 ARAM_ACCESS(ioport);
1147
1148 for (i = 0; i < 4; i++) {
1149
1150 pCardInfo->si_XlatInfo[i] =
1151 RD_HARPOON(ioport + hp_aramBase + BIOS_DATA_OFFSET + i);
1152 }
1153
1154 /* return with -1 if no sort, else return with
1155 logical card number sorted by BIOS (zero-based) */
1156
1157 pCardInfo->si_relative_cardnum =
1158 (unsigned
1159 char)(RD_HARPOON(ioport + hp_aramBase + BIOS_RELATIVE_CARD) - 1);
1160
1161 SGRAM_ACCESS(ioport);
1162
1163 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1164 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1165 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1166 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1167 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1168 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1169 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1170 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1171
1172 pCardInfo->si_present = 0x01;
1173
1174 return 0;
1175}
1176
1177/*---------------------------------------------------------------------
1178 *
1179 * Function: FlashPoint_HardwareResetHostAdapter
1180 *
1181 * Description: Setup adapter for normal operation (hard reset).
1182 *
1183 *---------------------------------------------------------------------*/
1184
1185static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
1186 *pCardInfo)
1187{
1188 struct sccb_card *CurrCard = NULL;
1189 struct nvram_info *pCurrNvRam;
1190 unsigned char i, j, thisCard, ScamFlg;
1191 unsigned short temp, sync_bit_map, id;
1192 u32 ioport;
1193
1194 ioport = pCardInfo->si_baseaddr;
1195
1196 for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) {
1197
1198 if (thisCard == MAX_CARDS)
1199 return (void *)FAILURE;
1200
1201 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1202
1203 CurrCard = &FPT_BL_Card[thisCard];
1204 FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1205 break;
1206 }
1207
1208 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1209
1210 FPT_BL_Card[thisCard].ioPort = ioport;
1211 CurrCard = &FPT_BL_Card[thisCard];
1212
1213 if (FPT_mbCards)
1214 for (i = 0; i < FPT_mbCards; i++) {
1215 if (CurrCard->ioPort ==
1216 FPT_nvRamInfo[i].niBaseAddr)
1217 CurrCard->pNvRamInfo =
1218 &FPT_nvRamInfo[i];
1219 }
1220 FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1221 CurrCard->cardIndex = thisCard;
1222 CurrCard->cardInfo = pCardInfo;
1223
1224 break;
1225 }
1226 }
1227
1228 pCurrNvRam = CurrCard->pNvRamInfo;
1229
1230 if (pCurrNvRam) {
1231 ScamFlg = pCurrNvRam->niScamConf;
1232 } else {
1233 ScamFlg =
1234 (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1235 }
1236
1237 FPT_BusMasterInit(ioport);
1238 FPT_XbowInit(ioport, ScamFlg);
1239
1240 FPT_autoLoadDefaultMap(ioport);
1241
1242 for (i = 0, id = 0x01; i != pCardInfo->si_id; i++, id <<= 1) {
1243 }
1244
1245 WR_HARPOON(ioport + hp_selfid_0, id);
1246 WR_HARPOON(ioport + hp_selfid_1, 0x00);
1247 WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id);
1248 CurrCard->ourId = pCardInfo->si_id;
1249
1250 i = (unsigned char)pCardInfo->si_mflags;
1251 if (i & SCSI_PARITY_ENA)
1252 WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P));
1253
1254 j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1255 if (i & LOW_BYTE_TERM)
1256 j |= SCSI_TERM_ENA_L;
1257 WR_HARPOON(ioport + hp_bm_ctrl, j);
1258
1259 j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1260 if (i & HIGH_BYTE_TERM)
1261 j |= SCSI_TERM_ENA_H;
1262 WR_HARPOON(ioport + hp_ee_ctrl, j);
1263
1264 if (!(pCardInfo->si_mflags & SOFT_RESET)) {
1265
1266 FPT_sresb(ioport, thisCard);
1267
1268 FPT_scini(thisCard, pCardInfo->si_id, 0);
1269 }
1270
1271 if (pCardInfo->si_mflags & POST_ALL_UNDERRRUNS)
1272 CurrCard->globalFlags |= F_NO_FILTER;
1273
1274 if (pCurrNvRam) {
1275 if (pCurrNvRam->niSysConf & 0x10)
1276 CurrCard->globalFlags |= F_GREEN_PC;
1277 } else {
1278 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)) & GREEN_PC_ENA)
1279 CurrCard->globalFlags |= F_GREEN_PC;
1280 }
1281
1282 /* Set global flag to indicate Re-Negotiation to be done on all
1283 ckeck condition */
1284 if (pCurrNvRam) {
1285 if (pCurrNvRam->niScsiConf & 0x04)
1286 CurrCard->globalFlags |= F_DO_RENEGO;
1287 } else {
1288 if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & RENEGO_ENA)
1289 CurrCard->globalFlags |= F_DO_RENEGO;
1290 }
1291
1292 if (pCurrNvRam) {
1293 if (pCurrNvRam->niScsiConf & 0x08)
1294 CurrCard->globalFlags |= F_CONLUN_IO;
1295 } else {
1296 if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & CONNIO_ENA)
1297 CurrCard->globalFlags |= F_CONLUN_IO;
1298 }
1299
1300 temp = pCardInfo->si_per_targ_no_disc;
1301
1302 for (i = 0, id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1303
1304 if (temp & id)
1305 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1306 }
1307
1308 sync_bit_map = 0x0001;
1309
1310 for (id = 0; id < (MAX_SCSI_TAR / 2); id++) {
1311
1312 if (pCurrNvRam) {
1313 temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
1314 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1315 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1316 } else
1317 temp =
1318 FPT_utilEERead(ioport,
1319 (unsigned short)((SYNC_RATE_TBL / 2)
1320 + id));
1321
1322 for (i = 0; i < 2; temp >>= 8, i++) {
1323
1324 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1325
1326 FPT_sccbMgrTbl[thisCard][id * 2 +
1327 i].TarEEValue =
1328 (unsigned char)temp;
1329 }
1330
1331 else {
1332 FPT_sccbMgrTbl[thisCard][id * 2 +
1333 i].TarStatus |=
1334 SYNC_SUPPORTED;
1335 FPT_sccbMgrTbl[thisCard][id * 2 +
1336 i].TarEEValue =
1337 (unsigned char)(temp & ~EE_SYNC_MASK);
1338 }
1339
1340/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1341 (id*2+i >= 8)){
1342*/
1343 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map) {
1344
1345 FPT_sccbMgrTbl[thisCard][id * 2 +
1346 i].TarEEValue |=
1347 EE_WIDE_SCSI;
1348
1349 }
1350
1351 else { /* NARROW SCSI */
1352 FPT_sccbMgrTbl[thisCard][id * 2 +
1353 i].TarStatus |=
1354 WIDE_NEGOCIATED;
1355 }
1356
1357 sync_bit_map <<= 1;
1358
1359 }
1360 }
1361
1362 WR_HARPOON((ioport + hp_semaphore),
1363 (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) |
1364 SCCB_MGR_PRESENT));
1365
1366 return (void *)CurrCard;
1367}
1368
1369static void FlashPoint_ReleaseHostAdapter(void *pCurrCard)
1370{
1371 unsigned char i;
1372 u32 portBase;
1373 u32 regOffset;
1374 u32 scamData;
1375 u32 *pScamTbl;
1376 struct nvram_info *pCurrNvRam;
1377
1378 pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
1379
1380 if (pCurrNvRam) {
1381 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1382 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1383 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1384 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1385 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1386
1387 for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1388 FPT_WrStack(pCurrNvRam->niBaseAddr,
1389 (unsigned char)(i + 5),
1390 pCurrNvRam->niSyncTbl[i]);
1391
1392 portBase = pCurrNvRam->niBaseAddr;
1393
1394 for (i = 0; i < MAX_SCSI_TAR; i++) {
1395 regOffset = hp_aramBase + 64 + i * 4;
1396 pScamTbl = (u32 *)&pCurrNvRam->niScamTbl[i];
1397 scamData = *pScamTbl;
1398 WR_HARP32(portBase, regOffset, scamData);
1399 }
1400
1401 } else {
1402 FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0);
1403 }
1404}
1405
1406static void FPT_RNVRamData(struct nvram_info *pNvRamInfo)
1407{
1408 unsigned char i;
1409 u32 portBase;
1410 u32 regOffset;
1411 u32 scamData;
1412 u32 *pScamTbl;
1413
1414 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1415 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1416 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1417 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1418 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1419
1420 for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1421 pNvRamInfo->niSyncTbl[i] =
1422 FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i + 5));
1423
1424 portBase = pNvRamInfo->niBaseAddr;
1425
1426 for (i = 0; i < MAX_SCSI_TAR; i++) {
1427 regOffset = hp_aramBase + 64 + i * 4;
1428 RD_HARP32(portBase, regOffset, scamData);
1429 pScamTbl = (u32 *)&pNvRamInfo->niScamTbl[i];
1430 *pScamTbl = scamData;
1431 }
1432
1433}
1434
1435static unsigned char FPT_RdStack(u32 portBase, unsigned char index)
1436{
1437 WR_HARPOON(portBase + hp_stack_addr, index);
1438 return RD_HARPOON(portBase + hp_stack_data);
1439}
1440
1441static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data)
1442{
1443 WR_HARPOON(portBase + hp_stack_addr, index);
1444 WR_HARPOON(portBase + hp_stack_data, data);
1445}
1446
1447static unsigned char FPT_ChkIfChipInitialized(u32 ioPort)
1448{
1449 if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1450 return 0;
1451 if ((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1452 != CLKCTRL_DEFAULT)
1453 return 0;
1454 if ((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1455 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1456 return 1;
1457 return 0;
1458
1459}
1460
1461/*---------------------------------------------------------------------
1462 *
1463 * Function: FlashPoint_StartCCB
1464 *
1465 * Description: Start a command pointed to by p_Sccb. When the
1466 * command is completed it will be returned via the
1467 * callback function.
1468 *
1469 *---------------------------------------------------------------------*/
1470static void FlashPoint_StartCCB(void *curr_card, struct sccb *p_Sccb)
1471{
1472 u32 ioport;
1473 unsigned char thisCard, lun;
1474 struct sccb *pSaveSccb;
1475 CALL_BK_FN callback;
1476 struct sccb_card *pCurrCard = curr_card;
1477
1478 thisCard = pCurrCard->cardIndex;
1479 ioport = pCurrCard->ioPort;
1480
1481 if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) {
1482
1483 p_Sccb->HostStatus = SCCB_COMPLETE;
1484 p_Sccb->SccbStatus = SCCB_ERROR;
1485 callback = (CALL_BK_FN) p_Sccb->SccbCallback;
1486 if (callback)
1487 callback(p_Sccb);
1488
1489 return;
1490 }
1491
1492 FPT_sinits(p_Sccb, thisCard);
1493
1494 if (!pCurrCard->cmdCounter) {
1495 WR_HARPOON(ioport + hp_semaphore,
1496 (RD_HARPOON(ioport + hp_semaphore)
1497 | SCCB_MGR_ACTIVE));
1498
1499 if (pCurrCard->globalFlags & F_GREEN_PC) {
1500 WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
1501 WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
1502 }
1503 }
1504
1505 pCurrCard->cmdCounter++;
1506
1507 if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) {
1508
1509 WR_HARPOON(ioport + hp_semaphore,
1510 (RD_HARPOON(ioport + hp_semaphore)
1511 | TICKLE_ME));
1512 if (p_Sccb->OperationCode == RESET_COMMAND) {
1513 pSaveSccb =
1514 pCurrCard->currentSCCB;
1515 pCurrCard->currentSCCB = p_Sccb;
1516 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1517 pCurrCard->currentSCCB =
1518 pSaveSccb;
1519 } else {
1520 FPT_queueAddSccb(p_Sccb, thisCard);
1521 }
1522 }
1523
1524 else if ((RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1525
1526 if (p_Sccb->OperationCode == RESET_COMMAND) {
1527 pSaveSccb =
1528 pCurrCard->currentSCCB;
1529 pCurrCard->currentSCCB = p_Sccb;
1530 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1531 pCurrCard->currentSCCB =
1532 pSaveSccb;
1533 } else {
1534 FPT_queueAddSccb(p_Sccb, thisCard);
1535 }
1536 }
1537
1538 else {
1539
1540 MDISABLE_INT(ioport);
1541
1542 if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
1543 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].
1544 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1545 lun = p_Sccb->Lun;
1546 else
1547 lun = 0;
1548 if ((pCurrCard->currentSCCB == NULL) &&
1549 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0)
1550 && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1551 == 0)) {
1552
1553 pCurrCard->currentSCCB = p_Sccb;
1554 FPT_ssel(p_Sccb->SccbIOPort, thisCard);
1555 }
1556
1557 else {
1558
1559 if (p_Sccb->OperationCode == RESET_COMMAND) {
1560 pSaveSccb = pCurrCard->currentSCCB;
1561 pCurrCard->currentSCCB = p_Sccb;
1562 FPT_queueSelectFail(&FPT_BL_Card[thisCard],
1563 thisCard);
1564 pCurrCard->currentSCCB = pSaveSccb;
1565 } else {
1566 FPT_queueAddSccb(p_Sccb, thisCard);
1567 }
1568 }
1569
1570 MENABLE_INT(ioport);
1571 }
1572
1573}
1574
1575/*---------------------------------------------------------------------
1576 *
1577 * Function: FlashPoint_AbortCCB
1578 *
1579 * Description: Abort the command pointed to by p_Sccb. When the
1580 * command is completed it will be returned via the
1581 * callback function.
1582 *
1583 *---------------------------------------------------------------------*/
1584static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb)
1585{
1586 u32 ioport;
1587
1588 unsigned char thisCard;
1589 CALL_BK_FN callback;
1590 struct sccb *pSaveSCCB;
1591 struct sccb_mgr_tar_info *currTar_Info;
1592
1593 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1594
1595 thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1596
1597 if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1598
1599 if (FPT_queueFindSccb(p_Sccb, thisCard)) {
1600
1601 ((struct sccb_card *)pCurrCard)->cmdCounter--;
1602
1603 if (!((struct sccb_card *)pCurrCard)->cmdCounter)
1604 WR_HARPOON(ioport + hp_semaphore,
1605 (RD_HARPOON(ioport + hp_semaphore)
1606 & (unsigned
1607 char)(~(SCCB_MGR_ACTIVE |
1608 TICKLE_ME))));
1609
1610 p_Sccb->SccbStatus = SCCB_ABORT;
1611 callback = p_Sccb->SccbCallback;
1612 callback(p_Sccb);
1613
1614 return 0;
1615 }
1616
1617 else {
1618 if (((struct sccb_card *)pCurrCard)->currentSCCB ==
1619 p_Sccb) {
1620 p_Sccb->SccbStatus = SCCB_ABORT;
1621 return 0;
1622
1623 }
1624
1625 else {
1626 if (p_Sccb->Sccb_tag) {
1627 MDISABLE_INT(ioport);
1628 if (((struct sccb_card *)pCurrCard)->
1629 discQ_Tbl[p_Sccb->Sccb_tag] ==
1630 p_Sccb) {
1631 p_Sccb->SccbStatus = SCCB_ABORT;
1632 p_Sccb->Sccb_scsistat =
1633 ABORT_ST;
1634 p_Sccb->Sccb_scsimsg =
1635 ABORT_TASK;
1636
1637 if (((struct sccb_card *)
1638 pCurrCard)->currentSCCB ==
1639 NULL) {
1640 ((struct sccb_card *)
1641 pCurrCard)->
1642 currentSCCB = p_Sccb;
1643 FPT_ssel(ioport,
1644 thisCard);
1645 } else {
1646 pSaveSCCB =
1647 ((struct sccb_card
1648 *)pCurrCard)->
1649 currentSCCB;
1650 ((struct sccb_card *)
1651 pCurrCard)->
1652 currentSCCB = p_Sccb;
1653 FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard);
1654 ((struct sccb_card *)
1655 pCurrCard)->
1656 currentSCCB = pSaveSCCB;
1657 }
1658 }
1659 MENABLE_INT(ioport);
1660 return 0;
1661 } else {
1662 currTar_Info =
1663 &FPT_sccbMgrTbl[thisCard][p_Sccb->
1664 TargID];
1665
1666 if (FPT_BL_Card[thisCard].
1667 discQ_Tbl[currTar_Info->
1668 LunDiscQ_Idx[p_Sccb->Lun]]
1669 == p_Sccb) {
1670 p_Sccb->SccbStatus = SCCB_ABORT;
1671 return 0;
1672 }
1673 }
1674 }
1675 }
1676 }
1677 return -1;
1678}
1679
1680/*---------------------------------------------------------------------
1681 *
1682 * Function: FlashPoint_InterruptPending
1683 *
1684 * Description: Do a quick check to determine if there is a pending
1685 * interrupt for this card and disable the IRQ Pin if so.
1686 *
1687 *---------------------------------------------------------------------*/
1688static unsigned char FlashPoint_InterruptPending(void *pCurrCard)
1689{
1690 u32 ioport;
1691
1692 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1693
1694 if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) {
1695 return 1;
1696 }
1697
1698 else
1699
1700 return 0;
1701}
1702
1703/*---------------------------------------------------------------------
1704 *
1705 * Function: FlashPoint_HandleInterrupt
1706 *
1707 * Description: This is our entry point when an interrupt is generated
1708 * by the card and the upper level driver passes it on to
1709 * us.
1710 *
1711 *---------------------------------------------------------------------*/
1712static int FlashPoint_HandleInterrupt(void *pcard)
1713{
1714 struct sccb *currSCCB;
1715 unsigned char thisCard, result, bm_status;
1716 unsigned short hp_int;
1717 unsigned char i, target;
1718 struct sccb_card *pCurrCard = pcard;
1719 u32 ioport;
1720
1721 thisCard = pCurrCard->cardIndex;
1722 ioport = pCurrCard->ioPort;
1723
1724 MDISABLE_INT(ioport);
1725
1726 if (RD_HARPOON(ioport + hp_int_status) & EXT_STATUS_ON)
1727 bm_status = RD_HARPOON(ioport + hp_ext_status) &
1728 (unsigned char)BAD_EXT_STATUS;
1729 else
1730 bm_status = 0;
1731
1732 WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1733
1734 while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) &
1735 FPT_default_intena) | bm_status) {
1736
1737 currSCCB = pCurrCard->currentSCCB;
1738
1739 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1740 result =
1741 FPT_SccbMgr_bad_isr(ioport, thisCard, pCurrCard,
1742 hp_int);
1743 WRW_HARPOON((ioport + hp_intstat),
1744 (FIFO | TIMEOUT | RESET | SCAM_SEL));
1745 bm_status = 0;
1746
1747 if (result) {
1748
1749 MENABLE_INT(ioport);
1750 return result;
1751 }
1752 }
1753
1754 else if (hp_int & ICMD_COMP) {
1755
1756 if (!(hp_int & BUS_FREE)) {
1757 /* Wait for the BusFree before starting a new command. We
1758 must also check for being reselected since the BusFree
1759 may not show up if another device reselects us in 1.5us or
1760 less. SRR Wednesday, 3/8/1995.
1761 */
1762 while (!
1763 (RDW_HARPOON((ioport + hp_intstat)) &
1764 (BUS_FREE | RSEL))) ;
1765 }
1766
1767 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1768
1769 FPT_phaseChkFifo(ioport, thisCard);
1770
1771/* WRW_HARPOON((ioport+hp_intstat),
1772 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1773 */
1774
1775 WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1);
1776
1777 FPT_autoCmdCmplt(ioport, thisCard);
1778
1779 }
1780
1781 else if (hp_int & ITAR_DISC) {
1782
1783 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1784 FPT_phaseChkFifo(ioport, thisCard);
1785
1786 if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1787 SAVE_POINTERS) {
1788
1789 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1790 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1791
1792 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1793 }
1794
1795 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1796 FPT_queueDisconnect(currSCCB, thisCard);
1797
1798 /* Wait for the BusFree before starting a new command. We
1799 must also check for being reselected since the BusFree
1800 may not show up if another device reselects us in 1.5us or
1801 less. SRR Wednesday, 3/8/1995.
1802 */
1803 while (!
1804 (RDW_HARPOON((ioport + hp_intstat)) &
1805 (BUS_FREE | RSEL))
1806 && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE)
1807 && RD_HARPOON((ioport + hp_scsisig)) ==
1808 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG |
1809 SCSI_IOBIT))) ;
1810
1811 /*
1812 The additional loop exit condition above detects a timing problem
1813 with the revision D/E harpoon chips. The caller should reset the
1814 host adapter to recover when 0xFE is returned.
1815 */
1816 if (!
1817 (RDW_HARPOON((ioport + hp_intstat)) &
1818 (BUS_FREE | RSEL))) {
1819 MENABLE_INT(ioport);
1820 return 0xFE;
1821 }
1822
1823 WRW_HARPOON((ioport + hp_intstat),
1824 (BUS_FREE | ITAR_DISC));
1825
1826 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1827
1828 }
1829
1830 else if (hp_int & RSEL) {
1831
1832 WRW_HARPOON((ioport + hp_intstat),
1833 (PROG_HLT | RSEL | PHASE | BUS_FREE));
1834
1835 if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) {
1836 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1837 FPT_phaseChkFifo(ioport, thisCard);
1838
1839 if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1840 SAVE_POINTERS) {
1841 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1842 currSCCB->Sccb_XferState |=
1843 F_NO_DATA_YET;
1844 currSCCB->Sccb_savedATC =
1845 currSCCB->Sccb_ATC;
1846 }
1847
1848 WRW_HARPOON((ioport + hp_intstat),
1849 (BUS_FREE | ITAR_DISC));
1850 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1851 FPT_queueDisconnect(currSCCB, thisCard);
1852 }
1853
1854 FPT_sres(ioport, thisCard, pCurrCard);
1855 FPT_phaseDecode(ioport, thisCard);
1856
1857 }
1858
1859 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) {
1860
1861 WRW_HARPOON((ioport + hp_intstat),
1862 (IDO_STRT | XFER_CNT_0));
1863 FPT_phaseDecode(ioport, thisCard);
1864
1865 }
1866
1867 else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) {
1868 WRW_HARPOON((ioport + hp_intstat),
1869 (PHASE | IUNKWN | PROG_HLT));
1870 if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char)
1871 0x3f) < (unsigned char)SELCHK) {
1872 FPT_phaseDecode(ioport, thisCard);
1873 } else {
1874 /* Harpoon problem some SCSI target device respond to selection
1875 with short BUSY pulse (<400ns) this will make the Harpoon is not able
1876 to latch the correct Target ID into reg. x53.
1877 The work around require to correct this reg. But when write to this
1878 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
1879 need to read this reg first then restore it later. After update to 0x53 */
1880
1881 i = (unsigned
1882 char)(RD_HARPOON(ioport + hp_fifowrite));
1883 target =
1884 (unsigned
1885 char)(RD_HARPOON(ioport + hp_gp_reg_3));
1886 WR_HARPOON(ioport + hp_xfer_pad,
1887 (unsigned char)ID_UNLOCK);
1888 WR_HARPOON(ioport + hp_select_id,
1889 (unsigned char)(target | target <<
1890 4));
1891 WR_HARPOON(ioport + hp_xfer_pad,
1892 (unsigned char)0x00);
1893 WR_HARPOON(ioport + hp_fifowrite, i);
1894 WR_HARPOON(ioport + hp_autostart_3,
1895 (AUTO_IMMED + TAG_STRT));
1896 }
1897 }
1898
1899 else if (hp_int & XFER_CNT_0) {
1900
1901 WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0);
1902
1903 FPT_schkdd(ioport, thisCard);
1904
1905 }
1906
1907 else if (hp_int & BUS_FREE) {
1908
1909 WRW_HARPOON((ioport + hp_intstat), BUS_FREE);
1910
1911 if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
1912
1913 FPT_hostDataXferAbort(ioport, thisCard,
1914 currSCCB);
1915 }
1916
1917 FPT_phaseBusFree(ioport, thisCard);
1918 }
1919
1920 else if (hp_int & ITICKLE) {
1921
1922 WRW_HARPOON((ioport + hp_intstat), ITICKLE);
1923 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1924 }
1925
1926 if (((struct sccb_card *)pCurrCard)->
1927 globalFlags & F_NEW_SCCB_CMD) {
1928
1929 pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1930
1931 if (pCurrCard->currentSCCB == NULL)
1932 FPT_queueSearchSelect(pCurrCard, thisCard);
1933
1934 if (pCurrCard->currentSCCB != NULL) {
1935 pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1936 FPT_ssel(ioport, thisCard);
1937 }
1938
1939 break;
1940
1941 }
1942
1943 } /*end while */
1944
1945 MENABLE_INT(ioport);
1946
1947 return 0;
1948}
1949
1950/*---------------------------------------------------------------------
1951 *
1952 * Function: Sccb_bad_isr
1953 *
1954 * Description: Some type of interrupt has occurred which is slightly
1955 * out of the ordinary. We will now decode it fully, in
1956 * this routine. This is broken up in an attempt to save
1957 * processing time.
1958 *
1959 *---------------------------------------------------------------------*/
1960static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card,
1961 struct sccb_card *pCurrCard,
1962 unsigned short p_int)
1963{
1964 unsigned char temp, ScamFlg;
1965 struct sccb_mgr_tar_info *currTar_Info;
1966 struct nvram_info *pCurrNvRam;
1967
1968 if (RD_HARPOON(p_port + hp_ext_status) &
1969 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) {
1970
1971 if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
1972
1973 FPT_hostDataXferAbort(p_port, p_card,
1974 pCurrCard->currentSCCB);
1975 }
1976
1977 if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT)
1978 {
1979 WR_HARPOON(p_port + hp_pci_stat_cfg,
1980 (RD_HARPOON(p_port + hp_pci_stat_cfg) &
1981 ~REC_MASTER_ABORT));
1982
1983 WR_HARPOON(p_port + hp_host_blk_cnt, 0x00);
1984
1985 }
1986
1987 if (pCurrCard->currentSCCB != NULL) {
1988
1989 if (!pCurrCard->currentSCCB->HostStatus)
1990 pCurrCard->currentSCCB->HostStatus =
1991 SCCB_BM_ERR;
1992
1993 FPT_sxfrp(p_port, p_card);
1994
1995 temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
1996 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
1997 WR_HARPOON(p_port + hp_ee_ctrl,
1998 ((unsigned char)temp | SEE_MS | SEE_CS));
1999 WR_HARPOON(p_port + hp_ee_ctrl, temp);
2000
2001 if (!
2002 (RDW_HARPOON((p_port + hp_intstat)) &
2003 (BUS_FREE | RESET))) {
2004 FPT_phaseDecode(p_port, p_card);
2005 }
2006 }
2007 }
2008
2009 else if (p_int & RESET) {
2010
2011 WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
2012 WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
2013 if (pCurrCard->currentSCCB != NULL) {
2014
2015 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2016
2017 FPT_hostDataXferAbort(p_port, p_card,
2018 pCurrCard->currentSCCB);
2019 }
2020
2021 DISABLE_AUTO(p_port);
2022
2023 FPT_sresb(p_port, p_card);
2024
2025 while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) {
2026 }
2027
2028 pCurrNvRam = pCurrCard->pNvRamInfo;
2029 if (pCurrNvRam) {
2030 ScamFlg = pCurrNvRam->niScamConf;
2031 } else {
2032 ScamFlg =
2033 (unsigned char)FPT_utilEERead(p_port,
2034 SCAM_CONFIG / 2);
2035 }
2036
2037 FPT_XbowInit(p_port, ScamFlg);
2038
2039 FPT_scini(p_card, pCurrCard->ourId, 0);
2040
2041 return 0xFF;
2042 }
2043
2044 else if (p_int & FIFO) {
2045
2046 WRW_HARPOON((p_port + hp_intstat), FIFO);
2047
2048 if (pCurrCard->currentSCCB != NULL)
2049 FPT_sxfrp(p_port, p_card);
2050 }
2051
2052 else if (p_int & TIMEOUT) {
2053
2054 DISABLE_AUTO(p_port);
2055
2056 WRW_HARPOON((p_port + hp_intstat),
2057 (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE |
2058 IUNKWN));
2059
2060 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2061
2062 currTar_Info =
2063 &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2064 if ((pCurrCard->globalFlags & F_CONLUN_IO)
2065 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2066 TAG_Q_TRYING))
2067 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] =
2068 0;
2069 else
2070 currTar_Info->TarLUNBusy[0] = 0;
2071
2072 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2073 currTar_Info->TarSyncCtrl = 0;
2074 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2075 }
2076
2077 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2078 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2079 }
2080
2081 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,
2082 currTar_Info);
2083
2084 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2085
2086 }
2087
2088 else if (p_int & SCAM_SEL) {
2089
2090 FPT_scarb(p_port, LEVEL2_TAR);
2091 FPT_scsel(p_port);
2092 FPT_scasid(p_card, p_port);
2093
2094 FPT_scbusf(p_port);
2095
2096 WRW_HARPOON((p_port + hp_intstat), SCAM_SEL);
2097 }
2098
2099 return 0x00;
2100}
2101
2102/*---------------------------------------------------------------------
2103 *
2104 * Function: SccbMgrTableInit
2105 *
2106 * Description: Initialize all Sccb manager data structures.
2107 *
2108 *---------------------------------------------------------------------*/
2109
2110static void FPT_SccbMgrTableInitAll(void)
2111{
2112 unsigned char thisCard;
2113
2114 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) {
2115 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard);
2116
2117 FPT_BL_Card[thisCard].ioPort = 0x00;
2118 FPT_BL_Card[thisCard].cardInfo = NULL;
2119 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2120 FPT_BL_Card[thisCard].ourId = 0x00;
2121 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2122 }
2123}
2124
2125/*---------------------------------------------------------------------
2126 *
2127 * Function: SccbMgrTableInit
2128 *
2129 * Description: Initialize all Sccb manager data structures.
2130 *
2131 *---------------------------------------------------------------------*/
2132
2133static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
2134 unsigned char p_card)
2135{
2136 unsigned char scsiID, qtag;
2137
2138 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2139 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2140 }
2141
2142 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
2143 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2144 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2145 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2146 }
2147
2148 pCurrCard->scanIndex = 0x00;
2149 pCurrCard->currentSCCB = NULL;
2150 pCurrCard->globalFlags = 0x00;
2151 pCurrCard->cmdCounter = 0x00;
2152 pCurrCard->tagQ_Lst = 0x01;
2153 pCurrCard->discQCount = 0;
2154
2155}
2156
2157/*---------------------------------------------------------------------
2158 *
2159 * Function: SccbMgrTableInit
2160 *
2161 * Description: Initialize all Sccb manager data structures.
2162 *
2163 *---------------------------------------------------------------------*/
2164
2165static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
2166 unsigned char target)
2167{
2168
2169 unsigned char lun, qtag;
2170 struct sccb_mgr_tar_info *currTar_Info;
2171
2172 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2173
2174 currTar_Info->TarSelQ_Cnt = 0;
2175 currTar_Info->TarSyncCtrl = 0;
2176
2177 currTar_Info->TarSelQ_Head = NULL;
2178 currTar_Info->TarSelQ_Tail = NULL;
2179 currTar_Info->TarTagQ_Cnt = 0;
2180 currTar_Info->TarLUN_CA = 0;
2181
2182 for (lun = 0; lun < MAX_LUN; lun++) {
2183 currTar_Info->TarLUNBusy[lun] = 0;
2184 currTar_Info->LunDiscQ_Idx[lun] = 0;
2185 }
2186
2187 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2188 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) {
2189 if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
2190 target) {
2191 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2192 FPT_BL_Card[p_card].discQCount--;
2193 }
2194 }
2195 }
2196}
2197
2198/*---------------------------------------------------------------------
2199 *
2200 * Function: sfetm
2201 *
2202 * Description: Read in a message byte from the SCSI bus, and check
2203 * for a parity error.
2204 *
2205 *---------------------------------------------------------------------*/
2206
2207static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB)
2208{
2209 unsigned char message;
2210 unsigned short TimeOutLoop;
2211
2212 TimeOutLoop = 0;
2213 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2214 (TimeOutLoop++ < 20000)) {
2215 }
2216
2217 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2218
2219 message = RD_HARPOON(port + hp_scsidata_0);
2220
2221 WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH);
2222
2223 if (TimeOutLoop > 20000)
2224 message = 0x00; /* force message byte = 0 if Time Out on Req */
2225
2226 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
2227 (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) {
2228 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2229 WR_HARPOON(port + hp_xferstat, 0);
2230 WR_HARPOON(port + hp_fiforead, 0);
2231 WR_HARPOON(port + hp_fifowrite, 0);
2232 if (pCurrSCCB != NULL) {
2233 pCurrSCCB->Sccb_scsimsg = MSG_PARITY_ERROR;
2234 }
2235 message = 0x00;
2236 do {
2237 ACCEPT_MSG_ATN(port);
2238 TimeOutLoop = 0;
2239 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2240 (TimeOutLoop++ < 20000)) {
2241 }
2242 if (TimeOutLoop > 20000) {
2243 WRW_HARPOON((port + hp_intstat), PARITY);
2244 return message;
2245 }
2246 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) !=
2247 S_MSGI_PH) {
2248 WRW_HARPOON((port + hp_intstat), PARITY);
2249 return message;
2250 }
2251 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2252
2253 RD_HARPOON(port + hp_scsidata_0);
2254
2255 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2256
2257 } while (1);
2258
2259 }
2260 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2261 WR_HARPOON(port + hp_xferstat, 0);
2262 WR_HARPOON(port + hp_fiforead, 0);
2263 WR_HARPOON(port + hp_fifowrite, 0);
2264 return message;
2265}
2266
2267/*---------------------------------------------------------------------
2268 *
2269 * Function: FPT_ssel
2270 *
2271 * Description: Load up automation and select target device.
2272 *
2273 *---------------------------------------------------------------------*/
2274
2275static void FPT_ssel(u32 port, unsigned char p_card)
2276{
2277
2278 unsigned char auto_loaded, i, target, *theCCB;
2279
2280 u32 cdb_reg;
2281 struct sccb_card *CurrCard;
2282 struct sccb *currSCCB;
2283 struct sccb_mgr_tar_info *currTar_Info;
2284 unsigned char lastTag, lun;
2285
2286 CurrCard = &FPT_BL_Card[p_card];
2287 currSCCB = CurrCard->currentSCCB;
2288 target = currSCCB->TargID;
2289 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2290 lastTag = CurrCard->tagQ_Lst;
2291
2292 ARAM_ACCESS(port);
2293
2294 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2295 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2296
2297 if (((CurrCard->globalFlags & F_CONLUN_IO) &&
2298 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2299
2300 lun = currSCCB->Lun;
2301 else
2302 lun = 0;
2303
2304 if (CurrCard->globalFlags & F_TAG_STARTED) {
2305 if (!(currSCCB->ControlByte & F_USE_CMD_Q)) {
2306 if ((currTar_Info->TarLUN_CA == 0)
2307 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2308 == TAG_Q_TRYING)) {
2309
2310 if (currTar_Info->TarTagQ_Cnt != 0) {
2311 currTar_Info->TarLUNBusy[lun] = 1;
2312 FPT_queueSelectFail(CurrCard, p_card);
2313 SGRAM_ACCESS(port);
2314 return;
2315 }
2316
2317 else {
2318 currTar_Info->TarLUNBusy[lun] = 1;
2319 }
2320
2321 }
2322 /*End non-tagged */
2323 else {
2324 currTar_Info->TarLUNBusy[lun] = 1;
2325 }
2326
2327 }
2328 /*!Use cmd Q Tagged */
2329 else {
2330 if (currTar_Info->TarLUN_CA == 1) {
2331 FPT_queueSelectFail(CurrCard, p_card);
2332 SGRAM_ACCESS(port);
2333 return;
2334 }
2335
2336 currTar_Info->TarLUNBusy[lun] = 1;
2337
2338 } /*else use cmd Q tagged */
2339
2340 }
2341 /*if glob tagged started */
2342 else {
2343 currTar_Info->TarLUNBusy[lun] = 1;
2344 }
2345
2346 if ((((CurrCard->globalFlags & F_CONLUN_IO) &&
2347 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2348 || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) {
2349 if (CurrCard->discQCount >= QUEUE_DEPTH) {
2350 currTar_Info->TarLUNBusy[lun] = 1;
2351 FPT_queueSelectFail(CurrCard, p_card);
2352 SGRAM_ACCESS(port);
2353 return;
2354 }
2355 for (i = 1; i < QUEUE_DEPTH; i++) {
2356 if (++lastTag >= QUEUE_DEPTH)
2357 lastTag = 1;
2358 if (CurrCard->discQ_Tbl[lastTag] == NULL) {
2359 CurrCard->tagQ_Lst = lastTag;
2360 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2361 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2362 CurrCard->discQCount++;
2363 break;
2364 }
2365 }
2366 if (i == QUEUE_DEPTH) {
2367 currTar_Info->TarLUNBusy[lun] = 1;
2368 FPT_queueSelectFail(CurrCard, p_card);
2369 SGRAM_ACCESS(port);
2370 return;
2371 }
2372 }
2373
2374 auto_loaded = 0;
2375
2376 WR_HARPOON(port + hp_select_id, target);
2377 WR_HARPOON(port + hp_gp_reg_3, target); /* Use by new automation logic */
2378
2379 if (currSCCB->OperationCode == RESET_COMMAND) {
2380 WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2381 (currSCCB->
2382 Sccb_idmsg & ~DISC_PRIV)));
2383
2384 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
2385
2386 currSCCB->Sccb_scsimsg = TARGET_RESET;
2387
2388 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2389 auto_loaded = 1;
2390 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2391
2392 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2393 currTar_Info->TarSyncCtrl = 0;
2394 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2395 }
2396
2397 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2398 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2399 }
2400
2401 FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info);
2402 FPT_SccbMgrTableInitTarget(p_card, target);
2403
2404 }
2405
2406 else if (currSCCB->Sccb_scsistat == ABORT_ST) {
2407 WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2408 (currSCCB->
2409 Sccb_idmsg & ~DISC_PRIV)));
2410
2411 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
2412
2413 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT +
2414 (((unsigned
2415 char)(currSCCB->
2416 ControlByte &
2417 TAG_TYPE_MASK)
2418 >> 6) | (unsigned char)
2419 0x20)));
2420 WRW_HARPOON((port + SYNC_MSGS + 2),
2421 (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag));
2422 WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP));
2423
2424 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2425 auto_loaded = 1;
2426
2427 }
2428
2429 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2430 auto_loaded = FPT_siwidn(port, p_card);
2431 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2432 }
2433
2434 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2435 == SYNC_SUPPORTED)) {
2436 auto_loaded = FPT_sisyncn(port, p_card, 0);
2437 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2438 }
2439
2440 if (!auto_loaded) {
2441
2442 if (currSCCB->ControlByte & F_USE_CMD_Q) {
2443
2444 CurrCard->globalFlags |= F_TAG_STARTED;
2445
2446 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2447 == TAG_Q_REJECT) {
2448 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2449
2450 /* Fix up the start instruction with a jump to
2451 Non-Tag-CMD handling */
2452 WRW_HARPOON((port + ID_MSG_STRT),
2453 BRH_OP + ALWAYS + NTCMD);
2454
2455 WRW_HARPOON((port + NON_TAG_ID_MSG),
2456 (MPM_OP + AMSG_OUT +
2457 currSCCB->Sccb_idmsg));
2458
2459 WR_HARPOON(port + hp_autostart_3,
2460 (SELECT + SELCHK_STRT));
2461
2462 /* Setup our STATE so we know what happened when
2463 the wheels fall off. */
2464 currSCCB->Sccb_scsistat = SELECT_ST;
2465
2466 currTar_Info->TarLUNBusy[lun] = 1;
2467 }
2468
2469 else {
2470 WRW_HARPOON((port + ID_MSG_STRT),
2471 (MPM_OP + AMSG_OUT +
2472 currSCCB->Sccb_idmsg));
2473
2474 WRW_HARPOON((port + ID_MSG_STRT + 2),
2475 (MPM_OP + AMSG_OUT +
2476 (((unsigned char)(currSCCB->
2477 ControlByte &
2478 TAG_TYPE_MASK)
2479 >> 6) | (unsigned char)0x20)));
2480
2481 for (i = 1; i < QUEUE_DEPTH; i++) {
2482 if (++lastTag >= QUEUE_DEPTH)
2483 lastTag = 1;
2484 if (CurrCard->discQ_Tbl[lastTag] ==
2485 NULL) {
2486 WRW_HARPOON((port +
2487 ID_MSG_STRT + 6),
2488 (MPM_OP + AMSG_OUT +
2489 lastTag));
2490 CurrCard->tagQ_Lst = lastTag;
2491 currSCCB->Sccb_tag = lastTag;
2492 CurrCard->discQ_Tbl[lastTag] =
2493 currSCCB;
2494 CurrCard->discQCount++;
2495 break;
2496 }
2497 }
2498
2499 if (i == QUEUE_DEPTH) {
2500 currTar_Info->TarLUNBusy[lun] = 1;
2501 FPT_queueSelectFail(CurrCard, p_card);
2502 SGRAM_ACCESS(port);
2503 return;
2504 }
2505
2506 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2507
2508 WR_HARPOON(port + hp_autostart_3,
2509 (SELECT + SELCHK_STRT));
2510 }
2511 }
2512
2513 else {
2514
2515 WRW_HARPOON((port + ID_MSG_STRT),
2516 BRH_OP + ALWAYS + NTCMD);
2517
2518 WRW_HARPOON((port + NON_TAG_ID_MSG),
2519 (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg));
2520
2521 currSCCB->Sccb_scsistat = SELECT_ST;
2522
2523 WR_HARPOON(port + hp_autostart_3,
2524 (SELECT + SELCHK_STRT));
2525 }
2526
2527 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2528
2529 cdb_reg = port + CMD_STRT;
2530
2531 for (i = 0; i < currSCCB->CdbLength; i++) {
2532 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2533 cdb_reg += 2;
2534 theCCB++;
2535 }
2536
2537 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2538 WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
2539
2540 }
2541 /* auto_loaded */
2542 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2543 WR_HARPOON(port + hp_xferstat, 0x00);
2544
2545 WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2546
2547 WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT));
2548
2549 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) {
2550 WR_HARPOON(port + hp_scsictrl_0,
2551 (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2552 } else {
2553
2554/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2555 auto_loaded |= AUTO_IMMED; */
2556 auto_loaded = AUTO_IMMED;
2557
2558 DISABLE_AUTO(port);
2559
2560 WR_HARPOON(port + hp_autostart_3, auto_loaded);
2561 }
2562
2563 SGRAM_ACCESS(port);
2564}
2565
2566/*---------------------------------------------------------------------
2567 *
2568 * Function: FPT_sres
2569 *
2570 * Description: Hookup the correct CCB and handle the incoming messages.
2571 *
2572 *---------------------------------------------------------------------*/
2573
2574static void FPT_sres(u32 port, unsigned char p_card,
2575 struct sccb_card *pCurrCard)
2576{
2577
2578 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2579
2580 struct sccb_mgr_tar_info *currTar_Info;
2581 struct sccb *currSCCB;
2582
2583 if (pCurrCard->currentSCCB != NULL) {
2584 currTar_Info =
2585 &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2586 DISABLE_AUTO(port);
2587
2588 WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL));
2589
2590 currSCCB = pCurrCard->currentSCCB;
2591 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
2592 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2593 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2594 }
2595 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2596 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2597 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2598 }
2599 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2600 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2601 TAG_Q_TRYING))) {
2602 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2603 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2604 pCurrCard->discQCount--;
2605 pCurrCard->discQ_Tbl[currTar_Info->
2606 LunDiscQ_Idx[currSCCB->
2607 Lun]]
2608 = NULL;
2609 }
2610 } else {
2611 currTar_Info->TarLUNBusy[0] = 0;
2612 if (currSCCB->Sccb_tag) {
2613 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2614 pCurrCard->discQCount--;
2615 pCurrCard->discQ_Tbl[currSCCB->
2616 Sccb_tag] = NULL;
2617 }
2618 } else {
2619 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2620 pCurrCard->discQCount--;
2621 pCurrCard->discQ_Tbl[currTar_Info->
2622 LunDiscQ_Idx[0]] =
2623 NULL;
2624 }
2625 }
2626 }
2627
2628 FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
2629 }
2630
2631 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2632
2633 our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4);
2634 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2635
2636 msgRetryCount = 0;
2637 do {
2638
2639 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2640 tag = 0;
2641
2642 while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2643 if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2644
2645 WRW_HARPOON((port + hp_intstat), PHASE);
2646 return;
2647 }
2648 }
2649
2650 WRW_HARPOON((port + hp_intstat), PHASE);
2651 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) {
2652
2653 message = FPT_sfm(port, pCurrCard->currentSCCB);
2654 if (message) {
2655
2656 if (message <= (0x80 | LUN_MASK)) {
2657 lun = message & (unsigned char)LUN_MASK;
2658
2659 if ((currTar_Info->
2660 TarStatus & TAR_TAG_Q_MASK) ==
2661 TAG_Q_TRYING) {
2662 if (currTar_Info->TarTagQ_Cnt !=
2663 0) {
2664
2665 if (!
2666 (currTar_Info->
2667 TarLUN_CA)) {
2668 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2669
2670 message =
2671 FPT_sfm
2672 (port,
2673 pCurrCard->
2674 currentSCCB);
2675 if (message) {
2676 ACCEPT_MSG
2677 (port);
2678 }
2679
2680 else
2681 message
2682 = 0;
2683
2684 if (message !=
2685 0) {
2686 tag =
2687 FPT_sfm
2688 (port,
2689 pCurrCard->
2690 currentSCCB);
2691
2692 if (!
2693 (tag))
2694 message
2695 =
2696 0;
2697 }
2698
2699 }
2700 /*C.A. exists! */
2701 }
2702 /*End Q cnt != 0 */
2703 }
2704 /*End Tag cmds supported! */
2705 }
2706 /*End valid ID message. */
2707 else {
2708
2709 ACCEPT_MSG_ATN(port);
2710 }
2711
2712 }
2713 /* End good id message. */
2714 else {
2715
2716 message = 0;
2717 }
2718 } else {
2719 ACCEPT_MSG_ATN(port);
2720
2721 while (!
2722 (RDW_HARPOON((port + hp_intstat)) &
2723 (PHASE | RESET))
2724 && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
2725 && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2726
2727 return;
2728 }
2729
2730 if (message == 0) {
2731 msgRetryCount++;
2732 if (msgRetryCount == 1) {
2733 FPT_SendMsg(port, MSG_PARITY_ERROR);
2734 } else {
2735 FPT_SendMsg(port, TARGET_RESET);
2736
2737 FPT_sssyncv(port, our_target, NARROW_SCSI,
2738 currTar_Info);
2739
2740 if (FPT_sccbMgrTbl[p_card][our_target].
2741 TarEEValue & EE_SYNC_MASK) {
2742
2743 FPT_sccbMgrTbl[p_card][our_target].
2744 TarStatus &= ~TAR_SYNC_MASK;
2745
2746 }
2747
2748 if (FPT_sccbMgrTbl[p_card][our_target].
2749 TarEEValue & EE_WIDE_SCSI) {
2750
2751 FPT_sccbMgrTbl[p_card][our_target].
2752 TarStatus &= ~TAR_WIDE_MASK;
2753 }
2754
2755 FPT_queueFlushTargSccb(p_card, our_target,
2756 SCCB_COMPLETE);
2757 FPT_SccbMgrTableInitTarget(p_card, our_target);
2758 return;
2759 }
2760 }
2761 } while (message == 0);
2762
2763 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2764 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
2765 currTar_Info->TarLUNBusy[lun] = 1;
2766 pCurrCard->currentSCCB =
2767 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
2768 if (pCurrCard->currentSCCB != NULL) {
2769 ACCEPT_MSG(port);
2770 } else {
2771 ACCEPT_MSG_ATN(port);
2772 }
2773 } else {
2774 currTar_Info->TarLUNBusy[0] = 1;
2775
2776 if (tag) {
2777 if (pCurrCard->discQ_Tbl[tag] != NULL) {
2778 pCurrCard->currentSCCB =
2779 pCurrCard->discQ_Tbl[tag];
2780 currTar_Info->TarTagQ_Cnt--;
2781 ACCEPT_MSG(port);
2782 } else {
2783 ACCEPT_MSG_ATN(port);
2784 }
2785 } else {
2786 pCurrCard->currentSCCB =
2787 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
2788 if (pCurrCard->currentSCCB != NULL) {
2789 ACCEPT_MSG(port);
2790 } else {
2791 ACCEPT_MSG_ATN(port);
2792 }
2793 }
2794 }
2795
2796 if (pCurrCard->currentSCCB != NULL) {
2797 if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) {
2798 /* During Abort Tag command, the target could have got re-selected
2799 and completed the command. Check the select Q and remove the CCB
2800 if it is in the Select Q */
2801 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
2802 }
2803 }
2804
2805 while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) &&
2806 !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) &&
2807 (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2808}
2809
2810static void FPT_SendMsg(u32 port, unsigned char message)
2811{
2812 while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2813 if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2814
2815 WRW_HARPOON((port + hp_intstat), PHASE);
2816 return;
2817 }
2818 }
2819
2820 WRW_HARPOON((port + hp_intstat), PHASE);
2821 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) {
2822 WRW_HARPOON((port + hp_intstat),
2823 (BUS_FREE | PHASE | XFER_CNT_0));
2824
2825 WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
2826
2827 WR_HARPOON(port + hp_scsidata_0, message);
2828
2829 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2830
2831 ACCEPT_MSG(port);
2832
2833 WR_HARPOON(port + hp_portctrl_0, 0x00);
2834
2835 if ((message == ABORT_TASK_SET) || (message == TARGET_RESET) ||
2836 (message == ABORT_TASK)) {
2837 while (!
2838 (RDW_HARPOON((port + hp_intstat)) &
2839 (BUS_FREE | PHASE))) {
2840 }
2841
2842 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2843 WRW_HARPOON((port + hp_intstat), BUS_FREE);
2844 }
2845 }
2846 }
2847}
2848
2849/*---------------------------------------------------------------------
2850 *
2851 * Function: FPT_sdecm
2852 *
2853 * Description: Determine the proper response to the message from the
2854 * target device.
2855 *
2856 *---------------------------------------------------------------------*/
2857static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
2858{
2859 struct sccb *currSCCB;
2860 struct sccb_card *CurrCard;
2861 struct sccb_mgr_tar_info *currTar_Info;
2862
2863 CurrCard = &FPT_BL_Card[p_card];
2864 currSCCB = CurrCard->currentSCCB;
2865
2866 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
2867
2868 if (message == RESTORE_POINTERS) {
2869 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) {
2870 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
2871
2872 FPT_hostDataXferRestart(currSCCB);
2873 }
2874
2875 ACCEPT_MSG(port);
2876 WR_HARPOON(port + hp_autostart_1,
2877 (AUTO_IMMED + DISCONNECT_START));
2878 }
2879
2880 else if (message == COMMAND_COMPLETE) {
2881
2882 if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
2883 currTar_Info->TarStatus &=
2884 ~(unsigned char)TAR_TAG_Q_MASK;
2885 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
2886 }
2887
2888 ACCEPT_MSG(port);
2889
2890 }
2891
2892 else if ((message == NOP) || (message >= IDENTIFY_BASE) ||
2893 (message == INITIATE_RECOVERY) ||
2894 (message == RELEASE_RECOVERY)) {
2895
2896 ACCEPT_MSG(port);
2897 WR_HARPOON(port + hp_autostart_1,
2898 (AUTO_IMMED + DISCONNECT_START));
2899 }
2900
2901 else if (message == MESSAGE_REJECT) {
2902
2903 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
2904 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
2905 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)
2906 || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) ==
2907 TAG_Q_TRYING))
2908 {
2909 WRW_HARPOON((port + hp_intstat), BUS_FREE);
2910
2911 ACCEPT_MSG(port);
2912
2913 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2914 (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
2915 {
2916 }
2917
2918 if (currSCCB->Lun == 0x00) {
2919 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2920
2921 currTar_Info->TarStatus |=
2922 (unsigned char)SYNC_SUPPORTED;
2923
2924 currTar_Info->TarEEValue &=
2925 ~EE_SYNC_MASK;
2926 }
2927
2928 else if (currSCCB->Sccb_scsistat ==
2929 SELECT_WN_ST) {
2930
2931 currTar_Info->TarStatus =
2932 (currTar_Info->
2933 TarStatus & ~WIDE_ENABLED) |
2934 WIDE_NEGOCIATED;
2935
2936 currTar_Info->TarEEValue &=
2937 ~EE_WIDE_SCSI;
2938
2939 }
2940
2941 else if ((currTar_Info->
2942 TarStatus & TAR_TAG_Q_MASK) ==
2943 TAG_Q_TRYING) {
2944 currTar_Info->TarStatus =
2945 (currTar_Info->
2946 TarStatus & ~(unsigned char)
2947 TAR_TAG_Q_MASK) | TAG_Q_REJECT;
2948
2949 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2950 CurrCard->discQCount--;
2951 CurrCard->discQ_Tbl[currSCCB->
2952 Sccb_tag] = NULL;
2953 currSCCB->Sccb_tag = 0x00;
2954
2955 }
2956 }
2957
2958 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2959
2960 if (currSCCB->Lun == 0x00) {
2961 WRW_HARPOON((port + hp_intstat),
2962 BUS_FREE);
2963 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
2964 }
2965 }
2966
2967 else {
2968
2969 if ((CurrCard->globalFlags & F_CONLUN_IO) &&
2970 ((currTar_Info->
2971 TarStatus & TAR_TAG_Q_MASK) !=
2972 TAG_Q_TRYING))
2973 currTar_Info->TarLUNBusy[currSCCB->
2974 Lun] = 1;
2975 else
2976 currTar_Info->TarLUNBusy[0] = 1;
2977
2978 currSCCB->ControlByte &=
2979 ~(unsigned char)F_USE_CMD_Q;
2980
2981 WR_HARPOON(port + hp_autostart_1,
2982 (AUTO_IMMED + DISCONNECT_START));
2983
2984 }
2985 }
2986
2987 else {
2988 ACCEPT_MSG(port);
2989
2990 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2991 (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
2992 {
2993 }
2994
2995 if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) {
2996 WR_HARPOON(port + hp_autostart_1,
2997 (AUTO_IMMED + DISCONNECT_START));
2998 }
2999 }
3000 }
3001
3002 else if (message == EXTENDED_MESSAGE) {
3003
3004 ACCEPT_MSG(port);
3005 FPT_shandem(port, p_card, currSCCB);
3006 }
3007
3008 else if (message == IGNORE_WIDE_RESIDUE) {
3009
3010 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3011
3012 message = FPT_sfm(port, currSCCB);
3013
3014 if (currSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
3015 ACCEPT_MSG(port);
3016 WR_HARPOON(port + hp_autostart_1,
3017 (AUTO_IMMED + DISCONNECT_START));
3018 }
3019
3020 else {
3021
3022 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3023 currSCCB->Sccb_scsimsg = MESSAGE_REJECT;
3024
3025 ACCEPT_MSG_ATN(port);
3026 WR_HARPOON(port + hp_autostart_1,
3027 (AUTO_IMMED + DISCONNECT_START));
3028 }
3029}
3030
3031/*---------------------------------------------------------------------
3032 *
3033 * Function: FPT_shandem
3034 *
3035 * Description: Decide what to do with the extended message.
3036 *
3037 *---------------------------------------------------------------------*/
3038static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
3039{
3040 unsigned char length, message;
3041
3042 length = FPT_sfm(port, pCurrSCCB);
3043 if (length) {
3044
3045 ACCEPT_MSG(port);
3046 message = FPT_sfm(port, pCurrSCCB);
3047 if (message) {
3048
3049 if (message == EXTENDED_SDTR) {
3050
3051 if (length == 0x03) {
3052
3053 ACCEPT_MSG(port);
3054 FPT_stsyncn(port, p_card);
3055 } else {
3056
3057 pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
3058 ACCEPT_MSG_ATN(port);
3059 }
3060 } else if (message == EXTENDED_WDTR) {
3061
3062 if (length == 0x02) {
3063
3064 ACCEPT_MSG(port);
3065 FPT_stwidn(port, p_card);
3066 } else {
3067
3068 pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
3069 ACCEPT_MSG_ATN(port);
3070
3071 WR_HARPOON(port + hp_autostart_1,
3072 (AUTO_IMMED +
3073 DISCONNECT_START));
3074 }
3075 } else {
3076
3077 pCurrSCCB->Sccb_scsimsg = MESSAGE_REJECT;
3078 ACCEPT_MSG_ATN(port);
3079
3080 WR_HARPOON(port + hp_autostart_1,
3081 (AUTO_IMMED + DISCONNECT_START));
3082 }
3083 } else {
3084 if (pCurrSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
3085 ACCEPT_MSG(port);
3086 WR_HARPOON(port + hp_autostart_1,
3087 (AUTO_IMMED + DISCONNECT_START));
3088 }
3089 } else {
3090 if (pCurrSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)
3091 WR_HARPOON(port + hp_autostart_1,
3092 (AUTO_IMMED + DISCONNECT_START));
3093 }
3094}
3095
3096/*---------------------------------------------------------------------
3097 *
3098 * Function: FPT_sisyncn
3099 *
3100 * Description: Read in a message byte from the SCSI bus, and check
3101 * for a parity error.
3102 *
3103 *---------------------------------------------------------------------*/
3104
3105static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
3106 unsigned char syncFlag)
3107{
3108 struct sccb *currSCCB;
3109 struct sccb_mgr_tar_info *currTar_Info;
3110
3111 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3112 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3113
3114 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3115
3116 WRW_HARPOON((port + ID_MSG_STRT),
3117 (MPM_OP + AMSG_OUT +
3118 (currSCCB->
3119 Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3120
3121 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3122
3123 WRW_HARPOON((port + SYNC_MSGS + 0),
3124 (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
3125 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3126 WRW_HARPOON((port + SYNC_MSGS + 4),
3127 (MPM_OP + AMSG_OUT + EXTENDED_SDTR));
3128
3129 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3130
3131 WRW_HARPOON((port + SYNC_MSGS + 6),
3132 (MPM_OP + AMSG_OUT + 12));
3133
3134 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3135 EE_SYNC_10MB)
3136
3137 WRW_HARPOON((port + SYNC_MSGS + 6),
3138 (MPM_OP + AMSG_OUT + 25));
3139
3140 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3141 EE_SYNC_5MB)
3142
3143 WRW_HARPOON((port + SYNC_MSGS + 6),
3144 (MPM_OP + AMSG_OUT + 50));
3145
3146 else
3147 WRW_HARPOON((port + SYNC_MSGS + 6),
3148 (MPM_OP + AMSG_OUT + 00));
3149
3150 WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3151 WRW_HARPOON((port + SYNC_MSGS + 10),
3152 (MPM_OP + AMSG_OUT + DEFAULT_OFFSET));
3153 WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3154
3155 if (syncFlag == 0) {
3156 WR_HARPOON(port + hp_autostart_3,
3157 (SELECT + SELCHK_STRT));
3158 currTar_Info->TarStatus =
3159 ((currTar_Info->
3160 TarStatus & ~(unsigned char)TAR_SYNC_MASK) |
3161 (unsigned char)SYNC_TRYING);
3162 } else {
3163 WR_HARPOON(port + hp_autostart_3,
3164 (AUTO_IMMED + CMD_ONLY_STRT));
3165 }
3166
3167 return 1;
3168 }
3169
3170 else {
3171
3172 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3173 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3174 return 0;
3175 }
3176}
3177
3178/*---------------------------------------------------------------------
3179 *
3180 * Function: FPT_stsyncn
3181 *
3182 * Description: The has sent us a Sync Nego message so handle it as
3183 * necessary.
3184 *
3185 *---------------------------------------------------------------------*/
3186static void FPT_stsyncn(u32 port, unsigned char p_card)
3187{
3188 unsigned char sync_msg, offset, sync_reg, our_sync_msg;
3189 struct sccb *currSCCB;
3190 struct sccb_mgr_tar_info *currTar_Info;
3191
3192 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3193 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3194
3195 sync_msg = FPT_sfm(port, currSCCB);
3196
3197 if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
3198 WR_HARPOON(port + hp_autostart_1,
3199 (AUTO_IMMED + DISCONNECT_START));
3200 return;
3201 }
3202
3203 ACCEPT_MSG(port);
3204
3205 offset = FPT_sfm(port, currSCCB);
3206
3207 if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
3208 WR_HARPOON(port + hp_autostart_1,
3209 (AUTO_IMMED + DISCONNECT_START));
3210 return;
3211 }
3212
3213 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3214
3215 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3216
3217 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3218
3219 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3220
3221 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3222
3223 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3224 else
3225
3226 our_sync_msg = 0; /* Message = Async */
3227
3228 if (sync_msg < our_sync_msg) {
3229 sync_msg = our_sync_msg; /*if faster, then set to max. */
3230 }
3231
3232 if (offset == ASYNC)
3233 sync_msg = ASYNC;
3234
3235 if (offset > MAX_OFFSET)
3236 offset = MAX_OFFSET;
3237
3238 sync_reg = 0x00;
3239
3240 if (sync_msg > 12)
3241
3242 sync_reg = 0x20; /* Use 10MB/s */
3243
3244 if (sync_msg > 25)
3245
3246 sync_reg = 0x40; /* Use 6.6MB/s */
3247
3248 if (sync_msg > 38)
3249
3250 sync_reg = 0x60; /* Use 5MB/s */
3251
3252 if (sync_msg > 50)
3253
3254 sync_reg = 0x80; /* Use 4MB/s */
3255
3256 if (sync_msg > 62)
3257
3258 sync_reg = 0xA0; /* Use 3.33MB/s */
3259
3260 if (sync_msg > 75)
3261
3262 sync_reg = 0xC0; /* Use 2.85MB/s */
3263
3264 if (sync_msg > 87)
3265
3266 sync_reg = 0xE0; /* Use 2.5MB/s */
3267
3268 if (sync_msg > 100) {
3269
3270 sync_reg = 0x00; /* Use ASYNC */
3271 offset = 0x00;
3272 }
3273
3274 if (currTar_Info->TarStatus & WIDE_ENABLED)
3275
3276 sync_reg |= offset;
3277
3278 else
3279
3280 sync_reg |= (offset | NARROW_SCSI);
3281
3282 FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info);
3283
3284 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3285
3286 ACCEPT_MSG(port);
3287
3288 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3289 ~(unsigned char)TAR_SYNC_MASK) |
3290 (unsigned char)SYNC_SUPPORTED);
3291
3292 WR_HARPOON(port + hp_autostart_1,
3293 (AUTO_IMMED + DISCONNECT_START));
3294 }
3295
3296 else {
3297
3298 ACCEPT_MSG_ATN(port);
3299
3300 FPT_sisyncr(port, sync_msg, offset);
3301
3302 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3303 ~(unsigned char)TAR_SYNC_MASK) |
3304 (unsigned char)SYNC_SUPPORTED);
3305 }
3306}
3307
3308/*---------------------------------------------------------------------
3309 *
3310 * Function: FPT_sisyncr
3311 *
3312 * Description: Answer the targets sync message.
3313 *
3314 *---------------------------------------------------------------------*/
3315static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
3316 unsigned char offset)
3317{
3318 ARAM_ACCESS(port);
3319 WRW_HARPOON((port + SYNC_MSGS + 0),
3320 (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
3321 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3322 WRW_HARPOON((port + SYNC_MSGS + 4),
3323 (MPM_OP + AMSG_OUT + EXTENDED_SDTR));
3324 WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse));
3325 WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3326 WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset));
3327 WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3328 SGRAM_ACCESS(port);
3329
3330 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3331 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3332
3333 WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3334
3335 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3336 }
3337}
3338
3339/*---------------------------------------------------------------------
3340 *
3341 * Function: FPT_siwidn
3342 *
3343 * Description: Read in a message byte from the SCSI bus, and check
3344 * for a parity error.
3345 *
3346 *---------------------------------------------------------------------*/
3347
3348static unsigned char FPT_siwidn(u32 port, unsigned char p_card)
3349{
3350 struct sccb *currSCCB;
3351 struct sccb_mgr_tar_info *currTar_Info;
3352
3353 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3354 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3355
3356 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3357
3358 WRW_HARPOON((port + ID_MSG_STRT),
3359 (MPM_OP + AMSG_OUT +
3360 (currSCCB->
3361 Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3362
3363 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3364
3365 WRW_HARPOON((port + SYNC_MSGS + 0),
3366 (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
3367 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3368 WRW_HARPOON((port + SYNC_MSGS + 4),
3369 (MPM_OP + AMSG_OUT + EXTENDED_WDTR));
3370 WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3371 WRW_HARPOON((port + SYNC_MSGS + 8),
3372 (MPM_OP + AMSG_OUT + SM16BIT));
3373 WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3374
3375 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
3376
3377 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3378 ~(unsigned char)TAR_WIDE_MASK) |
3379 (unsigned char)WIDE_ENABLED);
3380
3381 return 1;
3382 }
3383
3384 else {
3385
3386 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3387 ~(unsigned char)TAR_WIDE_MASK) |
3388 WIDE_NEGOCIATED);
3389
3390 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3391 return 0;
3392 }
3393}
3394
3395/*---------------------------------------------------------------------
3396 *
3397 * Function: FPT_stwidn
3398 *
3399 * Description: The has sent us a Wide Nego message so handle it as
3400 * necessary.
3401 *
3402 *---------------------------------------------------------------------*/
3403static void FPT_stwidn(u32 port, unsigned char p_card)
3404{
3405 unsigned char width;
3406 struct sccb *currSCCB;
3407 struct sccb_mgr_tar_info *currTar_Info;
3408
3409 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3410 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3411
3412 width = FPT_sfm(port, currSCCB);
3413
3414 if ((width == 0x00) && (currSCCB->Sccb_scsimsg == MSG_PARITY_ERROR)) {
3415 WR_HARPOON(port + hp_autostart_1,
3416 (AUTO_IMMED + DISCONNECT_START));
3417 return;
3418 }
3419
3420 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3421 width = 0;
3422
3423 if (width) {
3424 currTar_Info->TarStatus |= WIDE_ENABLED;
3425 width = 0;
3426 } else {
3427 width = NARROW_SCSI;
3428 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3429 }
3430
3431 FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info);
3432
3433 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
3434
3435 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3436
3437 if (!
3438 ((currTar_Info->TarStatus & TAR_SYNC_MASK) ==
3439 SYNC_SUPPORTED)) {
3440 ACCEPT_MSG_ATN(port);
3441 ARAM_ACCESS(port);
3442 FPT_sisyncn(port, p_card, 1);
3443 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3444 SGRAM_ACCESS(port);
3445 } else {
3446 ACCEPT_MSG(port);
3447 WR_HARPOON(port + hp_autostart_1,
3448 (AUTO_IMMED + DISCONNECT_START));
3449 }
3450 }
3451
3452 else {
3453
3454 ACCEPT_MSG_ATN(port);
3455
3456 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3457 width = SM16BIT;
3458 else
3459 width = SM8BIT;
3460
3461 FPT_siwidr(port, width);
3462
3463 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3464 }
3465}
3466
3467/*---------------------------------------------------------------------
3468 *
3469 * Function: FPT_siwidr
3470 *
3471 * Description: Answer the targets Wide nego message.
3472 *
3473 *---------------------------------------------------------------------*/
3474static void FPT_siwidr(u32 port, unsigned char width)
3475{
3476 ARAM_ACCESS(port);
3477 WRW_HARPOON((port + SYNC_MSGS + 0),
3478 (MPM_OP + AMSG_OUT + EXTENDED_MESSAGE));
3479 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3480 WRW_HARPOON((port + SYNC_MSGS + 4),
3481 (MPM_OP + AMSG_OUT + EXTENDED_WDTR));
3482 WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3483 WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width));
3484 WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3485 SGRAM_ACCESS(port);
3486
3487 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3488 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3489
3490 WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3491
3492 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3493 }
3494}
3495
3496/*---------------------------------------------------------------------
3497 *
3498 * Function: FPT_sssyncv
3499 *
3500 * Description: Write the desired value to the Sync Register for the
3501 * ID specified.
3502 *
3503 *---------------------------------------------------------------------*/
3504static void FPT_sssyncv(u32 p_port, unsigned char p_id,
3505 unsigned char p_sync_value,
3506 struct sccb_mgr_tar_info *currTar_Info)
3507{
3508 unsigned char index;
3509
3510 index = p_id;
3511
3512 switch (index) {
3513
3514 case 0:
3515 index = 12; /* hp_synctarg_0 */
3516 break;
3517 case 1:
3518 index = 13; /* hp_synctarg_1 */
3519 break;
3520 case 2:
3521 index = 14; /* hp_synctarg_2 */
3522 break;
3523 case 3:
3524 index = 15; /* hp_synctarg_3 */
3525 break;
3526 case 4:
3527 index = 8; /* hp_synctarg_4 */
3528 break;
3529 case 5:
3530 index = 9; /* hp_synctarg_5 */
3531 break;
3532 case 6:
3533 index = 10; /* hp_synctarg_6 */
3534 break;
3535 case 7:
3536 index = 11; /* hp_synctarg_7 */
3537 break;
3538 case 8:
3539 index = 4; /* hp_synctarg_8 */
3540 break;
3541 case 9:
3542 index = 5; /* hp_synctarg_9 */
3543 break;
3544 case 10:
3545 index = 6; /* hp_synctarg_10 */
3546 break;
3547 case 11:
3548 index = 7; /* hp_synctarg_11 */
3549 break;
3550 case 12:
3551 index = 0; /* hp_synctarg_12 */
3552 break;
3553 case 13:
3554 index = 1; /* hp_synctarg_13 */
3555 break;
3556 case 14:
3557 index = 2; /* hp_synctarg_14 */
3558 break;
3559 case 15:
3560 index = 3; /* hp_synctarg_15 */
3561
3562 }
3563
3564 WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value);
3565
3566 currTar_Info->TarSyncCtrl = p_sync_value;
3567}
3568
3569/*---------------------------------------------------------------------
3570 *
3571 * Function: FPT_sresb
3572 *
3573 * Description: Reset the desired card's SCSI bus.
3574 *
3575 *---------------------------------------------------------------------*/
3576static void FPT_sresb(u32 port, unsigned char p_card)
3577{
3578 unsigned char scsiID, i;
3579
3580 struct sccb_mgr_tar_info *currTar_Info;
3581
3582 WR_HARPOON(port + hp_page_ctrl,
3583 (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE));
3584 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3585
3586 WR_HARPOON(port + hp_scsictrl_0, SCSI_RST);
3587
3588 scsiID = RD_HARPOON(port + hp_seltimeout);
3589 WR_HARPOON(port + hp_seltimeout, TO_5ms);
3590 WRW_HARPOON((port + hp_intstat), TIMEOUT);
3591
3592 WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO));
3593
3594 while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) {
3595 }
3596
3597 WR_HARPOON(port + hp_seltimeout, scsiID);
3598
3599 WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
3600
3601 FPT_Wait(port, TO_5ms);
3602
3603 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3604
3605 WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00));
3606
3607 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
3608 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3609
3610 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
3611 currTar_Info->TarSyncCtrl = 0;
3612 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3613 }
3614
3615 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
3616 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3617 }
3618
3619 FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
3620
3621 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3622 }
3623
3624 FPT_BL_Card[p_card].scanIndex = 0x00;
3625 FPT_BL_Card[p_card].currentSCCB = NULL;
3626 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3627 | F_NEW_SCCB_CMD);
3628 FPT_BL_Card[p_card].cmdCounter = 0x00;
3629 FPT_BL_Card[p_card].discQCount = 0x00;
3630 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3631
3632 for (i = 0; i < QUEUE_DEPTH; i++)
3633 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3634
3635 WR_HARPOON(port + hp_page_ctrl,
3636 (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE));
3637
3638}
3639
3640/*---------------------------------------------------------------------
3641 *
3642 * Function: FPT_ssenss
3643 *
3644 * Description: Setup for the Auto Sense command.
3645 *
3646 *---------------------------------------------------------------------*/
3647static void FPT_ssenss(struct sccb_card *pCurrCard)
3648{
3649 unsigned char i;
3650 struct sccb *currSCCB;
3651
3652 currSCCB = pCurrCard->currentSCCB;
3653
3654 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3655
3656 for (i = 0; i < 6; i++) {
3657
3658 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3659 }
3660
3661 currSCCB->CdbLength = SIX_BYTE_CMD;
3662 currSCCB->Cdb[0] = REQUEST_SENSE;
3663 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3664 currSCCB->Cdb[2] = 0x00;
3665 currSCCB->Cdb[3] = 0x00;
3666 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3667 currSCCB->Cdb[5] = 0x00;
3668
3669 currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength;
3670
3671 currSCCB->Sccb_ATC = 0x00;
3672
3673 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3674
3675 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3676
3677 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3678
3679 currSCCB->ControlByte = 0x00;
3680
3681 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3682}
3683
3684/*---------------------------------------------------------------------
3685 *
3686 * Function: FPT_sxfrp
3687 *
3688 * Description: Transfer data into the bit bucket until the device
3689 * decides to switch phase.
3690 *
3691 *---------------------------------------------------------------------*/
3692
3693static void FPT_sxfrp(u32 p_port, unsigned char p_card)
3694{
3695 unsigned char curr_phz;
3696
3697 DISABLE_AUTO(p_port);
3698
3699 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3700
3701 FPT_hostDataXferAbort(p_port, p_card,
3702 FPT_BL_Card[p_card].currentSCCB);
3703
3704 }
3705
3706 /* If the Automation handled the end of the transfer then do not
3707 match the phase or we will get out of sync with the ISR. */
3708
3709 if (RDW_HARPOON((p_port + hp_intstat)) &
3710 (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3711 return;
3712
3713 WR_HARPOON(p_port + hp_xfercnt_0, 0x00);
3714
3715 curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3716
3717 WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0);
3718
3719 WR_HARPOON(p_port + hp_scsisig, curr_phz);
3720
3721 while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) &&
3722 (curr_phz ==
3723 (RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ)))
3724 {
3725 if (curr_phz & (unsigned char)SCSI_IOBIT) {
3726 WR_HARPOON(p_port + hp_portctrl_0,
3727 (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3728
3729 if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3730 RD_HARPOON(p_port + hp_fifodata_0);
3731 }
3732 } else {
3733 WR_HARPOON(p_port + hp_portctrl_0,
3734 (SCSI_PORT | HOST_PORT | HOST_WRT));
3735 if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) {
3736 WR_HARPOON(p_port + hp_fifodata_0, 0xFA);
3737 }
3738 }
3739 } /* End of While loop for padding data I/O phase */
3740
3741 while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3742 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ)
3743 break;
3744 }
3745
3746 WR_HARPOON(p_port + hp_portctrl_0,
3747 (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3748 while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3749 RD_HARPOON(p_port + hp_fifodata_0);
3750 }
3751
3752 if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3753 WR_HARPOON(p_port + hp_autostart_0,
3754 (AUTO_IMMED + DISCONNECT_START));
3755 while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) {
3756 }
3757
3758 if (RDW_HARPOON((p_port + hp_intstat)) &
3759 (ICMD_COMP | ITAR_DISC))
3760 while (!
3761 (RDW_HARPOON((p_port + hp_intstat)) &
3762 (BUS_FREE | RSEL))) ;
3763 }
3764}
3765
3766/*---------------------------------------------------------------------
3767 *
3768 * Function: FPT_schkdd
3769 *
3770 * Description: Make sure data has been flushed from both FIFOs and abort
3771 * the operations if necessary.
3772 *
3773 *---------------------------------------------------------------------*/
3774
3775static void FPT_schkdd(u32 port, unsigned char p_card)
3776{
3777 unsigned short TimeOutLoop;
3778 unsigned char sPhase;
3779
3780 struct sccb *currSCCB;
3781
3782 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3783
3784 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
3785 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
3786 return;
3787 }
3788
3789 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) {
3790
3791 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1);
3792
3793 currSCCB->Sccb_XferCnt = 1;
3794
3795 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
3796 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
3797 WR_HARPOON(port + hp_xferstat, 0x00);
3798 }
3799
3800 else {
3801
3802 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
3803
3804 currSCCB->Sccb_XferCnt = 0;
3805 }
3806
3807 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
3808 (currSCCB->HostStatus == SCCB_COMPLETE)) {
3809
3810 currSCCB->HostStatus = SCCB_PARITY_ERR;
3811 WRW_HARPOON((port + hp_intstat), PARITY);
3812 }
3813
3814 FPT_hostDataXferAbort(port, p_card, currSCCB);
3815
3816 while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) {
3817 }
3818
3819 TimeOutLoop = 0;
3820
3821 while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) {
3822 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
3823 return;
3824 }
3825 if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) {
3826 break;
3827 }
3828 if (RDW_HARPOON((port + hp_intstat)) & RESET) {
3829 return;
3830 }
3831 if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
3832 || (TimeOutLoop++ > 0x3000))
3833 break;
3834 }
3835
3836 sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
3837 if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) ||
3838 (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) ||
3839 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
3840 (sPhase == (SCSI_BSY | S_DATAI_PH))) {
3841
3842 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3843
3844 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) {
3845 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
3846 FPT_phaseDataIn(port, p_card);
3847 }
3848
3849 else {
3850 FPT_phaseDataOut(port, p_card);
3851 }
3852 } else {
3853 FPT_sxfrp(port, p_card);
3854 if (!(RDW_HARPOON((port + hp_intstat)) &
3855 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) {
3856 WRW_HARPOON((port + hp_intstat), AUTO_INT);
3857 FPT_phaseDecode(port, p_card);
3858 }
3859 }
3860
3861 }
3862
3863 else {
3864 WR_HARPOON(port + hp_portctrl_0, 0x00);
3865 }
3866}
3867
3868/*---------------------------------------------------------------------
3869 *
3870 * Function: FPT_sinits
3871 *
3872 * Description: Setup SCCB manager fields in this SCCB.
3873 *
3874 *---------------------------------------------------------------------*/
3875
3876static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
3877{
3878 struct sccb_mgr_tar_info *currTar_Info;
3879
3880 if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) {
3881 return;
3882 }
3883 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
3884
3885 p_sccb->Sccb_XferState = 0x00;
3886 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
3887
3888 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
3889 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
3890
3891 p_sccb->Sccb_SGoffset = 0;
3892 p_sccb->Sccb_XferState = F_SG_XFER;
3893 p_sccb->Sccb_XferCnt = 0x00;
3894 }
3895
3896 if (p_sccb->DataLength == 0x00)
3897
3898 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
3899
3900 if (p_sccb->ControlByte & F_USE_CMD_Q) {
3901 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
3902 p_sccb->ControlByte &= ~F_USE_CMD_Q;
3903
3904 else
3905 currTar_Info->TarStatus |= TAG_Q_TRYING;
3906 }
3907
3908/* For !single SCSI device in system & device allow Disconnect
3909 or command is tag_q type then send Cmd with Disconnect Enable
3910 else send Cmd with Disconnect Disable */
3911
3912/*
3913 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
3914 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
3915 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3916*/
3917 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
3918 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3919 p_sccb->Sccb_idmsg = IDENTIFY(true, p_sccb->Lun);
3920 } else {
3921 p_sccb->Sccb_idmsg = IDENTIFY(false, p_sccb->Lun);
3922 }
3923
3924 p_sccb->HostStatus = 0x00;
3925 p_sccb->TargetStatus = 0x00;
3926 p_sccb->Sccb_tag = 0x00;
3927 p_sccb->Sccb_MGRFlags = 0x00;
3928 p_sccb->Sccb_sgseg = 0x00;
3929 p_sccb->Sccb_ATC = 0x00;
3930 p_sccb->Sccb_savedATC = 0x00;
3931/*
3932 p_sccb->SccbVirtDataPtr = 0x00;
3933 p_sccb->Sccb_forwardlink = NULL;
3934 p_sccb->Sccb_backlink = NULL;
3935 */
3936 p_sccb->Sccb_scsistat = BUS_FREE_ST;
3937 p_sccb->SccbStatus = SCCB_IN_PROCESS;
3938 p_sccb->Sccb_scsimsg = NOP;
3939
3940}
3941
3942/*---------------------------------------------------------------------
3943 *
3944 * Function: Phase Decode
3945 *
3946 * Description: Determine the phase and call the appropriate function.
3947 *
3948 *---------------------------------------------------------------------*/
3949
3950static void FPT_phaseDecode(u32 p_port, unsigned char p_card)
3951{
3952 unsigned char phase_ref;
3953 void (*phase) (u32, unsigned char);
3954
3955 DISABLE_AUTO(p_port);
3956
3957 phase_ref =
3958 (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ);
3959
3960 phase = FPT_s_PhaseTbl[phase_ref];
3961
3962 (*phase) (p_port, p_card); /* Call the correct phase func */
3963}
3964
3965/*---------------------------------------------------------------------
3966 *
3967 * Function: Data Out Phase
3968 *
3969 * Description: Start up both the BusMaster and Xbow.
3970 *
3971 *---------------------------------------------------------------------*/
3972
3973static void FPT_phaseDataOut(u32 port, unsigned char p_card)
3974{
3975
3976 struct sccb *currSCCB;
3977
3978 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3979 if (currSCCB == NULL) {
3980 return; /* Exit if No SCCB record */
3981 }
3982
3983 currSCCB->Sccb_scsistat = DATA_OUT_ST;
3984 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
3985
3986 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3987
3988 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
3989
3990 WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
3991
3992 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
3993
3994 if (currSCCB->Sccb_XferCnt == 0) {
3995
3996 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
3997 (currSCCB->HostStatus == SCCB_COMPLETE))
3998 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
3999
4000 FPT_sxfrp(port, p_card);
4001 if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4002 FPT_phaseDecode(port, p_card);
4003 }
4004}
4005
4006/*---------------------------------------------------------------------
4007 *
4008 * Function: Data In Phase
4009 *
4010 * Description: Startup the BusMaster and the XBOW.
4011 *
4012 *---------------------------------------------------------------------*/
4013
4014static void FPT_phaseDataIn(u32 port, unsigned char p_card)
4015{
4016
4017 struct sccb *currSCCB;
4018
4019 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4020
4021 if (currSCCB == NULL) {
4022 return; /* Exit if No SCCB record */
4023 }
4024
4025 currSCCB->Sccb_scsistat = DATA_IN_ST;
4026 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4027 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4028
4029 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4030
4031 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4032
4033 WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4034
4035 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4036
4037 if (currSCCB->Sccb_XferCnt == 0) {
4038
4039 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4040 (currSCCB->HostStatus == SCCB_COMPLETE))
4041 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4042
4043 FPT_sxfrp(port, p_card);
4044 if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4045 FPT_phaseDecode(port, p_card);
4046
4047 }
4048}
4049
4050/*---------------------------------------------------------------------
4051 *
4052 * Function: Command Phase
4053 *
4054 * Description: Load the CDB into the automation and start it up.
4055 *
4056 *---------------------------------------------------------------------*/
4057
4058static void FPT_phaseCommand(u32 p_port, unsigned char p_card)
4059{
4060 struct sccb *currSCCB;
4061 u32 cdb_reg;
4062 unsigned char i;
4063
4064 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4065
4066 if (currSCCB->OperationCode == RESET_COMMAND) {
4067
4068 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4069 currSCCB->CdbLength = SIX_BYTE_CMD;
4070 }
4071
4072 WR_HARPOON(p_port + hp_scsisig, 0x00);
4073
4074 ARAM_ACCESS(p_port);
4075
4076 cdb_reg = p_port + CMD_STRT;
4077
4078 for (i = 0; i < currSCCB->CdbLength; i++) {
4079
4080 if (currSCCB->OperationCode == RESET_COMMAND)
4081
4082 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4083
4084 else
4085 WRW_HARPOON(cdb_reg,
4086 (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4087 cdb_reg += 2;
4088 }
4089
4090 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4091 WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
4092
4093 WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT));
4094
4095 currSCCB->Sccb_scsistat = COMMAND_ST;
4096
4097 WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4098 SGRAM_ACCESS(p_port);
4099}
4100
4101/*---------------------------------------------------------------------
4102 *
4103 * Function: Status phase
4104 *
4105 * Description: Bring in the status and command complete message bytes
4106 *
4107 *---------------------------------------------------------------------*/
4108
4109static void FPT_phaseStatus(u32 port, unsigned char p_card)
4110{
4111 /* Start-up the automation to finish off this command and let the
4112 isr handle the interrupt for command complete when it comes in.
4113 We could wait here for the interrupt to be generated?
4114 */
4115
4116 WR_HARPOON(port + hp_scsisig, 0x00);
4117
4118 WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START));
4119}
4120
4121/*---------------------------------------------------------------------
4122 *
4123 * Function: Phase Message Out
4124 *
4125 * Description: Send out our message (if we have one) and handle whatever
4126 * else is involed.
4127 *
4128 *---------------------------------------------------------------------*/
4129
4130static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
4131{
4132 unsigned char message, scsiID;
4133 struct sccb *currSCCB;
4134 struct sccb_mgr_tar_info *currTar_Info;
4135
4136 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4137
4138 if (currSCCB != NULL) {
4139
4140 message = currSCCB->Sccb_scsimsg;
4141 scsiID = currSCCB->TargID;
4142
4143 if (message == TARGET_RESET) {
4144
4145 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4146 currTar_Info->TarSyncCtrl = 0;
4147 FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
4148
4149 if (FPT_sccbMgrTbl[p_card][scsiID].
4150 TarEEValue & EE_SYNC_MASK) {
4151
4152 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4153 ~TAR_SYNC_MASK;
4154
4155 }
4156
4157 if (FPT_sccbMgrTbl[p_card][scsiID].
4158 TarEEValue & EE_WIDE_SCSI) {
4159
4160 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4161 ~TAR_WIDE_MASK;
4162 }
4163
4164 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4165 FPT_SccbMgrTableInitTarget(p_card, scsiID);
4166 } else if (currSCCB->Sccb_scsistat == ABORT_ST) {
4167 currSCCB->HostStatus = SCCB_COMPLETE;
4168 if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] !=
4169 NULL) {
4170 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4171 Sccb_tag] = NULL;
4172 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4173 }
4174
4175 }
4176
4177 else if (currSCCB->Sccb_scsistat < COMMAND_ST) {
4178
4179 if (message == NOP) {
4180 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4181
4182 FPT_ssel(port, p_card);
4183 return;
4184 }
4185 } else {
4186
4187 if (message == ABORT_TASK_SET)
4188
4189 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4190 }
4191
4192 } else {
4193 message = ABORT_TASK_SET;
4194 }
4195
4196 WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4197
4198 WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
4199
4200 WR_HARPOON(port + hp_scsidata_0, message);
4201
4202 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
4203
4204 ACCEPT_MSG(port);
4205
4206 WR_HARPOON(port + hp_portctrl_0, 0x00);
4207
4208 if ((message == ABORT_TASK_SET) || (message == TARGET_RESET) ||
4209 (message == ABORT_TASK)) {
4210
4211 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) {
4212 }
4213
4214 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
4215 WRW_HARPOON((port + hp_intstat), BUS_FREE);
4216
4217 if (currSCCB != NULL) {
4218
4219 if ((FPT_BL_Card[p_card].
4220 globalFlags & F_CONLUN_IO)
4221 &&
4222 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4223 TarStatus & TAR_TAG_Q_MASK) !=
4224 TAG_Q_TRYING))
4225 FPT_sccbMgrTbl[p_card][currSCCB->
4226 TargID].
4227 TarLUNBusy[currSCCB->Lun] = 0;
4228 else
4229 FPT_sccbMgrTbl[p_card][currSCCB->
4230 TargID].
4231 TarLUNBusy[0] = 0;
4232
4233 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
4234 currSCCB, p_card);
4235 }
4236
4237 else {
4238 FPT_BL_Card[p_card].globalFlags |=
4239 F_NEW_SCCB_CMD;
4240 }
4241 }
4242
4243 else {
4244
4245 FPT_sxfrp(port, p_card);
4246 }
4247 }
4248
4249 else {
4250
4251 if (message == MSG_PARITY_ERROR) {
4252 currSCCB->Sccb_scsimsg = NOP;
4253 WR_HARPOON(port + hp_autostart_1,
4254 (AUTO_IMMED + DISCONNECT_START));
4255 } else {
4256 FPT_sxfrp(port, p_card);
4257 }
4258 }
4259}
4260
4261/*---------------------------------------------------------------------
4262 *
4263 * Function: Message In phase
4264 *
4265 * Description: Bring in the message and determine what to do with it.
4266 *
4267 *---------------------------------------------------------------------*/
4268
4269static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
4270{
4271 unsigned char message;
4272 struct sccb *currSCCB;
4273
4274 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4275
4276 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
4277
4278 FPT_phaseChkFifo(port, p_card);
4279 }
4280
4281 message = RD_HARPOON(port + hp_scsidata_0);
4282 if ((message == DISCONNECT) || (message == SAVE_POINTERS)) {
4283
4284 WR_HARPOON(port + hp_autostart_1,
4285 (AUTO_IMMED + END_DATA_START));
4286
4287 }
4288
4289 else {
4290
4291 message = FPT_sfm(port, currSCCB);
4292 if (message) {
4293
4294 FPT_sdecm(message, port, p_card);
4295
4296 } else {
4297 if (currSCCB->Sccb_scsimsg != MSG_PARITY_ERROR)
4298 ACCEPT_MSG(port);
4299 WR_HARPOON(port + hp_autostart_1,
4300 (AUTO_IMMED + DISCONNECT_START));
4301 }
4302 }
4303
4304}
4305
4306/*---------------------------------------------------------------------
4307 *
4308 * Function: Illegal phase
4309 *
4310 * Description: Target switched to some illegal phase, so all we can do
4311 * is report an error back to the host (if that is possible)
4312 * and send an ABORT message to the misbehaving target.
4313 *
4314 *---------------------------------------------------------------------*/
4315
4316static void FPT_phaseIllegal(u32 port, unsigned char p_card)
4317{
4318 struct sccb *currSCCB;
4319
4320 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4321
4322 WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig));
4323 if (currSCCB != NULL) {
4324
4325 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4326 currSCCB->Sccb_scsistat = ABORT_ST;
4327 currSCCB->Sccb_scsimsg = ABORT_TASK_SET;
4328 }
4329
4330 ACCEPT_MSG_ATN(port);
4331}
4332
4333/*---------------------------------------------------------------------
4334 *
4335 * Function: Phase Check FIFO
4336 *
4337 * Description: Make sure data has been flushed from both FIFOs and abort
4338 * the operations if necessary.
4339 *
4340 *---------------------------------------------------------------------*/
4341
4342static void FPT_phaseChkFifo(u32 port, unsigned char p_card)
4343{
4344 u32 xfercnt;
4345 struct sccb *currSCCB;
4346
4347 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4348
4349 if (currSCCB->Sccb_scsistat == DATA_IN_ST) {
4350
4351 while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) &&
4352 (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) {
4353 }
4354
4355 if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) {
4356 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4357
4358 currSCCB->Sccb_XferCnt = 0;
4359
4360 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4361 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4362 currSCCB->HostStatus = SCCB_PARITY_ERR;
4363 WRW_HARPOON((port + hp_intstat), PARITY);
4364 }
4365
4366 FPT_hostDataXferAbort(port, p_card, currSCCB);
4367
4368 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4369
4370 while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY))
4371 && (RD_HARPOON(port + hp_ext_status) &
4372 BM_CMD_BUSY)) {
4373 }
4374
4375 }
4376 }
4377
4378 /*End Data In specific code. */
4379 GET_XFER_CNT(port, xfercnt);
4380
4381 WR_HARPOON(port + hp_xfercnt_0, 0x00);
4382
4383 WR_HARPOON(port + hp_portctrl_0, 0x00);
4384
4385 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4386
4387 currSCCB->Sccb_XferCnt = xfercnt;
4388
4389 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4390 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4391
4392 currSCCB->HostStatus = SCCB_PARITY_ERR;
4393 WRW_HARPOON((port + hp_intstat), PARITY);
4394 }
4395
4396 FPT_hostDataXferAbort(port, p_card, currSCCB);
4397
4398 WR_HARPOON(port + hp_fifowrite, 0x00);
4399 WR_HARPOON(port + hp_fiforead, 0x00);
4400 WR_HARPOON(port + hp_xferstat, 0x00);
4401
4402 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4403}
4404
4405/*---------------------------------------------------------------------
4406 *
4407 * Function: Phase Bus Free
4408 *
4409 * Description: We just went bus free so figure out if it was
4410 * because of command complete or from a disconnect.
4411 *
4412 *---------------------------------------------------------------------*/
4413static void FPT_phaseBusFree(u32 port, unsigned char p_card)
4414{
4415 struct sccb *currSCCB;
4416
4417 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4418
4419 if (currSCCB != NULL) {
4420
4421 DISABLE_AUTO(port);
4422
4423 if (currSCCB->OperationCode == RESET_COMMAND) {
4424
4425 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4426 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4427 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4428 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4429 TarLUNBusy[currSCCB->Lun] = 0;
4430 else
4431 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4432 TarLUNBusy[0] = 0;
4433
4434 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4435 p_card);
4436
4437 FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card);
4438
4439 }
4440
4441 else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4442 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4443 (unsigned char)SYNC_SUPPORTED;
4444 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4445 ~EE_SYNC_MASK;
4446 }
4447
4448 else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4449 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4450 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4451 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4452
4453 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4454 ~EE_WIDE_SCSI;
4455 }
4456
4457 else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
4458 /* Make sure this is not a phony BUS_FREE. If we were
4459 reselected or if BUSY is NOT on then this is a
4460 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4461
4462 if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ||
4463 (RDW_HARPOON((port + hp_intstat)) & RSEL)) {
4464 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4465 TarStatus &= ~TAR_TAG_Q_MASK;
4466 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4467 TarStatus |= TAG_Q_REJECT;
4468 }
4469
4470 else {
4471 return;
4472 }
4473 }
4474
4475 else {
4476
4477 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4478
4479 if (!currSCCB->HostStatus) {
4480 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4481 }
4482
4483 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4484 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4485 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4486 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4487 TarLUNBusy[currSCCB->Lun] = 0;
4488 else
4489 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4490 TarLUNBusy[0] = 0;
4491
4492 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4493 p_card);
4494 return;
4495 }
4496
4497 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4498
4499 } /*end if !=null */
4500}
4501
4502/*---------------------------------------------------------------------
4503 *
4504 * Function: Auto Load Default Map
4505 *
4506 * Description: Load the Automation RAM with the default map values.
4507 *
4508 *---------------------------------------------------------------------*/
4509static void FPT_autoLoadDefaultMap(u32 p_port)
4510{
4511 u32 map_addr;
4512
4513 ARAM_ACCESS(p_port);
4514 map_addr = p_port + hp_aramBase;
4515
4516 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0)); /*ID MESSAGE */
4517 map_addr += 2;
4518 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20)); /*SIMPLE TAG QUEUEING MSG */
4519 map_addr += 2;
4520 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4521 map_addr += 2;
4522 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00)); /*TAG ID MSG */
4523 map_addr += 2;
4524 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 0 */
4525 map_addr += 2;
4526 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 1 */
4527 map_addr += 2;
4528 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 2 */
4529 map_addr += 2;
4530 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 3 */
4531 map_addr += 2;
4532 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 4 */
4533 map_addr += 2;
4534 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 5 */
4535 map_addr += 2;
4536 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 6 */
4537 map_addr += 2;
4538 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 7 */
4539 map_addr += 2;
4540 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 8 */
4541 map_addr += 2;
4542 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 9 */
4543 map_addr += 2;
4544 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 10 */
4545 map_addr += 2;
4546 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 11 */
4547 map_addr += 2;
4548 WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT)); /*JUMP IF DATA OUT */
4549 map_addr += 2;
4550 WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI)); /*JUMP IF NO DATA IN FIFO */
4551 map_addr += 2; /*This means AYNC DATA IN */
4552 WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4553 map_addr += 2;
4554 WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT)); /*JUMP IF NOT DATA IN PHZ */
4555 map_addr += 2;
4556 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4557 map_addr += 2;
4558 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02)); /*SAVE DATA PTR MSG? */
4559 map_addr += 2;
4560 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC)); /*GO CHECK FOR DISCONNECT MSG */
4561 map_addr += 2;
4562 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1)); /*SAVE DATA PTRS MSG */
4563 map_addr += 2;
4564 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK DATA IN */
4565 map_addr += 2;
4566 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04)); /*DISCONNECT MSG? */
4567 map_addr += 2;
4568 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN)); /*UKNKNOWN MSG */
4569 map_addr += 2;
4570 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*XFER DISCONNECT MSG */
4571 map_addr += 2;
4572 WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC)); /*STOP AND INTERRUPT */
4573 map_addr += 2;
4574 WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN)); /*JUMP IF NOT STATUS PHZ. */
4575 map_addr += 2;
4576 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0)); /*GET STATUS BYTE */
4577 map_addr += 2;
4578 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC)); /*ERROR IF NOT MSG IN PHZ */
4579 map_addr += 2;
4580 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4581 map_addr += 2;
4582 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4583 map_addr += 2;
4584 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*GET CMD COMPLETE MSG */
4585 map_addr += 2;
4586 WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP)); /*END OF COMMAND */
4587 map_addr += 2;
4588
4589 WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4590 map_addr += 2;
4591 WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4592 map_addr += 2;
4593 WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4594 map_addr += 2;
4595 WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4596 map_addr += 2; /* DIDN'T GET ONE */
4597 WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG)); /* comp SCSI SEL ID & AR3 */
4598 map_addr += 2;
4599 WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00)); /*SEL ID OK then Conti. */
4600 map_addr += 2;
4601 WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4602
4603 SGRAM_ACCESS(p_port);
4604}
4605
4606/*---------------------------------------------------------------------
4607 *
4608 * Function: Auto Command Complete
4609 *
4610 * Description: Post command back to host and find another command
4611 * to execute.
4612 *
4613 *---------------------------------------------------------------------*/
4614
4615static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
4616{
4617 struct sccb *currSCCB;
4618 unsigned char status_byte;
4619
4620 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4621
4622 status_byte = RD_HARPOON(p_port + hp_gp_reg_0);
4623
4624 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4625
4626 if (status_byte != SAM_STAT_GOOD) {
4627
4628 if (status_byte == SAM_STAT_TASK_SET_FULL) {
4629
4630 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4631 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4632 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4633 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4634 TarLUNBusy[currSCCB->Lun] = 1;
4635 if (FPT_BL_Card[p_card].discQCount != 0)
4636 FPT_BL_Card[p_card].discQCount--;
4637 FPT_BL_Card[p_card].
4638 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4639 [currSCCB->TargID].
4640 LunDiscQ_Idx[currSCCB->Lun]] =
4641 NULL;
4642 } else {
4643 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4644 TarLUNBusy[0] = 1;
4645 if (currSCCB->Sccb_tag) {
4646 if (FPT_BL_Card[p_card].discQCount != 0)
4647 FPT_BL_Card[p_card].
4648 discQCount--;
4649 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4650 Sccb_tag]
4651 = NULL;
4652 } else {
4653 if (FPT_BL_Card[p_card].discQCount != 0)
4654 FPT_BL_Card[p_card].
4655 discQCount--;
4656 FPT_BL_Card[p_card].
4657 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4658 [currSCCB->TargID].
4659 LunDiscQ_Idx[0]] = NULL;
4660 }
4661 }
4662
4663 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4664
4665 FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
4666
4667 return;
4668 }
4669
4670 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4671 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4672 (unsigned char)SYNC_SUPPORTED;
4673
4674 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4675 ~EE_SYNC_MASK;
4676 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4677
4678 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4679 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4680 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4681 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4682 TarLUNBusy[currSCCB->Lun] = 1;
4683 if (FPT_BL_Card[p_card].discQCount != 0)
4684 FPT_BL_Card[p_card].discQCount--;
4685 FPT_BL_Card[p_card].
4686 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4687 [currSCCB->TargID].
4688 LunDiscQ_Idx[currSCCB->Lun]] =
4689 NULL;
4690 } else {
4691 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4692 TarLUNBusy[0] = 1;
4693 if (currSCCB->Sccb_tag) {
4694 if (FPT_BL_Card[p_card].discQCount != 0)
4695 FPT_BL_Card[p_card].
4696 discQCount--;
4697 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4698 Sccb_tag]
4699 = NULL;
4700 } else {
4701 if (FPT_BL_Card[p_card].discQCount != 0)
4702 FPT_BL_Card[p_card].
4703 discQCount--;
4704 FPT_BL_Card[p_card].
4705 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4706 [currSCCB->TargID].
4707 LunDiscQ_Idx[0]] = NULL;
4708 }
4709 }
4710 return;
4711
4712 }
4713
4714 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4715
4716 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4717 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4718 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4719
4720 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4721 ~EE_WIDE_SCSI;
4722 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4723
4724 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4725 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4726 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4727 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4728 TarLUNBusy[currSCCB->Lun] = 1;
4729 if (FPT_BL_Card[p_card].discQCount != 0)
4730 FPT_BL_Card[p_card].discQCount--;
4731 FPT_BL_Card[p_card].
4732 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4733 [currSCCB->TargID].
4734 LunDiscQ_Idx[currSCCB->Lun]] =
4735 NULL;
4736 } else {
4737 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4738 TarLUNBusy[0] = 1;
4739 if (currSCCB->Sccb_tag) {
4740 if (FPT_BL_Card[p_card].discQCount != 0)
4741 FPT_BL_Card[p_card].
4742 discQCount--;
4743 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4744 Sccb_tag]
4745 = NULL;
4746 } else {
4747 if (FPT_BL_Card[p_card].discQCount != 0)
4748 FPT_BL_Card[p_card].
4749 discQCount--;
4750 FPT_BL_Card[p_card].
4751 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4752 [currSCCB->TargID].
4753 LunDiscQ_Idx[0]] = NULL;
4754 }
4755 }
4756 return;
4757
4758 }
4759
4760 if (status_byte == SAM_STAT_CHECK_CONDITION) {
4761 if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) {
4762 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4763 TarEEValue & EE_SYNC_MASK) {
4764 FPT_sccbMgrTbl[p_card][currSCCB->
4765 TargID].
4766 TarStatus &= ~TAR_SYNC_MASK;
4767 }
4768 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4769 TarEEValue & EE_WIDE_SCSI) {
4770 FPT_sccbMgrTbl[p_card][currSCCB->
4771 TargID].
4772 TarStatus &= ~TAR_WIDE_MASK;
4773 }
4774 }
4775 }
4776
4777 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
4778
4779 currSCCB->SccbStatus = SCCB_ERROR;
4780 currSCCB->TargetStatus = status_byte;
4781
4782 if (status_byte == SAM_STAT_CHECK_CONDITION) {
4783
4784 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4785 TarLUN_CA = 1;
4786
4787 if (currSCCB->RequestSenseLength !=
4788 NO_AUTO_REQUEST_SENSE) {
4789
4790 if (currSCCB->RequestSenseLength == 0)
4791 currSCCB->RequestSenseLength =
4792 14;
4793
4794 FPT_ssenss(&FPT_BL_Card[p_card]);
4795 FPT_BL_Card[p_card].globalFlags |=
4796 F_NEW_SCCB_CMD;
4797
4798 if (((FPT_BL_Card[p_card].
4799 globalFlags & F_CONLUN_IO)
4800 &&
4801 ((FPT_sccbMgrTbl[p_card]
4802 [currSCCB->TargID].
4803 TarStatus & TAR_TAG_Q_MASK) !=
4804 TAG_Q_TRYING))) {
4805 FPT_sccbMgrTbl[p_card]
4806 [currSCCB->TargID].
4807 TarLUNBusy[currSCCB->Lun] =
4808 1;
4809 if (FPT_BL_Card[p_card].
4810 discQCount != 0)
4811 FPT_BL_Card[p_card].
4812 discQCount--;
4813 FPT_BL_Card[p_card].
4814 discQ_Tbl[FPT_sccbMgrTbl
4815 [p_card]
4816 [currSCCB->
4817 TargID].
4818 LunDiscQ_Idx
4819 [currSCCB->Lun]] =
4820 NULL;
4821 } else {
4822 FPT_sccbMgrTbl[p_card]
4823 [currSCCB->TargID].
4824 TarLUNBusy[0] = 1;
4825 if (currSCCB->Sccb_tag) {
4826 if (FPT_BL_Card[p_card].
4827 discQCount != 0)
4828 FPT_BL_Card
4829 [p_card].
4830 discQCount--;
4831 FPT_BL_Card[p_card].
4832 discQ_Tbl[currSCCB->
4833 Sccb_tag]
4834 = NULL;
4835 } else {
4836 if (FPT_BL_Card[p_card].
4837 discQCount != 0)
4838 FPT_BL_Card
4839 [p_card].
4840 discQCount--;
4841 FPT_BL_Card[p_card].
4842 discQ_Tbl
4843 [FPT_sccbMgrTbl
4844 [p_card][currSCCB->
4845 TargID].
4846 LunDiscQ_Idx[0]] =
4847 NULL;
4848 }
4849 }
4850 return;
4851 }
4852 }
4853 }
4854 }
4855
4856 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4857 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4858 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4859 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->
4860 Lun] = 0;
4861 else
4862 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4863
4864 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4865}
4866
4867#define SHORT_WAIT 0x0000000F
4868#define LONG_WAIT 0x0000FFFFL
4869
4870/*---------------------------------------------------------------------
4871 *
4872 * Function: Data Transfer Processor
4873 *
4874 * Description: This routine performs two tasks.
4875 * (1) Start data transfer by calling HOST_DATA_XFER_START
4876 * function. Once data transfer is started, (2) Depends
4877 * on the type of data transfer mode Scatter/Gather mode
4878 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
4879 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
4880 * data transfer done. In Scatter/Gather mode, this routine
4881 * checks bus master command complete and dual rank busy
4882 * bit to keep chaining SC transfer command. Similarly,
4883 * in Scatter/Gather mode, it checks Sccb_MGRFlag
4884 * (F_HOST_XFER_ACT bit) for data transfer done.
4885 *
4886 *---------------------------------------------------------------------*/
4887
4888static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard)
4889{
4890 struct sccb *currSCCB;
4891
4892 currSCCB = pCurrCard->currentSCCB;
4893
4894 if (currSCCB->Sccb_XferState & F_SG_XFER) {
4895 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
4896 {
4897 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
4898 currSCCB->Sccb_SGoffset = 0x00;
4899 }
4900 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4901
4902 FPT_busMstrSGDataXferStart(port, currSCCB);
4903 }
4904
4905 else {
4906 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) {
4907 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4908
4909 FPT_busMstrDataXferStart(port, currSCCB);
4910 }
4911 }
4912}
4913
4914/*---------------------------------------------------------------------
4915 *
4916 * Function: BusMaster Scatter Gather Data Transfer Start
4917 *
4918 * Description:
4919 *
4920 *---------------------------------------------------------------------*/
4921static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
4922{
4923 u32 count, addr, tmpSGCnt;
4924 unsigned int sg_index;
4925 unsigned char sg_count, i;
4926 u32 reg_offset;
4927 struct blogic_sg_seg *segp;
4928
4929 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)
4930 count = ((u32)HOST_RD_CMD) << 24;
4931 else
4932 count = ((u32)HOST_WRT_CMD) << 24;
4933
4934 sg_count = 0;
4935 tmpSGCnt = 0;
4936 sg_index = pcurrSCCB->Sccb_sgseg;
4937 reg_offset = hp_aramBase;
4938
4939 i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
4940 ~(SGRAM_ARAM | SCATTER_EN));
4941
4942 WR_HARPOON(p_port + hp_page_ctrl, i);
4943
4944 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
4945 ((sg_index * (unsigned int)SG_ELEMENT_SIZE) <
4946 pcurrSCCB->DataLength)) {
4947
4948 segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) +
4949 sg_index;
4950 tmpSGCnt += segp->segbytes;
4951 count |= segp->segbytes;
4952 addr = segp->segdata;
4953
4954 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
4955 addr +=
4956 ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
4957 count =
4958 (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
4959 tmpSGCnt = count & 0x00FFFFFFL;
4960 }
4961
4962 WR_HARP32(p_port, reg_offset, addr);
4963 reg_offset += 4;
4964
4965 WR_HARP32(p_port, reg_offset, count);
4966 reg_offset += 4;
4967
4968 count &= 0xFF000000L;
4969 sg_index++;
4970 sg_count++;
4971
4972 } /*End While */
4973
4974 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
4975
4976 WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4));
4977
4978 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
4979
4980 WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
4981
4982 WR_HARPOON(p_port + hp_portctrl_0,
4983 (DMA_PORT | SCSI_PORT | SCSI_INBIT));
4984 WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
4985 }
4986
4987 else {
4988
4989 if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) &&
4990 (tmpSGCnt & 0x000000001)) {
4991
4992 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
4993 tmpSGCnt--;
4994 }
4995
4996 WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
4997
4998 WR_HARPOON(p_port + hp_portctrl_0,
4999 (SCSI_PORT | DMA_PORT | DMA_RD));
5000 WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5001 }
5002
5003 WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN));
5004
5005}
5006
5007/*---------------------------------------------------------------------
5008 *
5009 * Function: BusMaster Data Transfer Start
5010 *
5011 * Description:
5012 *
5013 *---------------------------------------------------------------------*/
5014static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
5015{
5016 u32 addr, count;
5017
5018 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5019
5020 count = pcurrSCCB->Sccb_XferCnt;
5021
5022 addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5023 }
5024
5025 else {
5026 addr = pcurrSCCB->SensePointer;
5027 count = pcurrSCCB->RequestSenseLength;
5028
5029 }
5030
5031 HP_SETUP_ADDR_CNT(p_port, addr, count);
5032
5033 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5034
5035 WR_HARPOON(p_port + hp_portctrl_0,
5036 (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5037 WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5038
5039 WR_HARPOON(p_port + hp_xfer_cmd,
5040 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5041 }
5042
5043 else {
5044
5045 WR_HARPOON(p_port + hp_portctrl_0,
5046 (SCSI_PORT | DMA_PORT | DMA_RD));
5047 WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5048
5049 WR_HARPOON(p_port + hp_xfer_cmd,
5050 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5051
5052 }
5053}
5054
5055/*---------------------------------------------------------------------
5056 *
5057 * Function: BusMaster Timeout Handler
5058 *
5059 * Description: This function is called after a bus master command busy time
5060 * out is detected. This routines issue halt state machine
5061 * with a software time out for command busy. If command busy
5062 * is still asserted at the end of the time out, it issues
5063 * hard abort with another software time out. It hard abort
5064 * command busy is also time out, it'll just give up.
5065 *
5066 *---------------------------------------------------------------------*/
5067static unsigned char FPT_busMstrTimeOut(u32 p_port)
5068{
5069 unsigned long timeout;
5070
5071 timeout = LONG_WAIT;
5072
5073 WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH);
5074
5075 while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED))
5076 && timeout--) {
5077 }
5078
5079 if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5080 WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT);
5081
5082 timeout = LONG_WAIT;
5083 while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY)
5084 && timeout--) {
5085 }
5086 }
5087
5088 RD_HARPOON(p_port + hp_int_status); /*Clear command complete */
5089
5090 if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5091 return 1;
5092 }
5093
5094 else {
5095 return 0;
5096 }
5097}
5098
5099/*---------------------------------------------------------------------
5100 *
5101 * Function: Host Data Transfer Abort
5102 *
5103 * Description: Abort any in progress transfer.
5104 *
5105 *---------------------------------------------------------------------*/
5106static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
5107 struct sccb *pCurrSCCB)
5108{
5109
5110 unsigned long timeout;
5111 unsigned long remain_cnt;
5112 u32 sg_ptr;
5113 struct blogic_sg_seg *segp;
5114
5115 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5116
5117 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5118
5119 if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) {
5120
5121 WR_HARPOON(port + hp_bm_ctrl,
5122 (RD_HARPOON(port + hp_bm_ctrl) |
5123 FLUSH_XFER_CNTR));
5124 timeout = LONG_WAIT;
5125
5126 while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5127 && timeout--) {
5128 }
5129
5130 WR_HARPOON(port + hp_bm_ctrl,
5131 (RD_HARPOON(port + hp_bm_ctrl) &
5132 ~FLUSH_XFER_CNTR));
5133
5134 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5135
5136 if (FPT_busMstrTimeOut(port)) {
5137
5138 if (pCurrSCCB->HostStatus == 0x00)
5139
5140 pCurrSCCB->HostStatus =
5141 SCCB_BM_ERR;
5142
5143 }
5144
5145 if (RD_HARPOON(port + hp_int_status) &
5146 INT_EXT_STATUS)
5147
5148 if (RD_HARPOON(port + hp_ext_status) &
5149 BAD_EXT_STATUS)
5150
5151 if (pCurrSCCB->HostStatus ==
5152 0x00)
5153 {
5154 pCurrSCCB->HostStatus =
5155 SCCB_BM_ERR;
5156 }
5157 }
5158 }
5159 }
5160
5161 else if (pCurrSCCB->Sccb_XferCnt) {
5162
5163 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5164
5165 WR_HARPOON(port + hp_page_ctrl,
5166 (RD_HARPOON(port + hp_page_ctrl) &
5167 ~SCATTER_EN));
5168
5169 WR_HARPOON(port + hp_sg_addr, 0x00);
5170
5171 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5172
5173 if (sg_ptr >
5174 (unsigned int)(pCurrSCCB->DataLength /
5175 SG_ELEMENT_SIZE)) {
5176
5177 sg_ptr = (u32)(pCurrSCCB->DataLength /
5178 SG_ELEMENT_SIZE);
5179 }
5180
5181 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5182
5183 while (remain_cnt < 0x01000000L) {
5184
5185 sg_ptr--;
5186 segp = (struct blogic_sg_seg *)(pCurrSCCB->
5187 DataPointer) + (sg_ptr * 2);
5188 if (remain_cnt > (unsigned long)segp->segbytes)
5189 remain_cnt -=
5190 (unsigned long)segp->segbytes;
5191 else
5192 break;
5193 }
5194
5195 if (remain_cnt < 0x01000000L) {
5196
5197 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5198
5199 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5200
5201 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) ==
5202 pCurrSCCB->DataLength && (remain_cnt == 0))
5203
5204 pCurrSCCB->Sccb_XferState |=
5205 F_ALL_XFERRED;
5206 }
5207
5208 else {
5209
5210 if (pCurrSCCB->HostStatus == 0x00) {
5211
5212 pCurrSCCB->HostStatus =
5213 SCCB_GROSS_FW_ERR;
5214 }
5215 }
5216 }
5217
5218 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5219
5220 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5221
5222 FPT_busMstrTimeOut(port);
5223 }
5224
5225 else {
5226
5227 if (RD_HARPOON(port + hp_int_status) &
5228 INT_EXT_STATUS) {
5229
5230 if (RD_HARPOON(port + hp_ext_status) &
5231 BAD_EXT_STATUS) {
5232
5233 if (pCurrSCCB->HostStatus ==
5234 0x00) {
5235
5236 pCurrSCCB->HostStatus =
5237 SCCB_BM_ERR;
5238 }
5239 }
5240 }
5241
5242 }
5243 }
5244
5245 else {
5246
5247 if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) {
5248
5249 timeout = SHORT_WAIT;
5250
5251 while ((RD_HARPOON(port + hp_ext_status) &
5252 BM_CMD_BUSY)
5253 && ((RD_HARPOON(port + hp_fifo_cnt)) >=
5254 BM_THRESHOLD) && timeout--) {
5255 }
5256 }
5257
5258 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5259
5260 WR_HARPOON(port + hp_bm_ctrl,
5261 (RD_HARPOON(port + hp_bm_ctrl) |
5262 FLUSH_XFER_CNTR));
5263
5264 timeout = LONG_WAIT;
5265
5266 while ((RD_HARPOON(port + hp_ext_status) &
5267 BM_CMD_BUSY) && timeout--) {
5268 }
5269
5270 WR_HARPOON(port + hp_bm_ctrl,
5271 (RD_HARPOON(port + hp_bm_ctrl) &
5272 ~FLUSH_XFER_CNTR));
5273
5274 if (RD_HARPOON(port + hp_ext_status) &
5275 BM_CMD_BUSY) {
5276
5277 if (pCurrSCCB->HostStatus == 0x00) {
5278
5279 pCurrSCCB->HostStatus =
5280 SCCB_BM_ERR;
5281 }
5282
5283 FPT_busMstrTimeOut(port);
5284 }
5285 }
5286
5287 if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5288
5289 if (RD_HARPOON(port + hp_ext_status) &
5290 BAD_EXT_STATUS) {
5291
5292 if (pCurrSCCB->HostStatus == 0x00) {
5293
5294 pCurrSCCB->HostStatus =
5295 SCCB_BM_ERR;
5296 }
5297 }
5298 }
5299 }
5300
5301 }
5302
5303 else {
5304
5305 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5306
5307 timeout = LONG_WAIT;
5308
5309 while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5310 && timeout--) {
5311 }
5312
5313 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5314
5315 if (pCurrSCCB->HostStatus == 0x00) {
5316
5317 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5318 }
5319
5320 FPT_busMstrTimeOut(port);
5321 }
5322 }
5323
5324 if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5325
5326 if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) {
5327
5328 if (pCurrSCCB->HostStatus == 0x00) {
5329
5330 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5331 }
5332 }
5333
5334 }
5335
5336 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5337
5338 WR_HARPOON(port + hp_page_ctrl,
5339 (RD_HARPOON(port + hp_page_ctrl) &
5340 ~SCATTER_EN));
5341
5342 WR_HARPOON(port + hp_sg_addr, 0x00);
5343
5344 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5345
5346 pCurrSCCB->Sccb_SGoffset = 0x00;
5347
5348 if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5349 pCurrSCCB->DataLength) {
5350
5351 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5352 pCurrSCCB->Sccb_sgseg =
5353 (unsigned short)(pCurrSCCB->DataLength /
5354 SG_ELEMENT_SIZE);
5355 }
5356 }
5357
5358 else {
5359 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5360 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5361 }
5362 }
5363
5364 WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
5365}
5366
5367/*---------------------------------------------------------------------
5368 *
5369 * Function: Host Data Transfer Restart
5370 *
5371 * Description: Reset the available count due to a restore data
5372 * pointers message.
5373 *
5374 *---------------------------------------------------------------------*/
5375static void FPT_hostDataXferRestart(struct sccb *currSCCB)
5376{
5377 unsigned long data_count;
5378 unsigned int sg_index;
5379 struct blogic_sg_seg *segp;
5380
5381 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5382
5383 currSCCB->Sccb_XferCnt = 0;
5384
5385 sg_index = 0xffff; /*Index by long words into sg list. */
5386 data_count = 0; /*Running count of SG xfer counts. */
5387
5388
5389 while (data_count < currSCCB->Sccb_ATC) {
5390
5391 sg_index++;
5392 segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) +
5393 (sg_index * 2);
5394 data_count += segp->segbytes;
5395 }
5396
5397 if (data_count == currSCCB->Sccb_ATC) {
5398
5399 currSCCB->Sccb_SGoffset = 0;
5400 sg_index++;
5401 }
5402
5403 else {
5404 currSCCB->Sccb_SGoffset =
5405 data_count - currSCCB->Sccb_ATC;
5406 }
5407
5408 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5409 }
5410
5411 else {
5412 currSCCB->Sccb_XferCnt =
5413 currSCCB->DataLength - currSCCB->Sccb_ATC;
5414 }
5415}
5416
5417/*---------------------------------------------------------------------
5418 *
5419 * Function: FPT_scini
5420 *
5421 * Description: Setup all data structures necessary for SCAM selection.
5422 *
5423 *---------------------------------------------------------------------*/
5424
5425static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
5426 unsigned char p_power_up)
5427{
5428
5429 unsigned char loser, assigned_id;
5430 u32 p_port;
5431
5432 unsigned char i, k, ScamFlg;
5433 struct sccb_card *currCard;
5434 struct nvram_info *pCurrNvRam;
5435
5436 currCard = &FPT_BL_Card[p_card];
5437 p_port = currCard->ioPort;
5438 pCurrNvRam = currCard->pNvRamInfo;
5439
5440 if (pCurrNvRam) {
5441 ScamFlg = pCurrNvRam->niScamConf;
5442 i = pCurrNvRam->niSysConf;
5443 } else {
5444 ScamFlg =
5445 (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2);
5446 i = (unsigned
5447 char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2)));
5448 }
5449 if (!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5450 return;
5451
5452 FPT_inisci(p_card, p_port, p_our_id);
5453
5454 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5455 too slow to return to SCAM selection */
5456
5457 /* if (p_power_up)
5458 FPT_Wait1Second(p_port);
5459 else
5460 FPT_Wait(p_port, TO_250ms); */
5461
5462 FPT_Wait1Second(p_port);
5463
5464 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) {
5465 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5466 }
5467
5468 FPT_scsel(p_port);
5469
5470 do {
5471 FPT_scxferc(p_port, SYNC_PTRN);
5472 FPT_scxferc(p_port, DOM_MSTR);
5473 loser =
5474 FPT_scsendi(p_port,
5475 &FPT_scamInfo[p_our_id].id_string[0]);
5476 } while (loser == 0xFF);
5477
5478 FPT_scbusf(p_port);
5479
5480 if ((p_power_up) && (!loser)) {
5481 FPT_sresb(p_port, p_card);
5482 FPT_Wait(p_port, TO_250ms);
5483
5484 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5485 }
5486
5487 FPT_scsel(p_port);
5488
5489 do {
5490 FPT_scxferc(p_port, SYNC_PTRN);
5491 FPT_scxferc(p_port, DOM_MSTR);
5492 loser =
5493 FPT_scsendi(p_port,
5494 &FPT_scamInfo[p_our_id].
5495 id_string[0]);
5496 } while (loser == 0xFF);
5497
5498 FPT_scbusf(p_port);
5499 }
5500 }
5501
5502 else {
5503 loser = 0;
5504 }
5505
5506 if (!loser) {
5507
5508 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5509
5510 if (ScamFlg & SCAM_ENABLED) {
5511
5512 for (i = 0; i < MAX_SCSI_TAR; i++) {
5513 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5514 (FPT_scamInfo[i].state == ID_UNUSED)) {
5515 if (FPT_scsell(p_port, i)) {
5516 FPT_scamInfo[i].state = LEGACY;
5517 if ((FPT_scamInfo[i].
5518 id_string[0] != 0xFF)
5519 || (FPT_scamInfo[i].
5520 id_string[1] != 0xFA)) {
5521
5522 FPT_scamInfo[i].
5523 id_string[0] = 0xFF;
5524 FPT_scamInfo[i].
5525 id_string[1] = 0xFA;
5526 if (pCurrNvRam == NULL)
5527 currCard->
5528 globalFlags
5529 |=
5530 F_UPDATE_EEPROM;
5531 }
5532 }
5533 }
5534 }
5535
5536 FPT_sresb(p_port, p_card);
5537 FPT_Wait1Second(p_port);
5538 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5539 }
5540 FPT_scsel(p_port);
5541 FPT_scasid(p_card, p_port);
5542 }
5543
5544 }
5545
5546 else if ((loser) && (ScamFlg & SCAM_ENABLED)) {
5547 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5548 assigned_id = 0;
5549 FPT_scwtsel(p_port);
5550
5551 do {
5552 while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) {
5553 }
5554
5555 i = FPT_scxferc(p_port, 0x00);
5556 if (i == ASSIGN_ID) {
5557 if (!
5558 (FPT_scsendi
5559 (p_port,
5560 &FPT_scamInfo[p_our_id].id_string[0]))) {
5561 i = FPT_scxferc(p_port, 0x00);
5562 if (FPT_scvalq(i)) {
5563 k = FPT_scxferc(p_port, 0x00);
5564
5565 if (FPT_scvalq(k)) {
5566 currCard->ourId =
5567 ((unsigned char)(i
5568 <<
5569 3)
5570 +
5571 (k &
5572 (unsigned char)7))
5573 & (unsigned char)
5574 0x3F;
5575 FPT_inisci(p_card,
5576 p_port,
5577 p_our_id);
5578 FPT_scamInfo[currCard->
5579 ourId].
5580 state = ID_ASSIGNED;
5581 FPT_scamInfo[currCard->
5582 ourId].
5583 id_string[0]
5584 = SLV_TYPE_CODE0;
5585 assigned_id = 1;
5586 }
5587 }
5588 }
5589 }
5590
5591 else if (i == SET_P_FLAG) {
5592 if (!(FPT_scsendi(p_port,
5593 &FPT_scamInfo[p_our_id].
5594 id_string[0])))
5595 FPT_scamInfo[p_our_id].id_string[0] |=
5596 0x80;
5597 }
5598 } while (!assigned_id);
5599
5600 while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) {
5601 }
5602 }
5603
5604 if (ScamFlg & SCAM_ENABLED) {
5605 FPT_scbusf(p_port);
5606 if (currCard->globalFlags & F_UPDATE_EEPROM) {
5607 FPT_scsavdi(p_card, p_port);
5608 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5609 }
5610 }
5611
5612/*
5613 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5614 {
5615 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5616 (FPT_scamInfo[i].state == LEGACY))
5617 k++;
5618 }
5619
5620 if (k==2)
5621 currCard->globalFlags |= F_SINGLE_DEVICE;
5622 else
5623 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5624*/
5625}
5626
5627/*---------------------------------------------------------------------
5628 *
5629 * Function: FPT_scarb
5630 *
5631 * Description: Gain control of the bus and wait SCAM select time (250ms)
5632 *
5633 *---------------------------------------------------------------------*/
5634
5635static int FPT_scarb(u32 p_port, unsigned char p_sel_type)
5636{
5637 if (p_sel_type == INIT_SELTD) {
5638
5639 while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {
5640 }
5641
5642 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL)
5643 return 0;
5644
5645 if (RD_HARPOON(p_port + hp_scsidata_0) != 00)
5646 return 0;
5647
5648 WR_HARPOON(p_port + hp_scsisig,
5649 (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY));
5650
5651 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) {
5652
5653 WR_HARPOON(p_port + hp_scsisig,
5654 (RD_HARPOON(p_port + hp_scsisig) &
5655 ~SCSI_BSY));
5656 return 0;
5657 }
5658
5659 WR_HARPOON(p_port + hp_scsisig,
5660 (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL));
5661
5662 if (RD_HARPOON(p_port + hp_scsidata_0) != 00) {
5663
5664 WR_HARPOON(p_port + hp_scsisig,
5665 (RD_HARPOON(p_port + hp_scsisig) &
5666 ~(SCSI_BSY | SCSI_SEL)));
5667 return 0;
5668 }
5669 }
5670
5671 WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5672 & ~ACTdeassert));
5673 WR_HARPOON(p_port + hp_scsireset, SCAM_EN);
5674 WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5675 WR_HARPOON(p_port + hp_scsidata_1, 0x00);
5676 WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN);
5677
5678 WR_HARPOON(p_port + hp_scsisig,
5679 (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG));
5680
5681 WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig)
5682 & ~SCSI_BSY));
5683
5684 FPT_Wait(p_port, TO_250ms);
5685
5686 return 1;
5687}
5688
5689/*---------------------------------------------------------------------
5690 *
5691 * Function: FPT_scbusf
5692 *
5693 * Description: Release the SCSI bus and disable SCAM selection.
5694 *
5695 *---------------------------------------------------------------------*/
5696
5697static void FPT_scbusf(u32 p_port)
5698{
5699 WR_HARPOON(p_port + hp_page_ctrl,
5700 (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
5701
5702 WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5703
5704 WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0)
5705 & ~SCSI_BUS_EN));
5706
5707 WR_HARPOON(p_port + hp_scsisig, 0x00);
5708
5709 WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset)
5710 & ~SCAM_EN));
5711
5712 WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5713 | ACTdeassert));
5714
5715 WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5716
5717 WR_HARPOON(p_port + hp_page_ctrl,
5718 (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE));
5719}
5720
5721/*---------------------------------------------------------------------
5722 *
5723 * Function: FPT_scasid
5724 *
5725 * Description: Assign an ID to all the SCAM devices.
5726 *
5727 *---------------------------------------------------------------------*/
5728
5729static void FPT_scasid(unsigned char p_card, u32 p_port)
5730{
5731 unsigned char temp_id_string[ID_STRING_LENGTH];
5732
5733 unsigned char i, k, scam_id;
5734 unsigned char crcBytes[3];
5735 struct nvram_info *pCurrNvRam;
5736 unsigned short *pCrcBytes;
5737
5738 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
5739
5740 i = 0;
5741
5742 while (!i) {
5743
5744 for (k = 0; k < ID_STRING_LENGTH; k++) {
5745 temp_id_string[k] = (unsigned char)0x00;
5746 }
5747
5748 FPT_scxferc(p_port, SYNC_PTRN);
5749 FPT_scxferc(p_port, ASSIGN_ID);
5750
5751 if (!(FPT_sciso(p_port, &temp_id_string[0]))) {
5752 if (pCurrNvRam) {
5753 pCrcBytes = (unsigned short *)&crcBytes[0];
5754 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
5755 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
5756 temp_id_string[1] = crcBytes[2];
5757 temp_id_string[2] = crcBytes[0];
5758 temp_id_string[3] = crcBytes[1];
5759 for (k = 4; k < ID_STRING_LENGTH; k++)
5760 temp_id_string[k] = (unsigned char)0x00;
5761 }
5762 i = FPT_scmachid(p_card, temp_id_string);
5763
5764 if (i == CLR_PRIORITY) {
5765 FPT_scxferc(p_port, MISC_CODE);
5766 FPT_scxferc(p_port, CLR_P_FLAG);
5767 i = 0; /*Not the last ID yet. */
5768 }
5769
5770 else if (i != NO_ID_AVAIL) {
5771 if (i < 8)
5772 FPT_scxferc(p_port, ID_0_7);
5773 else
5774 FPT_scxferc(p_port, ID_8_F);
5775
5776 scam_id = (i & (unsigned char)0x07);
5777
5778 for (k = 1; k < 0x08; k <<= 1)
5779 if (!(k & i))
5780 scam_id += 0x08; /*Count number of zeros in DB0-3. */
5781
5782 FPT_scxferc(p_port, scam_id);
5783
5784 i = 0; /*Not the last ID yet. */
5785 }
5786 }
5787
5788 else {
5789 i = 1;
5790 }
5791
5792 } /*End while */
5793
5794 FPT_scxferc(p_port, SYNC_PTRN);
5795 FPT_scxferc(p_port, CFG_CMPLT);
5796}
5797
5798/*---------------------------------------------------------------------
5799 *
5800 * Function: FPT_scsel
5801 *
5802 * Description: Select all the SCAM devices.
5803 *
5804 *---------------------------------------------------------------------*/
5805
5806static void FPT_scsel(u32 p_port)
5807{
5808
5809 WR_HARPOON(p_port + hp_scsisig, SCSI_SEL);
5810 FPT_scwiros(p_port, SCSI_MSG);
5811
5812 WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY));
5813
5814 WR_HARPOON(p_port + hp_scsisig,
5815 (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5816 WR_HARPOON(p_port + hp_scsidata_0,
5817 (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) |
5818 (unsigned char)(BIT(7) + BIT(6))));
5819
5820 WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5821 FPT_scwiros(p_port, SCSI_SEL);
5822
5823 WR_HARPOON(p_port + hp_scsidata_0,
5824 (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) &
5825 ~(unsigned char)BIT(6)));
5826 FPT_scwirod(p_port, BIT(6));
5827
5828 WR_HARPOON(p_port + hp_scsisig,
5829 (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5830}
5831
5832/*---------------------------------------------------------------------
5833 *
5834 * Function: FPT_scxferc
5835 *
5836 * Description: Handshake the p_data (DB4-0) across the bus.
5837 *
5838 *---------------------------------------------------------------------*/
5839
5840static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data)
5841{
5842 unsigned char curr_data, ret_data;
5843
5844 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
5845
5846 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5847
5848 curr_data &= ~BIT(7);
5849
5850 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5851
5852 FPT_scwirod(p_port, BIT(7)); /*Wait for DB7 to be released. */
5853 while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ;
5854
5855 ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F);
5856
5857 curr_data |= BIT(6);
5858
5859 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5860
5861 curr_data &= ~BIT(5);
5862
5863 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5864
5865 FPT_scwirod(p_port, BIT(5)); /*Wait for DB5 to be released. */
5866
5867 curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */
5868 curr_data |= BIT(7);
5869
5870 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5871
5872 curr_data &= ~BIT(6);
5873
5874 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5875
5876 FPT_scwirod(p_port, BIT(6)); /*Wait for DB6 to be released. */
5877
5878 return ret_data;
5879}
5880
5881/*---------------------------------------------------------------------
5882 *
5883 * Function: FPT_scsendi
5884 *
5885 * Description: Transfer our Identification string to determine if we
5886 * will be the dominant master.
5887 *
5888 *---------------------------------------------------------------------*/
5889
5890static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[])
5891{
5892 unsigned char ret_data, byte_cnt, bit_cnt, defer;
5893
5894 defer = 0;
5895
5896 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5897
5898 for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) {
5899
5900 if (defer)
5901 ret_data = FPT_scxferc(p_port, 00);
5902
5903 else if (p_id_string[byte_cnt] & bit_cnt)
5904
5905 ret_data = FPT_scxferc(p_port, 02);
5906
5907 else {
5908
5909 ret_data = FPT_scxferc(p_port, 01);
5910 if (ret_data & 02)
5911 defer = 1;
5912 }
5913
5914 if ((ret_data & 0x1C) == 0x10)
5915 return 0x00; /*End of isolation stage, we won! */
5916
5917 if (ret_data & 0x1C)
5918 return 0xFF;
5919
5920 if ((defer) && (!(ret_data & 0x1F)))
5921 return 0x01; /*End of isolation stage, we lost. */
5922
5923 } /*bit loop */
5924
5925 } /*byte loop */
5926
5927 if (defer)
5928 return 0x01; /*We lost */
5929 else
5930 return 0; /*We WON! Yeeessss! */
5931}
5932
5933/*---------------------------------------------------------------------
5934 *
5935 * Function: FPT_sciso
5936 *
5937 * Description: Transfer the Identification string.
5938 *
5939 *---------------------------------------------------------------------*/
5940
5941static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[])
5942{
5943 unsigned char ret_data, the_data, byte_cnt, bit_cnt;
5944
5945 the_data = 0;
5946
5947 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5948
5949 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
5950
5951 ret_data = FPT_scxferc(p_port, 0);
5952
5953 if (ret_data & 0xFC)
5954 return 0xFF;
5955
5956 else {
5957
5958 the_data <<= 1;
5959 if (ret_data & BIT(1)) {
5960 the_data |= 1;
5961 }
5962 }
5963
5964 if ((ret_data & 0x1F) == 0) {
5965/*
5966 if(bit_cnt != 0 || bit_cnt != 8)
5967 {
5968 byte_cnt = 0;
5969 bit_cnt = 0;
5970 FPT_scxferc(p_port, SYNC_PTRN);
5971 FPT_scxferc(p_port, ASSIGN_ID);
5972 continue;
5973 }
5974*/
5975 if (byte_cnt)
5976 return 0x00;
5977 else
5978 return 0xFF;
5979 }
5980
5981 } /*bit loop */
5982
5983 p_id_string[byte_cnt] = the_data;
5984
5985 } /*byte loop */
5986
5987 return 0;
5988}
5989
5990/*---------------------------------------------------------------------
5991 *
5992 * Function: FPT_scwirod
5993 *
5994 * Description: Sample the SCSI data bus making sure the signal has been
5995 * deasserted for the correct number of consecutive samples.
5996 *
5997 *---------------------------------------------------------------------*/
5998
5999static void FPT_scwirod(u32 p_port, unsigned char p_data_bit)
6000{
6001 unsigned char i;
6002
6003 i = 0;
6004 while (i < MAX_SCSI_TAR) {
6005
6006 if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit)
6007
6008 i = 0;
6009
6010 else
6011
6012 i++;
6013
6014 }
6015}
6016
6017/*---------------------------------------------------------------------
6018 *
6019 * Function: FPT_scwiros
6020 *
6021 * Description: Sample the SCSI Signal lines making sure the signal has been
6022 * deasserted for the correct number of consecutive samples.
6023 *
6024 *---------------------------------------------------------------------*/
6025
6026static void FPT_scwiros(u32 p_port, unsigned char p_data_bit)
6027{
6028 unsigned char i;
6029
6030 i = 0;
6031 while (i < MAX_SCSI_TAR) {
6032
6033 if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit)
6034
6035 i = 0;
6036
6037 else
6038
6039 i++;
6040
6041 }
6042}
6043
6044/*---------------------------------------------------------------------
6045 *
6046 * Function: FPT_scvalq
6047 *
6048 * Description: Make sure we received a valid data byte.
6049 *
6050 *---------------------------------------------------------------------*/
6051
6052static unsigned char FPT_scvalq(unsigned char p_quintet)
6053{
6054 unsigned char count;
6055
6056 for (count = 1; count < 0x08; count <<= 1) {
6057 if (!(p_quintet & count))
6058 p_quintet -= 0x80;
6059 }
6060
6061 if (p_quintet & 0x18)
6062 return 0;
6063
6064 else
6065 return 1;
6066}
6067
6068/*---------------------------------------------------------------------
6069 *
6070 * Function: FPT_scsell
6071 *
6072 * Description: Select the specified device ID using a selection timeout
6073 * less than 4ms. If somebody responds then it is a legacy
6074 * drive and this ID must be marked as such.
6075 *
6076 *---------------------------------------------------------------------*/
6077
6078static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id)
6079{
6080 unsigned long i;
6081
6082 WR_HARPOON(p_port + hp_page_ctrl,
6083 (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
6084
6085 ARAM_ACCESS(p_port);
6086
6087 WR_HARPOON(p_port + hp_addstat,
6088 (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER));
6089 WR_HARPOON(p_port + hp_seltimeout, TO_4ms);
6090
6091 for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) {
6092 WRW_HARPOON(i, (MPM_OP + ACOMMAND));
6093 }
6094 WRW_HARPOON(i, (BRH_OP + ALWAYS + NP));
6095
6096 WRW_HARPOON((p_port + hp_intstat),
6097 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6098
6099 WR_HARPOON(p_port + hp_select_id, targ_id);
6100
6101 WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT);
6102 WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6103 WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6104
6105 while (!(RDW_HARPOON((p_port + hp_intstat)) &
6106 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {
6107 }
6108
6109 if (RDW_HARPOON((p_port + hp_intstat)) & RESET)
6110 FPT_Wait(p_port, TO_250ms);
6111
6112 DISABLE_AUTO(p_port);
6113
6114 WR_HARPOON(p_port + hp_addstat,
6115 (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER));
6116 WR_HARPOON(p_port + hp_seltimeout, TO_290ms);
6117
6118 SGRAM_ACCESS(p_port);
6119
6120 if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) {
6121
6122 WRW_HARPOON((p_port + hp_intstat),
6123 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6124
6125 WR_HARPOON(p_port + hp_page_ctrl,
6126 (RD_HARPOON(p_port + hp_page_ctrl) &
6127 ~G_INT_DISABLE));
6128
6129 return 0; /*No legacy device */
6130 }
6131
6132 else {
6133
6134 while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) {
6135 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) {
6136 WR_HARPOON(p_port + hp_scsisig,
6137 (SCSI_ACK + S_ILL_PH));
6138 ACCEPT_MSG(p_port);
6139 }
6140 }
6141
6142 WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1);
6143
6144 WR_HARPOON(p_port + hp_page_ctrl,
6145 (RD_HARPOON(p_port + hp_page_ctrl) &
6146 ~G_INT_DISABLE));
6147
6148 return 1; /*Found one of them oldies! */
6149 }
6150}
6151
6152/*---------------------------------------------------------------------
6153 *
6154 * Function: FPT_scwtsel
6155 *
6156 * Description: Wait to be selected by another SCAM initiator.
6157 *
6158 *---------------------------------------------------------------------*/
6159
6160static void FPT_scwtsel(u32 p_port)
6161{
6162 while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) {
6163 }
6164}
6165
6166/*---------------------------------------------------------------------
6167 *
6168 * Function: FPT_inisci
6169 *
6170 * Description: Setup the data Structure with the info from the EEPROM.
6171 *
6172 *---------------------------------------------------------------------*/
6173
6174static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id)
6175{
6176 unsigned char i, k, max_id;
6177 unsigned short ee_data;
6178 struct nvram_info *pCurrNvRam;
6179
6180 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6181
6182 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6183 max_id = 0x08;
6184
6185 else
6186 max_id = 0x10;
6187
6188 if (pCurrNvRam) {
6189 for (i = 0; i < max_id; i++) {
6190
6191 for (k = 0; k < 4; k++)
6192 FPT_scamInfo[i].id_string[k] =
6193 pCurrNvRam->niScamTbl[i][k];
6194 for (k = 4; k < ID_STRING_LENGTH; k++)
6195 FPT_scamInfo[i].id_string[k] =
6196 (unsigned char)0x00;
6197
6198 if (FPT_scamInfo[i].id_string[0] == 0x00)
6199 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6200 else
6201 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6202
6203 }
6204 } else {
6205 for (i = 0; i < max_id; i++) {
6206 for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6207 ee_data =
6208 FPT_utilEERead(p_port,
6209 (unsigned
6210 short)((EE_SCAMBASE / 2) +
6211 (unsigned short)(i *
6212 ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6213 FPT_scamInfo[i].id_string[k] =
6214 (unsigned char)ee_data;
6215 ee_data >>= 8;
6216 FPT_scamInfo[i].id_string[k + 1] =
6217 (unsigned char)ee_data;
6218 }
6219
6220 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6221 (FPT_scamInfo[i].id_string[0] == 0xFF))
6222
6223 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6224
6225 else
6226 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6227
6228 }
6229 }
6230 for (k = 0; k < ID_STRING_LENGTH; k++)
6231 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6232
6233}
6234
6235/*---------------------------------------------------------------------
6236 *
6237 * Function: FPT_scmachid
6238 *
6239 * Description: Match the Device ID string with our values stored in
6240 * the EEPROM.
6241 *
6242 *---------------------------------------------------------------------*/
6243
6244static unsigned char FPT_scmachid(unsigned char p_card,
6245 unsigned char p_id_string[])
6246{
6247
6248 unsigned char i, k, match;
6249
6250 for (i = 0; i < MAX_SCSI_TAR; i++) {
6251
6252 match = 1;
6253
6254 for (k = 0; k < ID_STRING_LENGTH; k++) {
6255 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6256 match = 0;
6257 }
6258
6259 if (match) {
6260 FPT_scamInfo[i].state = ID_ASSIGNED;
6261 return i;
6262 }
6263
6264 }
6265
6266 if (p_id_string[0] & BIT(5))
6267 i = 8;
6268 else
6269 i = MAX_SCSI_TAR;
6270
6271 if (((p_id_string[0] & 0x06) == 0x02)
6272 || ((p_id_string[0] & 0x06) == 0x04))
6273 match = p_id_string[1] & (unsigned char)0x1F;
6274 else
6275 match = 7;
6276
6277 while (i > 0) {
6278 i--;
6279
6280 if (FPT_scamInfo[match].state == ID_UNUSED) {
6281 for (k = 0; k < ID_STRING_LENGTH; k++) {
6282 FPT_scamInfo[match].id_string[k] =
6283 p_id_string[k];
6284 }
6285
6286 FPT_scamInfo[match].state = ID_ASSIGNED;
6287
6288 if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6289 FPT_BL_Card[p_card].globalFlags |=
6290 F_UPDATE_EEPROM;
6291 return match;
6292
6293 }
6294
6295 match--;
6296
6297 if (match == 0xFF) {
6298 if (p_id_string[0] & BIT(5))
6299 match = 7;
6300 else
6301 match = MAX_SCSI_TAR - 1;
6302 }
6303 }
6304
6305 if (p_id_string[0] & BIT(7)) {
6306 return CLR_PRIORITY;
6307 }
6308
6309 if (p_id_string[0] & BIT(5))
6310 i = 8;
6311 else
6312 i = MAX_SCSI_TAR;
6313
6314 if (((p_id_string[0] & 0x06) == 0x02)
6315 || ((p_id_string[0] & 0x06) == 0x04))
6316 match = p_id_string[1] & (unsigned char)0x1F;
6317 else
6318 match = 7;
6319
6320 while (i > 0) {
6321
6322 i--;
6323
6324 if (FPT_scamInfo[match].state == ID_UNASSIGNED) {
6325 for (k = 0; k < ID_STRING_LENGTH; k++) {
6326 FPT_scamInfo[match].id_string[k] =
6327 p_id_string[k];
6328 }
6329
6330 FPT_scamInfo[match].id_string[0] |= BIT(7);
6331 FPT_scamInfo[match].state = ID_ASSIGNED;
6332 if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6333 FPT_BL_Card[p_card].globalFlags |=
6334 F_UPDATE_EEPROM;
6335 return match;
6336
6337 }
6338
6339 match--;
6340
6341 if (match == 0xFF) {
6342 if (p_id_string[0] & BIT(5))
6343 match = 7;
6344 else
6345 match = MAX_SCSI_TAR - 1;
6346 }
6347 }
6348
6349 return NO_ID_AVAIL;
6350}
6351
6352/*---------------------------------------------------------------------
6353 *
6354 * Function: FPT_scsavdi
6355 *
6356 * Description: Save off the device SCAM ID strings.
6357 *
6358 *---------------------------------------------------------------------*/
6359
6360static void FPT_scsavdi(unsigned char p_card, u32 p_port)
6361{
6362 unsigned char i, k, max_id;
6363 unsigned short ee_data, sum_data;
6364
6365 sum_data = 0x0000;
6366
6367 for (i = 1; i < EE_SCAMBASE / 2; i++) {
6368 sum_data += FPT_utilEERead(p_port, i);
6369 }
6370
6371 FPT_utilEEWriteOnOff(p_port, 1); /* Enable write access to the EEPROM */
6372
6373 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6374 max_id = 0x08;
6375
6376 else
6377 max_id = 0x10;
6378
6379 for (i = 0; i < max_id; i++) {
6380
6381 for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6382 ee_data = FPT_scamInfo[i].id_string[k + 1];
6383 ee_data <<= 8;
6384 ee_data |= FPT_scamInfo[i].id_string[k];
6385 sum_data += ee_data;
6386 FPT_utilEEWrite(p_port, ee_data,
6387 (unsigned short)((EE_SCAMBASE / 2) +
6388 (unsigned short)(i *
6389 ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6390 }
6391 }
6392
6393 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2);
6394 FPT_utilEEWriteOnOff(p_port, 0); /* Turn off write access */
6395}
6396
6397/*---------------------------------------------------------------------
6398 *
6399 * Function: FPT_XbowInit
6400 *
6401 * Description: Setup the Xbow for normal operation.
6402 *
6403 *---------------------------------------------------------------------*/
6404
6405static void FPT_XbowInit(u32 port, unsigned char ScamFlg)
6406{
6407 unsigned char i;
6408
6409 i = RD_HARPOON(port + hp_page_ctrl);
6410 WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE));
6411
6412 WR_HARPOON(port + hp_scsireset, 0x00);
6413 WR_HARPOON(port + hp_portctrl_1, HOST_MODE8);
6414
6415 WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET |
6416 FIFO_CLR));
6417
6418 WR_HARPOON(port + hp_scsireset, SCSI_INI);
6419
6420 WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT);
6421
6422 WR_HARPOON(port + hp_scsisig, 0x00); /* Clear any signals we might */
6423 WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
6424
6425 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
6426
6427 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6428 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6429
6430 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6431 FPT_default_intena |= SCAM_SEL;
6432
6433 WRW_HARPOON((port + hp_intena), FPT_default_intena);
6434
6435 WR_HARPOON(port + hp_seltimeout, TO_290ms);
6436
6437 /* Turn on SCSI_MODE8 for narrow cards to fix the
6438 strapping issue with the DUAL CHANNEL card */
6439 if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD)
6440 WR_HARPOON(port + hp_addstat, SCSI_MODE8);
6441
6442 WR_HARPOON(port + hp_page_ctrl, i);
6443
6444}
6445
6446/*---------------------------------------------------------------------
6447 *
6448 * Function: FPT_BusMasterInit
6449 *
6450 * Description: Initialize the BusMaster for normal operations.
6451 *
6452 *---------------------------------------------------------------------*/
6453
6454static void FPT_BusMasterInit(u32 p_port)
6455{
6456
6457 WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST);
6458 WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
6459
6460 WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64);
6461
6462 WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT));
6463
6464 WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H));
6465
6466 RD_HARPOON(p_port + hp_int_status); /*Clear interrupts. */
6467 WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6468 WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) &
6469 ~SCATTER_EN));
6470}
6471
6472/*---------------------------------------------------------------------
6473 *
6474 * Function: FPT_DiagEEPROM
6475 *
6476 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6477 * necessary.
6478 *
6479 *---------------------------------------------------------------------*/
6480
6481static void FPT_DiagEEPROM(u32 p_port)
6482{
6483 unsigned short index, temp, max_wd_cnt;
6484
6485 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6486 max_wd_cnt = EEPROM_WD_CNT;
6487 else
6488 max_wd_cnt = EEPROM_WD_CNT * 2;
6489
6490 temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2);
6491
6492 if (temp == 0x4641) {
6493
6494 for (index = 2; index < max_wd_cnt; index++) {
6495
6496 temp += FPT_utilEERead(p_port, index);
6497
6498 }
6499
6500 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) {
6501
6502 return; /*EEPROM is Okay so return now! */
6503 }
6504 }
6505
6506 FPT_utilEEWriteOnOff(p_port, (unsigned char)1);
6507
6508 for (index = 0; index < max_wd_cnt; index++) {
6509
6510 FPT_utilEEWrite(p_port, 0x0000, index);
6511 }
6512
6513 temp = 0;
6514
6515 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2);
6516 temp += 0x4641;
6517 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2);
6518 temp += 0x3920;
6519 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2);
6520 temp += 0x3033;
6521 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2);
6522 temp += 0x2020;
6523 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2);
6524 temp += 0x70D3;
6525 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2);
6526 temp += 0x0010;
6527 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2);
6528 temp += 0x0003;
6529 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2);
6530 temp += 0x0007;
6531
6532 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2);
6533 temp += 0x0000;
6534 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2);
6535 temp += 0x0000;
6536 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2);
6537 temp += 0x0000;
6538
6539 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2);
6540 temp += 0x4242;
6541 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2);
6542 temp += 0x4242;
6543 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2);
6544 temp += 0x4242;
6545 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2);
6546 temp += 0x4242;
6547 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2);
6548 temp += 0x4242;
6549 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2);
6550 temp += 0x4242;
6551 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2);
6552 temp += 0x4242;
6553 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2);
6554 temp += 0x4242;
6555
6556 FPT_utilEEWrite(p_port, 0x6C46, 64 / 2); /*PRODUCT ID */
6557 temp += 0x6C46;
6558 FPT_utilEEWrite(p_port, 0x7361, 66 / 2); /* FlashPoint LT */
6559 temp += 0x7361;
6560 FPT_utilEEWrite(p_port, 0x5068, 68 / 2);
6561 temp += 0x5068;
6562 FPT_utilEEWrite(p_port, 0x696F, 70 / 2);
6563 temp += 0x696F;
6564 FPT_utilEEWrite(p_port, 0x746E, 72 / 2);
6565 temp += 0x746E;
6566 FPT_utilEEWrite(p_port, 0x4C20, 74 / 2);
6567 temp += 0x4C20;
6568 FPT_utilEEWrite(p_port, 0x2054, 76 / 2);
6569 temp += 0x2054;
6570 FPT_utilEEWrite(p_port, 0x2020, 78 / 2);
6571 temp += 0x2020;
6572
6573 index = ((EE_SCAMBASE / 2) + (7 * 16));
6574 FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index);
6575 temp += (0x0700 + TYPE_CODE0);
6576 index++;
6577 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6578 temp += 0x5542; /* BUSLOGIC */
6579 index++;
6580 FPT_utilEEWrite(p_port, 0x4C53, index);
6581 temp += 0x4C53;
6582 index++;
6583 FPT_utilEEWrite(p_port, 0x474F, index);
6584 temp += 0x474F;
6585 index++;
6586 FPT_utilEEWrite(p_port, 0x4349, index);
6587 temp += 0x4349;
6588 index++;
6589 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6590 temp += 0x5442; /* BT- 930 */
6591 index++;
6592 FPT_utilEEWrite(p_port, 0x202D, index);
6593 temp += 0x202D;
6594 index++;
6595 FPT_utilEEWrite(p_port, 0x3339, index);
6596 temp += 0x3339;
6597 index++; /*Serial # */
6598 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6599 temp += 0x2030;
6600 index++;
6601 FPT_utilEEWrite(p_port, 0x5453, index);
6602 temp += 0x5453;
6603 index++;
6604 FPT_utilEEWrite(p_port, 0x5645, index);
6605 temp += 0x5645;
6606 index++;
6607 FPT_utilEEWrite(p_port, 0x2045, index);
6608 temp += 0x2045;
6609 index++;
6610 FPT_utilEEWrite(p_port, 0x202F, index);
6611 temp += 0x202F;
6612 index++;
6613 FPT_utilEEWrite(p_port, 0x4F4A, index);
6614 temp += 0x4F4A;
6615 index++;
6616 FPT_utilEEWrite(p_port, 0x204E, index);
6617 temp += 0x204E;
6618 index++;
6619 FPT_utilEEWrite(p_port, 0x3539, index);
6620 temp += 0x3539;
6621
6622 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2);
6623
6624 FPT_utilEEWriteOnOff(p_port, (unsigned char)0);
6625
6626}
6627
6628/*---------------------------------------------------------------------
6629 *
6630 * Function: Queue Search Select
6631 *
6632 * Description: Try to find a new command to execute.
6633 *
6634 *---------------------------------------------------------------------*/
6635
6636static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
6637 unsigned char p_card)
6638{
6639 unsigned char scan_ptr, lun;
6640 struct sccb_mgr_tar_info *currTar_Info;
6641 struct sccb *pOldSccb;
6642
6643 scan_ptr = pCurrCard->scanIndex;
6644 do {
6645 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6646 if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
6647 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6648 TAG_Q_TRYING)) {
6649 if (currTar_Info->TarSelQ_Cnt != 0) {
6650
6651 scan_ptr++;
6652 if (scan_ptr == MAX_SCSI_TAR)
6653 scan_ptr = 0;
6654
6655 for (lun = 0; lun < MAX_LUN; lun++) {
6656 if (currTar_Info->TarLUNBusy[lun] == 0) {
6657
6658 pCurrCard->currentSCCB =
6659 currTar_Info->TarSelQ_Head;
6660 pOldSccb = NULL;
6661
6662 while ((pCurrCard->
6663 currentSCCB != NULL)
6664 && (lun !=
6665 pCurrCard->
6666 currentSCCB->Lun)) {
6667 pOldSccb =
6668 pCurrCard->
6669 currentSCCB;
6670 pCurrCard->currentSCCB =
6671 (struct sccb
6672 *)(pCurrCard->
6673 currentSCCB)->
6674 Sccb_forwardlink;
6675 }
6676 if (pCurrCard->currentSCCB ==
6677 NULL)
6678 continue;
6679 if (pOldSccb != NULL) {
6680 pOldSccb->
6681 Sccb_forwardlink =
6682 (struct sccb
6683 *)(pCurrCard->
6684 currentSCCB)->
6685 Sccb_forwardlink;
6686 pOldSccb->
6687 Sccb_backlink =
6688 (struct sccb
6689 *)(pCurrCard->
6690 currentSCCB)->
6691 Sccb_backlink;
6692 currTar_Info->
6693 TarSelQ_Cnt--;
6694 } else {
6695 currTar_Info->
6696 TarSelQ_Head =
6697 (struct sccb
6698 *)(pCurrCard->
6699 currentSCCB)->
6700 Sccb_forwardlink;
6701
6702 if (currTar_Info->
6703 TarSelQ_Head ==
6704 NULL) {
6705 currTar_Info->
6706 TarSelQ_Tail
6707 = NULL;
6708 currTar_Info->
6709 TarSelQ_Cnt
6710 = 0;
6711 } else {
6712 currTar_Info->
6713 TarSelQ_Cnt--;
6714 currTar_Info->
6715 TarSelQ_Head->
6716 Sccb_backlink
6717 =
6718 (struct sccb
6719 *)NULL;
6720 }
6721 }
6722 pCurrCard->scanIndex = scan_ptr;
6723
6724 pCurrCard->globalFlags |=
6725 F_NEW_SCCB_CMD;
6726
6727 break;
6728 }
6729 }
6730 }
6731
6732 else {
6733 scan_ptr++;
6734 if (scan_ptr == MAX_SCSI_TAR) {
6735 scan_ptr = 0;
6736 }
6737 }
6738
6739 } else {
6740 if ((currTar_Info->TarSelQ_Cnt != 0) &&
6741 (currTar_Info->TarLUNBusy[0] == 0)) {
6742
6743 pCurrCard->currentSCCB =
6744 currTar_Info->TarSelQ_Head;
6745
6746 currTar_Info->TarSelQ_Head =
6747 (struct sccb *)(pCurrCard->currentSCCB)->
6748 Sccb_forwardlink;
6749
6750 if (currTar_Info->TarSelQ_Head == NULL) {
6751 currTar_Info->TarSelQ_Tail = NULL;
6752 currTar_Info->TarSelQ_Cnt = 0;
6753 } else {
6754 currTar_Info->TarSelQ_Cnt--;
6755 currTar_Info->TarSelQ_Head->
6756 Sccb_backlink = (struct sccb *)NULL;
6757 }
6758
6759 scan_ptr++;
6760 if (scan_ptr == MAX_SCSI_TAR)
6761 scan_ptr = 0;
6762
6763 pCurrCard->scanIndex = scan_ptr;
6764
6765 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6766
6767 break;
6768 }
6769
6770 else {
6771 scan_ptr++;
6772 if (scan_ptr == MAX_SCSI_TAR) {
6773 scan_ptr = 0;
6774 }
6775 }
6776 }
6777 } while (scan_ptr != pCurrCard->scanIndex);
6778}
6779
6780/*---------------------------------------------------------------------
6781 *
6782 * Function: Queue Select Fail
6783 *
6784 * Description: Add the current SCCB to the head of the Queue.
6785 *
6786 *---------------------------------------------------------------------*/
6787
6788static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
6789 unsigned char p_card)
6790{
6791 unsigned char thisTarg;
6792 struct sccb_mgr_tar_info *currTar_Info;
6793
6794 if (pCurrCard->currentSCCB != NULL) {
6795 thisTarg =
6796 (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->
6797 TargID);
6798 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6799
6800 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
6801
6802 pCurrCard->currentSCCB->Sccb_forwardlink =
6803 currTar_Info->TarSelQ_Head;
6804
6805 if (currTar_Info->TarSelQ_Cnt == 0) {
6806 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
6807 }
6808
6809 else {
6810 currTar_Info->TarSelQ_Head->Sccb_backlink =
6811 pCurrCard->currentSCCB;
6812 }
6813
6814 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
6815
6816 pCurrCard->currentSCCB = NULL;
6817 currTar_Info->TarSelQ_Cnt++;
6818 }
6819}
6820
6821/*---------------------------------------------------------------------
6822 *
6823 * Function: Queue Command Complete
6824 *
6825 * Description: Call the callback function with the current SCCB.
6826 *
6827 *---------------------------------------------------------------------*/
6828
6829static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
6830 struct sccb *p_sccb, unsigned char p_card)
6831{
6832
6833 unsigned char i, SCSIcmd;
6834 CALL_BK_FN callback;
6835 struct sccb_mgr_tar_info *currTar_Info;
6836
6837 SCSIcmd = p_sccb->Cdb[0];
6838
6839 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
6840
6841 if ((p_sccb->
6842 ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN))
6843 && (p_sccb->HostStatus == SCCB_COMPLETE)
6844 && (p_sccb->TargetStatus != SAM_STAT_CHECK_CONDITION))
6845
6846 if ((SCSIcmd == READ_6) ||
6847 (SCSIcmd == WRITE_6) ||
6848 (SCSIcmd == READ_10) ||
6849 (SCSIcmd == WRITE_10) ||
6850 (SCSIcmd == WRITE_VERIFY) ||
6851 (SCSIcmd == START_STOP) ||
6852 (pCurrCard->globalFlags & F_NO_FILTER)
6853 )
6854 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
6855 }
6856
6857 if (p_sccb->SccbStatus == SCCB_IN_PROCESS) {
6858 if (p_sccb->HostStatus || p_sccb->TargetStatus)
6859 p_sccb->SccbStatus = SCCB_ERROR;
6860 else
6861 p_sccb->SccbStatus = SCCB_SUCCESS;
6862 }
6863
6864 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
6865
6866 p_sccb->CdbLength = p_sccb->Save_CdbLen;
6867 for (i = 0; i < 6; i++) {
6868 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
6869 }
6870 }
6871
6872 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
6873 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
6874
6875 FPT_utilUpdateResidual(p_sccb);
6876 }
6877
6878 pCurrCard->cmdCounter--;
6879 if (!pCurrCard->cmdCounter) {
6880
6881 if (pCurrCard->globalFlags & F_GREEN_PC) {
6882 WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0,
6883 (PWR_DWN | CLKCTRL_DEFAULT));
6884 WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK);
6885 }
6886
6887 WR_HARPOON(pCurrCard->ioPort + hp_semaphore,
6888 (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) &
6889 ~SCCB_MGR_ACTIVE));
6890
6891 }
6892
6893 if (pCurrCard->discQCount != 0) {
6894 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6895 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
6896 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6897 TAG_Q_TRYING))) {
6898 pCurrCard->discQCount--;
6899 pCurrCard->discQ_Tbl[currTar_Info->
6900 LunDiscQ_Idx[p_sccb->Lun]] = NULL;
6901 } else {
6902 if (p_sccb->Sccb_tag) {
6903 pCurrCard->discQCount--;
6904 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
6905 } else {
6906 pCurrCard->discQCount--;
6907 pCurrCard->discQ_Tbl[currTar_Info->
6908 LunDiscQ_Idx[0]] = NULL;
6909 }
6910 }
6911
6912 }
6913
6914 callback = (CALL_BK_FN) p_sccb->SccbCallback;
6915 callback(p_sccb);
6916 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6917 pCurrCard->currentSCCB = NULL;
6918}
6919
6920/*---------------------------------------------------------------------
6921 *
6922 * Function: Queue Disconnect
6923 *
6924 * Description: Add SCCB to our disconnect array.
6925 *
6926 *---------------------------------------------------------------------*/
6927static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card)
6928{
6929 struct sccb_mgr_tar_info *currTar_Info;
6930
6931 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6932
6933 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
6934 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
6935 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6936 LunDiscQ_Idx[p_sccb->Lun]] =
6937 p_sccb;
6938 } else {
6939 if (p_sccb->Sccb_tag) {
6940 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] =
6941 p_sccb;
6942 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] =
6943 0;
6944 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
6945 } else {
6946 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6947 LunDiscQ_Idx[0]] = p_sccb;
6948 }
6949 }
6950 FPT_BL_Card[p_card].currentSCCB = NULL;
6951}
6952
6953/*---------------------------------------------------------------------
6954 *
6955 * Function: Queue Flush SCCB
6956 *
6957 * Description: Flush all SCCB's back to the host driver for this target.
6958 *
6959 *---------------------------------------------------------------------*/
6960
6961static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
6962{
6963 unsigned char qtag, thisTarg;
6964 struct sccb *currSCCB;
6965 struct sccb_mgr_tar_info *currTar_Info;
6966
6967 currSCCB = FPT_BL_Card[p_card].currentSCCB;
6968 if (currSCCB != NULL) {
6969 thisTarg = (unsigned char)currSCCB->TargID;
6970 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6971
6972 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
6973
6974 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
6975 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
6976 thisTarg)) {
6977
6978 FPT_BL_Card[p_card].discQ_Tbl[qtag]->
6979 HostStatus = (unsigned char)error_code;
6980
6981 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
6982 FPT_BL_Card[p_card].
6983 discQ_Tbl[qtag], p_card);
6984
6985 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
6986 currTar_Info->TarTagQ_Cnt--;
6987
6988 }
6989 }
6990 }
6991
6992}
6993
6994/*---------------------------------------------------------------------
6995 *
6996 * Function: Queue Flush Target SCCB
6997 *
6998 * Description: Flush all SCCB's back to the host driver for this target.
6999 *
7000 *---------------------------------------------------------------------*/
7001
7002static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7003 unsigned char error_code)
7004{
7005 unsigned char qtag;
7006 struct sccb_mgr_tar_info *currTar_Info;
7007
7008 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7009
7010 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7011
7012 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7013 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) {
7014
7015 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus =
7016 (unsigned char)error_code;
7017
7018 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7019 FPT_BL_Card[p_card].
7020 discQ_Tbl[qtag], p_card);
7021
7022 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7023 currTar_Info->TarTagQ_Cnt--;
7024
7025 }
7026 }
7027
7028}
7029
7030static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card)
7031{
7032 struct sccb_mgr_tar_info *currTar_Info;
7033 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7034
7035 p_SCCB->Sccb_forwardlink = NULL;
7036
7037 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7038
7039 if (currTar_Info->TarSelQ_Cnt == 0) {
7040
7041 currTar_Info->TarSelQ_Head = p_SCCB;
7042 }
7043
7044 else {
7045
7046 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7047 }
7048
7049 currTar_Info->TarSelQ_Tail = p_SCCB;
7050 currTar_Info->TarSelQ_Cnt++;
7051}
7052
7053/*---------------------------------------------------------------------
7054 *
7055 * Function: Queue Find SCCB
7056 *
7057 * Description: Search the target select Queue for this SCCB, and
7058 * remove it if found.
7059 *
7060 *---------------------------------------------------------------------*/
7061
7062static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
7063 unsigned char p_card)
7064{
7065 struct sccb *q_ptr;
7066 struct sccb_mgr_tar_info *currTar_Info;
7067
7068 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7069
7070 q_ptr = currTar_Info->TarSelQ_Head;
7071
7072 while (q_ptr != NULL) {
7073
7074 if (q_ptr == p_SCCB) {
7075
7076 if (currTar_Info->TarSelQ_Head == q_ptr) {
7077
7078 currTar_Info->TarSelQ_Head =
7079 q_ptr->Sccb_forwardlink;
7080 }
7081
7082 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7083
7084 currTar_Info->TarSelQ_Tail =
7085 q_ptr->Sccb_backlink;
7086 }
7087
7088 if (q_ptr->Sccb_forwardlink != NULL) {
7089 q_ptr->Sccb_forwardlink->Sccb_backlink =
7090 q_ptr->Sccb_backlink;
7091 }
7092
7093 if (q_ptr->Sccb_backlink != NULL) {
7094 q_ptr->Sccb_backlink->Sccb_forwardlink =
7095 q_ptr->Sccb_forwardlink;
7096 }
7097
7098 currTar_Info->TarSelQ_Cnt--;
7099
7100 return 1;
7101 }
7102
7103 else {
7104 q_ptr = q_ptr->Sccb_forwardlink;
7105 }
7106 }
7107
7108 return 0;
7109
7110}
7111
7112/*---------------------------------------------------------------------
7113 *
7114 * Function: Utility Update Residual Count
7115 *
7116 * Description: Update the XferCnt to the remaining byte count.
7117 * If we transferred all the data then just write zero.
7118 * If Non-SG transfer then report Total Cnt - Actual Transfer
7119 * Cnt. For SG transfers add the count fields of all
7120 * remaining SG elements, as well as any partial remaining
7121 * element.
7122 *
7123 *---------------------------------------------------------------------*/
7124
7125static void FPT_utilUpdateResidual(struct sccb *p_SCCB)
7126{
7127 unsigned long partial_cnt;
7128 unsigned int sg_index;
7129 struct blogic_sg_seg *segp;
7130
7131 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7132
7133 p_SCCB->DataLength = 0x0000;
7134 }
7135
7136 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7137
7138 partial_cnt = 0x0000;
7139
7140 sg_index = p_SCCB->Sccb_sgseg;
7141
7142
7143 if (p_SCCB->Sccb_SGoffset) {
7144
7145 partial_cnt = p_SCCB->Sccb_SGoffset;
7146 sg_index++;
7147 }
7148
7149 while (((unsigned long)sg_index *
7150 (unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) {
7151 segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) +
7152 (sg_index * 2);
7153 partial_cnt += segp->segbytes;
7154 sg_index++;
7155 }
7156
7157 p_SCCB->DataLength = partial_cnt;
7158 }
7159
7160 else {
7161
7162 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7163 }
7164}
7165
7166/*---------------------------------------------------------------------
7167 *
7168 * Function: Wait 1 Second
7169 *
7170 * Description: Wait for 1 second.
7171 *
7172 *---------------------------------------------------------------------*/
7173
7174static void FPT_Wait1Second(u32 p_port)
7175{
7176 unsigned char i;
7177
7178 for (i = 0; i < 4; i++) {
7179
7180 FPT_Wait(p_port, TO_250ms);
7181
7182 if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7183 break;
7184
7185 if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7186 break;
7187 }
7188}
7189
7190/*---------------------------------------------------------------------
7191 *
7192 * Function: FPT_Wait
7193 *
7194 * Description: Wait the desired delay.
7195 *
7196 *---------------------------------------------------------------------*/
7197
7198static void FPT_Wait(u32 p_port, unsigned char p_delay)
7199{
7200 unsigned char old_timer;
7201 unsigned char green_flag;
7202
7203 old_timer = RD_HARPOON(p_port + hp_seltimeout);
7204
7205 green_flag = RD_HARPOON(p_port + hp_clkctrl_0);
7206 WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
7207
7208 WR_HARPOON(p_port + hp_seltimeout, p_delay);
7209 WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7210 WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT));
7211
7212 WR_HARPOON(p_port + hp_portctrl_0,
7213 (RD_HARPOON(p_port + hp_portctrl_0) | START_TO));
7214
7215 while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) {
7216
7217 if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7218 break;
7219
7220 if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7221 break;
7222 }
7223
7224 WR_HARPOON(p_port + hp_portctrl_0,
7225 (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO));
7226
7227 WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7228 WRW_HARPOON((p_port + hp_intena), FPT_default_intena);
7229
7230 WR_HARPOON(p_port + hp_clkctrl_0, green_flag);
7231
7232 WR_HARPOON(p_port + hp_seltimeout, old_timer);
7233}
7234
7235/*---------------------------------------------------------------------
7236 *
7237 * Function: Enable/Disable Write to EEPROM
7238 *
7239 * Description: The EEPROM must first be enabled for writes
7240 * A total of 9 clocks are needed.
7241 *
7242 *---------------------------------------------------------------------*/
7243
7244static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode)
7245{
7246 unsigned char ee_value;
7247
7248 ee_value =
7249 (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
7250 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7251
7252 if (p_mode)
7253
7254 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7255
7256 else
7257
7258 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7259
7260 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7261 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
7262}
7263
7264/*---------------------------------------------------------------------
7265 *
7266 * Function: Write EEPROM
7267 *
7268 * Description: Write a word to the EEPROM at the specified
7269 * address.
7270 *
7271 *---------------------------------------------------------------------*/
7272
7273static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
7274 unsigned short ee_addr)
7275{
7276
7277 unsigned char ee_value;
7278 unsigned short i;
7279
7280 ee_value =
7281 (unsigned
7282 char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7283 (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7284
7285 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7286
7287 ee_value |= (SEE_MS + SEE_CS);
7288
7289 for (i = 0x8000; i != 0; i >>= 1) {
7290
7291 if (i & ee_data)
7292 ee_value |= SEE_DO;
7293 else
7294 ee_value &= ~SEE_DO;
7295
7296 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7297 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7298 ee_value |= SEE_CLK; /* Clock data! */
7299 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7300 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7301 ee_value &= ~SEE_CLK;
7302 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7303 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7304 }
7305 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7306 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));
7307
7308 FPT_Wait(p_port, TO_10ms);
7309
7310 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7311 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7312 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /* Turn off Master Select */
7313}
7314
7315/*---------------------------------------------------------------------
7316 *
7317 * Function: Read EEPROM
7318 *
7319 * Description: Read a word from the EEPROM at the desired
7320 * address.
7321 *
7322 *---------------------------------------------------------------------*/
7323
7324static unsigned short FPT_utilEERead(u32 p_port,
7325 unsigned short ee_addr)
7326{
7327 unsigned short i, ee_data1, ee_data2;
7328
7329 i = 0;
7330 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7331 do {
7332 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7333
7334 if (ee_data1 == ee_data2)
7335 return ee_data1;
7336
7337 ee_data1 = ee_data2;
7338 i++;
7339
7340 } while (i < 4);
7341
7342 return ee_data1;
7343}
7344
7345/*---------------------------------------------------------------------
7346 *
7347 * Function: Read EEPROM Original
7348 *
7349 * Description: Read a word from the EEPROM at the desired
7350 * address.
7351 *
7352 *---------------------------------------------------------------------*/
7353
7354static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr)
7355{
7356
7357 unsigned char ee_value;
7358 unsigned short i, ee_data;
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_READ, ee_addr);
7366
7367 ee_value |= (SEE_MS + SEE_CS);
7368 ee_data = 0;
7369
7370 for (i = 1; i <= 16; i++) {
7371
7372 ee_value |= SEE_CLK; /* Clock data! */
7373 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7374 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7375 ee_value &= ~SEE_CLK;
7376 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7377 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7378
7379 ee_data <<= 1;
7380
7381 if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI)
7382 ee_data |= 1;
7383 }
7384
7385 ee_value &= ~(SEE_MS + SEE_CS);
7386 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7387 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
7388
7389 return ee_data;
7390}
7391
7392/*---------------------------------------------------------------------
7393 *
7394 * Function: Send EE command and Address to the EEPROM
7395 *
7396 * Description: Transfers the correct command and sends the address
7397 * to the eeprom.
7398 *
7399 *---------------------------------------------------------------------*/
7400
7401static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
7402 unsigned short ee_addr)
7403{
7404 unsigned char ee_value;
7405 unsigned char narrow_flg;
7406
7407 unsigned short i;
7408
7409 narrow_flg =
7410 (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
7411 NARROW_SCSI_CARD);
7412
7413 ee_value = SEE_MS;
7414 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7415
7416 ee_value |= SEE_CS; /* Set CS to EEPROM */
7417 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7418
7419 for (i = 0x04; i != 0; i >>= 1) {
7420
7421 if (i & ee_cmd)
7422 ee_value |= SEE_DO;
7423 else
7424 ee_value &= ~SEE_DO;
7425
7426 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7427 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7428 ee_value |= SEE_CLK; /* Clock data! */
7429 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7430 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7431 ee_value &= ~SEE_CLK;
7432 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7433 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7434 }
7435
7436 if (narrow_flg)
7437 i = 0x0080;
7438
7439 else
7440 i = 0x0200;
7441
7442 while (i != 0) {
7443
7444 if (i & ee_addr)
7445 ee_value |= SEE_DO;
7446 else
7447 ee_value &= ~SEE_DO;
7448
7449 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7450 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7451 ee_value |= SEE_CLK; /* Clock data! */
7452 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7453 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7454 ee_value &= ~SEE_CLK;
7455 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7456 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7457
7458 i >>= 1;
7459 }
7460}
7461
7462static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7463{
7464 unsigned short crc = 0;
7465 int i, j;
7466 unsigned short ch;
7467 for (i = 0; i < ID_STRING_LENGTH; i++) {
7468 ch = (unsigned short)buffer[i];
7469 for (j = 0; j < 8; j++) {
7470 if ((crc ^ ch) & 1)
7471 crc = (crc >> 1) ^ CRCMASK;
7472 else
7473 crc >>= 1;
7474 ch >>= 1;
7475 }
7476 }
7477 return crc;
7478}
7479
7480static unsigned char FPT_CalcLrc(unsigned char buffer[])
7481{
7482 int i;
7483 unsigned char lrc;
7484 lrc = 0;
7485 for (i = 0; i < ID_STRING_LENGTH; i++)
7486 lrc ^= buffer[i];
7487 return lrc;
7488}
7489
7490/*
7491 The following inline definitions avoid type conflicts.
7492*/
7493
7494static inline unsigned char
7495FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo)
7496{
7497 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *)
7498 FlashPointInfo);
7499}
7500
7501static inline void *
7502FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo)
7503{
7504 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *)
7505 FlashPointInfo);
7506}
7507
7508static inline void
7509FlashPoint__ReleaseHostAdapter(void *CardHandle)
7510{
7511 FlashPoint_ReleaseHostAdapter(CardHandle);
7512}
7513
7514static inline void
7515FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB)
7516{
7517 FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB);
7518}
7519
7520static inline void
7521FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB)
7522{
7523 FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
7524}
7525
7526static inline bool
7527FlashPoint__InterruptPending(void *CardHandle)
7528{
7529 return FlashPoint_InterruptPending(CardHandle);
7530}
7531
7532static inline int
7533FlashPoint__HandleInterrupt(void *CardHandle)
7534{
7535 return FlashPoint_HandleInterrupt(CardHandle);
7536}
7537
7538#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7539#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7540#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7541#define FlashPoint_StartCCB FlashPoint__StartCCB
7542#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7543#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7544#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7545
7546#else /* !CONFIG_SCSI_FLASHPOINT */
7547
7548/*
7549 Define prototypes for the FlashPoint SCCB Manager Functions.
7550*/
7551
7552extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *);
7553extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *);
7554extern void FlashPoint_StartCCB(void *, struct blogic_ccb *);
7555extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *);
7556extern bool FlashPoint_InterruptPending(void *);
7557extern int FlashPoint_HandleInterrupt(void *);
7558extern void FlashPoint_ReleaseHostAdapter(void *);
7559
7560#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;
1038 fallthrough;
1039 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1040 temp5 |= 0x8000;
1041 fallthrough;
1042 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1043 temp2 |= 0x8000;
1044 fallthrough;
1045 case AUTO_RATE_00: /* Asynchronous */
1046 break;
1047 }
1048
1049 if (temp & DISC_ENABLE_BIT)
1050 temp3 |= 0x8000;
1051
1052 if (temp & WIDE_NEGO_BIT)
1053 temp4 |= 0x8000;
1054
1055 }
1056 }
1057
1058 pCardInfo->si_per_targ_init_sync = temp2;
1059 pCardInfo->si_per_targ_no_disc = temp3;
1060 pCardInfo->si_per_targ_wide_nego = temp4;
1061 pCardInfo->si_per_targ_fast_nego = temp5;
1062 pCardInfo->si_per_targ_ultra_nego = temp6;
1063
1064 if (pCurrNvRam)
1065 i = pCurrNvRam->niSysConf;
1066 else
1067 i = (unsigned
1068 char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)));
1069
1070 if (pCurrNvRam)
1071 ScamFlg = pCurrNvRam->niScamConf;
1072 else
1073 ScamFlg =
1074 (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1075
1076 pCardInfo->si_flags = 0x0000;
1077
1078 if (i & 0x01)
1079 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1080
1081 if (!(i & 0x02))
1082 pCardInfo->si_flags |= SOFT_RESET;
1083
1084 if (i & 0x10)
1085 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1086
1087 if (ScamFlg & SCAM_ENABLED)
1088 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1089
1090 if (ScamFlg & SCAM_LEVEL2)
1091 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1092
1093 j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1094 if (i & 0x04) {
1095 j |= SCSI_TERM_ENA_L;
1096 }
1097 WR_HARPOON(ioport + hp_bm_ctrl, j);
1098
1099 j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1100 if (i & 0x08) {
1101 j |= SCSI_TERM_ENA_H;
1102 }
1103 WR_HARPOON(ioport + hp_ee_ctrl, j);
1104
1105 if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD))
1106
1107 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1108
1109 pCardInfo->si_card_family = HARPOON_FAMILY;
1110 pCardInfo->si_bustype = BUSTYPE_PCI;
1111
1112 if (pCurrNvRam) {
1113 pCardInfo->si_card_model[0] = '9';
1114 switch (pCurrNvRam->niModel & 0x0f) {
1115 case MODEL_LT:
1116 pCardInfo->si_card_model[1] = '3';
1117 pCardInfo->si_card_model[2] = '0';
1118 break;
1119 case MODEL_LW:
1120 pCardInfo->si_card_model[1] = '5';
1121 pCardInfo->si_card_model[2] = '0';
1122 break;
1123 case MODEL_DL:
1124 pCardInfo->si_card_model[1] = '3';
1125 pCardInfo->si_card_model[2] = '2';
1126 break;
1127 case MODEL_DW:
1128 pCardInfo->si_card_model[1] = '5';
1129 pCardInfo->si_card_model[2] = '2';
1130 break;
1131 }
1132 } else {
1133 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0 / 2));
1134 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1135 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2 / 2));
1136
1137 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1138 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1139 }
1140
1141 if (pCardInfo->si_card_model[1] == '3') {
1142 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1143 pCardInfo->si_flags |= LOW_BYTE_TERM;
1144 } else if (pCardInfo->si_card_model[2] == '0') {
1145 temp = RD_HARPOON(ioport + hp_xfer_pad);
1146 WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4)));
1147 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1148 pCardInfo->si_flags |= LOW_BYTE_TERM;
1149 WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4)));
1150 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1151 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1152 WR_HARPOON(ioport + hp_xfer_pad, temp);
1153 } else {
1154 temp = RD_HARPOON(ioport + hp_ee_ctrl);
1155 temp2 = RD_HARPOON(ioport + hp_xfer_pad);
1156 WR_HARPOON(ioport + hp_ee_ctrl, (temp | SEE_CS));
1157 WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1158 temp3 = 0;
1159 for (i = 0; i < 8; i++) {
1160 temp3 <<= 1;
1161 if (!(RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)))
1162 temp3 |= 1;
1163 WR_HARPOON(ioport + hp_xfer_pad, (temp2 & ~BIT(4)));
1164 WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1165 }
1166 WR_HARPOON(ioport + hp_ee_ctrl, temp);
1167 WR_HARPOON(ioport + hp_xfer_pad, temp2);
1168 if (!(temp3 & BIT(7)))
1169 pCardInfo->si_flags |= LOW_BYTE_TERM;
1170 if (!(temp3 & BIT(6)))
1171 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1172 }
1173
1174 ARAM_ACCESS(ioport);
1175
1176 for (i = 0; i < 4; i++) {
1177
1178 pCardInfo->si_XlatInfo[i] =
1179 RD_HARPOON(ioport + hp_aramBase + BIOS_DATA_OFFSET + i);
1180 }
1181
1182 /* return with -1 if no sort, else return with
1183 logical card number sorted by BIOS (zero-based) */
1184
1185 pCardInfo->si_relative_cardnum =
1186 (unsigned
1187 char)(RD_HARPOON(ioport + hp_aramBase + BIOS_RELATIVE_CARD) - 1);
1188
1189 SGRAM_ACCESS(ioport);
1190
1191 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1192 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1193 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1194 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1195 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1196 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1197 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1198 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1199
1200 pCardInfo->si_present = 0x01;
1201
1202 return 0;
1203}
1204
1205/*---------------------------------------------------------------------
1206 *
1207 * Function: FlashPoint_HardwareResetHostAdapter
1208 *
1209 * Description: Setup adapter for normal operation (hard reset).
1210 *
1211 *---------------------------------------------------------------------*/
1212
1213static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
1214 *pCardInfo)
1215{
1216 struct sccb_card *CurrCard = NULL;
1217 struct nvram_info *pCurrNvRam;
1218 unsigned char i, j, thisCard, ScamFlg;
1219 unsigned short temp, sync_bit_map, id;
1220 u32 ioport;
1221
1222 ioport = pCardInfo->si_baseaddr;
1223
1224 for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) {
1225
1226 if (thisCard == MAX_CARDS)
1227 return (void *)FAILURE;
1228
1229 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1230
1231 CurrCard = &FPT_BL_Card[thisCard];
1232 FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1233 break;
1234 }
1235
1236 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1237
1238 FPT_BL_Card[thisCard].ioPort = ioport;
1239 CurrCard = &FPT_BL_Card[thisCard];
1240
1241 if (FPT_mbCards)
1242 for (i = 0; i < FPT_mbCards; i++) {
1243 if (CurrCard->ioPort ==
1244 FPT_nvRamInfo[i].niBaseAddr)
1245 CurrCard->pNvRamInfo =
1246 &FPT_nvRamInfo[i];
1247 }
1248 FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1249 CurrCard->cardIndex = thisCard;
1250 CurrCard->cardInfo = pCardInfo;
1251
1252 break;
1253 }
1254 }
1255
1256 pCurrNvRam = CurrCard->pNvRamInfo;
1257
1258 if (pCurrNvRam) {
1259 ScamFlg = pCurrNvRam->niScamConf;
1260 } else {
1261 ScamFlg =
1262 (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1263 }
1264
1265 FPT_BusMasterInit(ioport);
1266 FPT_XbowInit(ioport, ScamFlg);
1267
1268 FPT_autoLoadDefaultMap(ioport);
1269
1270 for (i = 0, id = 0x01; i != pCardInfo->si_id; i++, id <<= 1) {
1271 }
1272
1273 WR_HARPOON(ioport + hp_selfid_0, id);
1274 WR_HARPOON(ioport + hp_selfid_1, 0x00);
1275 WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id);
1276 CurrCard->ourId = pCardInfo->si_id;
1277
1278 i = (unsigned char)pCardInfo->si_flags;
1279 if (i & SCSI_PARITY_ENA)
1280 WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P));
1281
1282 j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1283 if (i & LOW_BYTE_TERM)
1284 j |= SCSI_TERM_ENA_L;
1285 WR_HARPOON(ioport + hp_bm_ctrl, j);
1286
1287 j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1288 if (i & HIGH_BYTE_TERM)
1289 j |= SCSI_TERM_ENA_H;
1290 WR_HARPOON(ioport + hp_ee_ctrl, j);
1291
1292 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1293
1294 FPT_sresb(ioport, thisCard);
1295
1296 FPT_scini(thisCard, pCardInfo->si_id, 0);
1297 }
1298
1299 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1300 CurrCard->globalFlags |= F_NO_FILTER;
1301
1302 if (pCurrNvRam) {
1303 if (pCurrNvRam->niSysConf & 0x10)
1304 CurrCard->globalFlags |= F_GREEN_PC;
1305 } else {
1306 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)) & GREEN_PC_ENA)
1307 CurrCard->globalFlags |= F_GREEN_PC;
1308 }
1309
1310 /* Set global flag to indicate Re-Negotiation to be done on all
1311 ckeck condition */
1312 if (pCurrNvRam) {
1313 if (pCurrNvRam->niScsiConf & 0x04)
1314 CurrCard->globalFlags |= F_DO_RENEGO;
1315 } else {
1316 if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & RENEGO_ENA)
1317 CurrCard->globalFlags |= F_DO_RENEGO;
1318 }
1319
1320 if (pCurrNvRam) {
1321 if (pCurrNvRam->niScsiConf & 0x08)
1322 CurrCard->globalFlags |= F_CONLUN_IO;
1323 } else {
1324 if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & CONNIO_ENA)
1325 CurrCard->globalFlags |= F_CONLUN_IO;
1326 }
1327
1328 temp = pCardInfo->si_per_targ_no_disc;
1329
1330 for (i = 0, id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1331
1332 if (temp & id)
1333 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1334 }
1335
1336 sync_bit_map = 0x0001;
1337
1338 for (id = 0; id < (MAX_SCSI_TAR / 2); id++) {
1339
1340 if (pCurrNvRam) {
1341 temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
1342 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1343 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1344 } else
1345 temp =
1346 FPT_utilEERead(ioport,
1347 (unsigned short)((SYNC_RATE_TBL / 2)
1348 + id));
1349
1350 for (i = 0; i < 2; temp >>= 8, i++) {
1351
1352 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1353
1354 FPT_sccbMgrTbl[thisCard][id * 2 +
1355 i].TarEEValue =
1356 (unsigned char)temp;
1357 }
1358
1359 else {
1360 FPT_sccbMgrTbl[thisCard][id * 2 +
1361 i].TarStatus |=
1362 SYNC_SUPPORTED;
1363 FPT_sccbMgrTbl[thisCard][id * 2 +
1364 i].TarEEValue =
1365 (unsigned char)(temp & ~EE_SYNC_MASK);
1366 }
1367
1368/* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1369 (id*2+i >= 8)){
1370*/
1371 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map) {
1372
1373 FPT_sccbMgrTbl[thisCard][id * 2 +
1374 i].TarEEValue |=
1375 EE_WIDE_SCSI;
1376
1377 }
1378
1379 else { /* NARROW SCSI */
1380 FPT_sccbMgrTbl[thisCard][id * 2 +
1381 i].TarStatus |=
1382 WIDE_NEGOCIATED;
1383 }
1384
1385 sync_bit_map <<= 1;
1386
1387 }
1388 }
1389
1390 WR_HARPOON((ioport + hp_semaphore),
1391 (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) |
1392 SCCB_MGR_PRESENT));
1393
1394 return (void *)CurrCard;
1395}
1396
1397static void FlashPoint_ReleaseHostAdapter(void *pCurrCard)
1398{
1399 unsigned char i;
1400 u32 portBase;
1401 u32 regOffset;
1402 u32 scamData;
1403 u32 *pScamTbl;
1404 struct nvram_info *pCurrNvRam;
1405
1406 pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
1407
1408 if (pCurrNvRam) {
1409 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1410 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1411 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1412 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1413 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1414
1415 for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1416 FPT_WrStack(pCurrNvRam->niBaseAddr,
1417 (unsigned char)(i + 5),
1418 pCurrNvRam->niSyncTbl[i]);
1419
1420 portBase = pCurrNvRam->niBaseAddr;
1421
1422 for (i = 0; i < MAX_SCSI_TAR; i++) {
1423 regOffset = hp_aramBase + 64 + i * 4;
1424 pScamTbl = (u32 *)&pCurrNvRam->niScamTbl[i];
1425 scamData = *pScamTbl;
1426 WR_HARP32(portBase, regOffset, scamData);
1427 }
1428
1429 } else {
1430 FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0);
1431 }
1432}
1433
1434static void FPT_RNVRamData(struct nvram_info *pNvRamInfo)
1435{
1436 unsigned char i;
1437 u32 portBase;
1438 u32 regOffset;
1439 u32 scamData;
1440 u32 *pScamTbl;
1441
1442 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1443 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1444 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1445 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1446 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1447
1448 for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1449 pNvRamInfo->niSyncTbl[i] =
1450 FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i + 5));
1451
1452 portBase = pNvRamInfo->niBaseAddr;
1453
1454 for (i = 0; i < MAX_SCSI_TAR; i++) {
1455 regOffset = hp_aramBase + 64 + i * 4;
1456 RD_HARP32(portBase, regOffset, scamData);
1457 pScamTbl = (u32 *)&pNvRamInfo->niScamTbl[i];
1458 *pScamTbl = scamData;
1459 }
1460
1461}
1462
1463static unsigned char FPT_RdStack(u32 portBase, unsigned char index)
1464{
1465 WR_HARPOON(portBase + hp_stack_addr, index);
1466 return RD_HARPOON(portBase + hp_stack_data);
1467}
1468
1469static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data)
1470{
1471 WR_HARPOON(portBase + hp_stack_addr, index);
1472 WR_HARPOON(portBase + hp_stack_data, data);
1473}
1474
1475static unsigned char FPT_ChkIfChipInitialized(u32 ioPort)
1476{
1477 if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1478 return 0;
1479 if ((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1480 != CLKCTRL_DEFAULT)
1481 return 0;
1482 if ((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1483 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1484 return 1;
1485 return 0;
1486
1487}
1488
1489/*---------------------------------------------------------------------
1490 *
1491 * Function: FlashPoint_StartCCB
1492 *
1493 * Description: Start a command pointed to by p_Sccb. When the
1494 * command is completed it will be returned via the
1495 * callback function.
1496 *
1497 *---------------------------------------------------------------------*/
1498static void FlashPoint_StartCCB(void *curr_card, struct sccb *p_Sccb)
1499{
1500 u32 ioport;
1501 unsigned char thisCard, lun;
1502 struct sccb *pSaveSccb;
1503 CALL_BK_FN callback;
1504 struct sccb_card *pCurrCard = curr_card;
1505
1506 thisCard = pCurrCard->cardIndex;
1507 ioport = pCurrCard->ioPort;
1508
1509 if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) {
1510
1511 p_Sccb->HostStatus = SCCB_COMPLETE;
1512 p_Sccb->SccbStatus = SCCB_ERROR;
1513 callback = (CALL_BK_FN) p_Sccb->SccbCallback;
1514 if (callback)
1515 callback(p_Sccb);
1516
1517 return;
1518 }
1519
1520 FPT_sinits(p_Sccb, thisCard);
1521
1522 if (!pCurrCard->cmdCounter) {
1523 WR_HARPOON(ioport + hp_semaphore,
1524 (RD_HARPOON(ioport + hp_semaphore)
1525 | SCCB_MGR_ACTIVE));
1526
1527 if (pCurrCard->globalFlags & F_GREEN_PC) {
1528 WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
1529 WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
1530 }
1531 }
1532
1533 pCurrCard->cmdCounter++;
1534
1535 if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) {
1536
1537 WR_HARPOON(ioport + hp_semaphore,
1538 (RD_HARPOON(ioport + hp_semaphore)
1539 | TICKLE_ME));
1540 if (p_Sccb->OperationCode == RESET_COMMAND) {
1541 pSaveSccb =
1542 pCurrCard->currentSCCB;
1543 pCurrCard->currentSCCB = p_Sccb;
1544 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1545 pCurrCard->currentSCCB =
1546 pSaveSccb;
1547 } else {
1548 FPT_queueAddSccb(p_Sccb, thisCard);
1549 }
1550 }
1551
1552 else if ((RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1553
1554 if (p_Sccb->OperationCode == RESET_COMMAND) {
1555 pSaveSccb =
1556 pCurrCard->currentSCCB;
1557 pCurrCard->currentSCCB = p_Sccb;
1558 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1559 pCurrCard->currentSCCB =
1560 pSaveSccb;
1561 } else {
1562 FPT_queueAddSccb(p_Sccb, thisCard);
1563 }
1564 }
1565
1566 else {
1567
1568 MDISABLE_INT(ioport);
1569
1570 if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
1571 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].
1572 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1573 lun = p_Sccb->Lun;
1574 else
1575 lun = 0;
1576 if ((pCurrCard->currentSCCB == NULL) &&
1577 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0)
1578 && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1579 == 0)) {
1580
1581 pCurrCard->currentSCCB = p_Sccb;
1582 FPT_ssel(p_Sccb->SccbIOPort, thisCard);
1583 }
1584
1585 else {
1586
1587 if (p_Sccb->OperationCode == RESET_COMMAND) {
1588 pSaveSccb = pCurrCard->currentSCCB;
1589 pCurrCard->currentSCCB = p_Sccb;
1590 FPT_queueSelectFail(&FPT_BL_Card[thisCard],
1591 thisCard);
1592 pCurrCard->currentSCCB = pSaveSccb;
1593 } else {
1594 FPT_queueAddSccb(p_Sccb, thisCard);
1595 }
1596 }
1597
1598 MENABLE_INT(ioport);
1599 }
1600
1601}
1602
1603/*---------------------------------------------------------------------
1604 *
1605 * Function: FlashPoint_AbortCCB
1606 *
1607 * Description: Abort the command pointed to by p_Sccb. When the
1608 * command is completed it will be returned via the
1609 * callback function.
1610 *
1611 *---------------------------------------------------------------------*/
1612static int FlashPoint_AbortCCB(void *pCurrCard, struct sccb *p_Sccb)
1613{
1614 u32 ioport;
1615
1616 unsigned char thisCard;
1617 CALL_BK_FN callback;
1618 unsigned char TID;
1619 struct sccb *pSaveSCCB;
1620 struct sccb_mgr_tar_info *currTar_Info;
1621
1622 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1623
1624 thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1625
1626 if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1627
1628 if (FPT_queueFindSccb(p_Sccb, thisCard)) {
1629
1630 ((struct sccb_card *)pCurrCard)->cmdCounter--;
1631
1632 if (!((struct sccb_card *)pCurrCard)->cmdCounter)
1633 WR_HARPOON(ioport + hp_semaphore,
1634 (RD_HARPOON(ioport + hp_semaphore)
1635 & (unsigned
1636 char)(~(SCCB_MGR_ACTIVE |
1637 TICKLE_ME))));
1638
1639 p_Sccb->SccbStatus = SCCB_ABORT;
1640 callback = p_Sccb->SccbCallback;
1641 callback(p_Sccb);
1642
1643 return 0;
1644 }
1645
1646 else {
1647 if (((struct sccb_card *)pCurrCard)->currentSCCB ==
1648 p_Sccb) {
1649 p_Sccb->SccbStatus = SCCB_ABORT;
1650 return 0;
1651
1652 }
1653
1654 else {
1655
1656 TID = p_Sccb->TargID;
1657
1658 if (p_Sccb->Sccb_tag) {
1659 MDISABLE_INT(ioport);
1660 if (((struct sccb_card *)pCurrCard)->
1661 discQ_Tbl[p_Sccb->Sccb_tag] ==
1662 p_Sccb) {
1663 p_Sccb->SccbStatus = SCCB_ABORT;
1664 p_Sccb->Sccb_scsistat =
1665 ABORT_ST;
1666 p_Sccb->Sccb_scsimsg =
1667 SMABORT_TAG;
1668
1669 if (((struct sccb_card *)
1670 pCurrCard)->currentSCCB ==
1671 NULL) {
1672 ((struct sccb_card *)
1673 pCurrCard)->
1674 currentSCCB = p_Sccb;
1675 FPT_ssel(ioport,
1676 thisCard);
1677 } else {
1678 pSaveSCCB =
1679 ((struct sccb_card
1680 *)pCurrCard)->
1681 currentSCCB;
1682 ((struct sccb_card *)
1683 pCurrCard)->
1684 currentSCCB = p_Sccb;
1685 FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard);
1686 ((struct sccb_card *)
1687 pCurrCard)->
1688 currentSCCB = pSaveSCCB;
1689 }
1690 }
1691 MENABLE_INT(ioport);
1692 return 0;
1693 } else {
1694 currTar_Info =
1695 &FPT_sccbMgrTbl[thisCard][p_Sccb->
1696 TargID];
1697
1698 if (FPT_BL_Card[thisCard].
1699 discQ_Tbl[currTar_Info->
1700 LunDiscQ_Idx[p_Sccb->Lun]]
1701 == p_Sccb) {
1702 p_Sccb->SccbStatus = SCCB_ABORT;
1703 return 0;
1704 }
1705 }
1706 }
1707 }
1708 }
1709 return -1;
1710}
1711
1712/*---------------------------------------------------------------------
1713 *
1714 * Function: FlashPoint_InterruptPending
1715 *
1716 * Description: Do a quick check to determine if there is a pending
1717 * interrupt for this card and disable the IRQ Pin if so.
1718 *
1719 *---------------------------------------------------------------------*/
1720static unsigned char FlashPoint_InterruptPending(void *pCurrCard)
1721{
1722 u32 ioport;
1723
1724 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1725
1726 if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) {
1727 return 1;
1728 }
1729
1730 else
1731
1732 return 0;
1733}
1734
1735/*---------------------------------------------------------------------
1736 *
1737 * Function: FlashPoint_HandleInterrupt
1738 *
1739 * Description: This is our entry point when an interrupt is generated
1740 * by the card and the upper level driver passes it on to
1741 * us.
1742 *
1743 *---------------------------------------------------------------------*/
1744static int FlashPoint_HandleInterrupt(void *pcard)
1745{
1746 struct sccb *currSCCB;
1747 unsigned char thisCard, result, bm_status, bm_int_st;
1748 unsigned short hp_int;
1749 unsigned char i, target;
1750 struct sccb_card *pCurrCard = pcard;
1751 u32 ioport;
1752
1753 thisCard = pCurrCard->cardIndex;
1754 ioport = pCurrCard->ioPort;
1755
1756 MDISABLE_INT(ioport);
1757
1758 if ((bm_int_st = RD_HARPOON(ioport + hp_int_status)) & EXT_STATUS_ON)
1759 bm_status = RD_HARPOON(ioport + hp_ext_status) &
1760 (unsigned char)BAD_EXT_STATUS;
1761 else
1762 bm_status = 0;
1763
1764 WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1765
1766 while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) &
1767 FPT_default_intena) | bm_status) {
1768
1769 currSCCB = pCurrCard->currentSCCB;
1770
1771 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1772 result =
1773 FPT_SccbMgr_bad_isr(ioport, thisCard, 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 (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1800
1801 FPT_phaseChkFifo(ioport, thisCard);
1802
1803/* WRW_HARPOON((ioport+hp_intstat),
1804 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1805 */
1806
1807 WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1);
1808
1809 FPT_autoCmdCmplt(ioport, thisCard);
1810
1811 }
1812
1813 else if (hp_int & ITAR_DISC) {
1814
1815 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1816 FPT_phaseChkFifo(ioport, thisCard);
1817
1818 if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1819 SMSAVE_DATA_PTR) {
1820
1821 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1822 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1823
1824 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1825 }
1826
1827 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1828 FPT_queueDisconnect(currSCCB, thisCard);
1829
1830 /* Wait for the BusFree before starting a new command. We
1831 must also check for being reselected since the BusFree
1832 may not show up if another device reselects us in 1.5us or
1833 less. SRR Wednesday, 3/8/1995.
1834 */
1835 while (!
1836 (RDW_HARPOON((ioport + hp_intstat)) &
1837 (BUS_FREE | RSEL))
1838 && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE)
1839 && RD_HARPOON((ioport + hp_scsisig)) ==
1840 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG |
1841 SCSI_IOBIT))) ;
1842
1843 /*
1844 The additional loop exit condition above detects a timing problem
1845 with the revision D/E harpoon chips. The caller should reset the
1846 host adapter to recover when 0xFE is returned.
1847 */
1848 if (!
1849 (RDW_HARPOON((ioport + hp_intstat)) &
1850 (BUS_FREE | RSEL))) {
1851 MENABLE_INT(ioport);
1852 return 0xFE;
1853 }
1854
1855 WRW_HARPOON((ioport + hp_intstat),
1856 (BUS_FREE | ITAR_DISC));
1857
1858 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1859
1860 }
1861
1862 else if (hp_int & RSEL) {
1863
1864 WRW_HARPOON((ioport + hp_intstat),
1865 (PROG_HLT | RSEL | PHASE | BUS_FREE));
1866
1867 if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) {
1868 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1869 FPT_phaseChkFifo(ioport, thisCard);
1870
1871 if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1872 SMSAVE_DATA_PTR) {
1873 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1874 currSCCB->Sccb_XferState |=
1875 F_NO_DATA_YET;
1876 currSCCB->Sccb_savedATC =
1877 currSCCB->Sccb_ATC;
1878 }
1879
1880 WRW_HARPOON((ioport + hp_intstat),
1881 (BUS_FREE | ITAR_DISC));
1882 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1883 FPT_queueDisconnect(currSCCB, thisCard);
1884 }
1885
1886 FPT_sres(ioport, thisCard, pCurrCard);
1887 FPT_phaseDecode(ioport, thisCard);
1888
1889 }
1890
1891 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) {
1892
1893 WRW_HARPOON((ioport + hp_intstat),
1894 (IDO_STRT | XFER_CNT_0));
1895 FPT_phaseDecode(ioport, thisCard);
1896
1897 }
1898
1899 else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) {
1900 WRW_HARPOON((ioport + hp_intstat),
1901 (PHASE | IUNKWN | PROG_HLT));
1902 if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char)
1903 0x3f) < (unsigned char)SELCHK) {
1904 FPT_phaseDecode(ioport, thisCard);
1905 } else {
1906 /* Harpoon problem some SCSI target device respond to selection
1907 with short BUSY pulse (<400ns) this will make the Harpoon is not able
1908 to latch the correct Target ID into reg. x53.
1909 The work around require to correct this reg. But when write to this
1910 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
1911 need to read this reg first then restore it later. After update to 0x53 */
1912
1913 i = (unsigned
1914 char)(RD_HARPOON(ioport + hp_fifowrite));
1915 target =
1916 (unsigned
1917 char)(RD_HARPOON(ioport + hp_gp_reg_3));
1918 WR_HARPOON(ioport + hp_xfer_pad,
1919 (unsigned char)ID_UNLOCK);
1920 WR_HARPOON(ioport + hp_select_id,
1921 (unsigned char)(target | target <<
1922 4));
1923 WR_HARPOON(ioport + hp_xfer_pad,
1924 (unsigned char)0x00);
1925 WR_HARPOON(ioport + hp_fifowrite, i);
1926 WR_HARPOON(ioport + hp_autostart_3,
1927 (AUTO_IMMED + TAG_STRT));
1928 }
1929 }
1930
1931 else if (hp_int & XFER_CNT_0) {
1932
1933 WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0);
1934
1935 FPT_schkdd(ioport, thisCard);
1936
1937 }
1938
1939 else if (hp_int & BUS_FREE) {
1940
1941 WRW_HARPOON((ioport + hp_intstat), BUS_FREE);
1942
1943 if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
1944
1945 FPT_hostDataXferAbort(ioport, thisCard,
1946 currSCCB);
1947 }
1948
1949 FPT_phaseBusFree(ioport, thisCard);
1950 }
1951
1952 else if (hp_int & ITICKLE) {
1953
1954 WRW_HARPOON((ioport + hp_intstat), ITICKLE);
1955 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1956 }
1957
1958 if (((struct sccb_card *)pCurrCard)->
1959 globalFlags & F_NEW_SCCB_CMD) {
1960
1961 pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1962
1963 if (pCurrCard->currentSCCB == NULL)
1964 FPT_queueSearchSelect(pCurrCard, thisCard);
1965
1966 if (pCurrCard->currentSCCB != NULL) {
1967 pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1968 FPT_ssel(ioport, thisCard);
1969 }
1970
1971 break;
1972
1973 }
1974
1975 } /*end while */
1976
1977 MENABLE_INT(ioport);
1978
1979 return 0;
1980}
1981
1982/*---------------------------------------------------------------------
1983 *
1984 * Function: Sccb_bad_isr
1985 *
1986 * Description: Some type of interrupt has occurred which is slightly
1987 * out of the ordinary. We will now decode it fully, in
1988 * this routine. This is broken up in an attempt to save
1989 * processing time.
1990 *
1991 *---------------------------------------------------------------------*/
1992static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card,
1993 struct sccb_card *pCurrCard,
1994 unsigned short p_int)
1995{
1996 unsigned char temp, ScamFlg;
1997 struct sccb_mgr_tar_info *currTar_Info;
1998 struct nvram_info *pCurrNvRam;
1999
2000 if (RD_HARPOON(p_port + hp_ext_status) &
2001 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) {
2002
2003 if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
2004
2005 FPT_hostDataXferAbort(p_port, p_card,
2006 pCurrCard->currentSCCB);
2007 }
2008
2009 if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT)
2010 {
2011 WR_HARPOON(p_port + hp_pci_stat_cfg,
2012 (RD_HARPOON(p_port + hp_pci_stat_cfg) &
2013 ~REC_MASTER_ABORT));
2014
2015 WR_HARPOON(p_port + hp_host_blk_cnt, 0x00);
2016
2017 }
2018
2019 if (pCurrCard->currentSCCB != NULL) {
2020
2021 if (!pCurrCard->currentSCCB->HostStatus)
2022 pCurrCard->currentSCCB->HostStatus =
2023 SCCB_BM_ERR;
2024
2025 FPT_sxfrp(p_port, p_card);
2026
2027 temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
2028 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2029 WR_HARPOON(p_port + hp_ee_ctrl,
2030 ((unsigned char)temp | SEE_MS | SEE_CS));
2031 WR_HARPOON(p_port + hp_ee_ctrl, temp);
2032
2033 if (!
2034 (RDW_HARPOON((p_port + hp_intstat)) &
2035 (BUS_FREE | RESET))) {
2036 FPT_phaseDecode(p_port, p_card);
2037 }
2038 }
2039 }
2040
2041 else if (p_int & RESET) {
2042
2043 WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
2044 WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
2045 if (pCurrCard->currentSCCB != NULL) {
2046
2047 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2048
2049 FPT_hostDataXferAbort(p_port, p_card,
2050 pCurrCard->currentSCCB);
2051 }
2052
2053 DISABLE_AUTO(p_port);
2054
2055 FPT_sresb(p_port, p_card);
2056
2057 while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) {
2058 }
2059
2060 pCurrNvRam = pCurrCard->pNvRamInfo;
2061 if (pCurrNvRam) {
2062 ScamFlg = pCurrNvRam->niScamConf;
2063 } else {
2064 ScamFlg =
2065 (unsigned char)FPT_utilEERead(p_port,
2066 SCAM_CONFIG / 2);
2067 }
2068
2069 FPT_XbowInit(p_port, ScamFlg);
2070
2071 FPT_scini(p_card, pCurrCard->ourId, 0);
2072
2073 return 0xFF;
2074 }
2075
2076 else if (p_int & FIFO) {
2077
2078 WRW_HARPOON((p_port + hp_intstat), FIFO);
2079
2080 if (pCurrCard->currentSCCB != NULL)
2081 FPT_sxfrp(p_port, p_card);
2082 }
2083
2084 else if (p_int & TIMEOUT) {
2085
2086 DISABLE_AUTO(p_port);
2087
2088 WRW_HARPOON((p_port + hp_intstat),
2089 (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE |
2090 IUNKWN));
2091
2092 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2093
2094 currTar_Info =
2095 &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2096 if ((pCurrCard->globalFlags & F_CONLUN_IO)
2097 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2098 TAG_Q_TRYING))
2099 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] =
2100 0;
2101 else
2102 currTar_Info->TarLUNBusy[0] = 0;
2103
2104 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2105 currTar_Info->TarSyncCtrl = 0;
2106 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2107 }
2108
2109 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2110 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2111 }
2112
2113 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,
2114 currTar_Info);
2115
2116 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2117
2118 }
2119
2120 else if (p_int & SCAM_SEL) {
2121
2122 FPT_scarb(p_port, LEVEL2_TAR);
2123 FPT_scsel(p_port);
2124 FPT_scasid(p_card, p_port);
2125
2126 FPT_scbusf(p_port);
2127
2128 WRW_HARPOON((p_port + hp_intstat), SCAM_SEL);
2129 }
2130
2131 return 0x00;
2132}
2133
2134/*---------------------------------------------------------------------
2135 *
2136 * Function: SccbMgrTableInit
2137 *
2138 * Description: Initialize all Sccb manager data structures.
2139 *
2140 *---------------------------------------------------------------------*/
2141
2142static void FPT_SccbMgrTableInitAll(void)
2143{
2144 unsigned char thisCard;
2145
2146 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) {
2147 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard);
2148
2149 FPT_BL_Card[thisCard].ioPort = 0x00;
2150 FPT_BL_Card[thisCard].cardInfo = NULL;
2151 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2152 FPT_BL_Card[thisCard].ourId = 0x00;
2153 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2154 }
2155}
2156
2157/*---------------------------------------------------------------------
2158 *
2159 * Function: SccbMgrTableInit
2160 *
2161 * Description: Initialize all Sccb manager data structures.
2162 *
2163 *---------------------------------------------------------------------*/
2164
2165static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
2166 unsigned char p_card)
2167{
2168 unsigned char scsiID, qtag;
2169
2170 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2171 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2172 }
2173
2174 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
2175 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2176 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2177 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2178 }
2179
2180 pCurrCard->scanIndex = 0x00;
2181 pCurrCard->currentSCCB = NULL;
2182 pCurrCard->globalFlags = 0x00;
2183 pCurrCard->cmdCounter = 0x00;
2184 pCurrCard->tagQ_Lst = 0x01;
2185 pCurrCard->discQCount = 0;
2186
2187}
2188
2189/*---------------------------------------------------------------------
2190 *
2191 * Function: SccbMgrTableInit
2192 *
2193 * Description: Initialize all Sccb manager data structures.
2194 *
2195 *---------------------------------------------------------------------*/
2196
2197static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
2198 unsigned char target)
2199{
2200
2201 unsigned char lun, qtag;
2202 struct sccb_mgr_tar_info *currTar_Info;
2203
2204 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2205
2206 currTar_Info->TarSelQ_Cnt = 0;
2207 currTar_Info->TarSyncCtrl = 0;
2208
2209 currTar_Info->TarSelQ_Head = NULL;
2210 currTar_Info->TarSelQ_Tail = NULL;
2211 currTar_Info->TarTagQ_Cnt = 0;
2212 currTar_Info->TarLUN_CA = 0;
2213
2214 for (lun = 0; lun < MAX_LUN; lun++) {
2215 currTar_Info->TarLUNBusy[lun] = 0;
2216 currTar_Info->LunDiscQ_Idx[lun] = 0;
2217 }
2218
2219 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2220 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) {
2221 if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
2222 target) {
2223 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2224 FPT_BL_Card[p_card].discQCount--;
2225 }
2226 }
2227 }
2228}
2229
2230/*---------------------------------------------------------------------
2231 *
2232 * Function: sfetm
2233 *
2234 * Description: Read in a message byte from the SCSI bus, and check
2235 * for a parity error.
2236 *
2237 *---------------------------------------------------------------------*/
2238
2239static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB)
2240{
2241 unsigned char message;
2242 unsigned short TimeOutLoop;
2243
2244 TimeOutLoop = 0;
2245 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2246 (TimeOutLoop++ < 20000)) {
2247 }
2248
2249 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2250
2251 message = RD_HARPOON(port + hp_scsidata_0);
2252
2253 WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH);
2254
2255 if (TimeOutLoop > 20000)
2256 message = 0x00; /* force message byte = 0 if Time Out on Req */
2257
2258 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
2259 (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) {
2260 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2261 WR_HARPOON(port + hp_xferstat, 0);
2262 WR_HARPOON(port + hp_fiforead, 0);
2263 WR_HARPOON(port + hp_fifowrite, 0);
2264 if (pCurrSCCB != NULL) {
2265 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2266 }
2267 message = 0x00;
2268 do {
2269 ACCEPT_MSG_ATN(port);
2270 TimeOutLoop = 0;
2271 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2272 (TimeOutLoop++ < 20000)) {
2273 }
2274 if (TimeOutLoop > 20000) {
2275 WRW_HARPOON((port + hp_intstat), PARITY);
2276 return message;
2277 }
2278 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) !=
2279 S_MSGI_PH) {
2280 WRW_HARPOON((port + hp_intstat), PARITY);
2281 return message;
2282 }
2283 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2284
2285 RD_HARPOON(port + hp_scsidata_0);
2286
2287 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2288
2289 } while (1);
2290
2291 }
2292 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2293 WR_HARPOON(port + hp_xferstat, 0);
2294 WR_HARPOON(port + hp_fiforead, 0);
2295 WR_HARPOON(port + hp_fifowrite, 0);
2296 return message;
2297}
2298
2299/*---------------------------------------------------------------------
2300 *
2301 * Function: FPT_ssel
2302 *
2303 * Description: Load up automation and select target device.
2304 *
2305 *---------------------------------------------------------------------*/
2306
2307static void FPT_ssel(u32 port, unsigned char p_card)
2308{
2309
2310 unsigned char auto_loaded, i, target, *theCCB;
2311
2312 u32 cdb_reg;
2313 struct sccb_card *CurrCard;
2314 struct sccb *currSCCB;
2315 struct sccb_mgr_tar_info *currTar_Info;
2316 unsigned char lastTag, lun;
2317
2318 CurrCard = &FPT_BL_Card[p_card];
2319 currSCCB = CurrCard->currentSCCB;
2320 target = currSCCB->TargID;
2321 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2322 lastTag = CurrCard->tagQ_Lst;
2323
2324 ARAM_ACCESS(port);
2325
2326 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2327 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2328
2329 if (((CurrCard->globalFlags & F_CONLUN_IO) &&
2330 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2331
2332 lun = currSCCB->Lun;
2333 else
2334 lun = 0;
2335
2336 if (CurrCard->globalFlags & F_TAG_STARTED) {
2337 if (!(currSCCB->ControlByte & F_USE_CMD_Q)) {
2338 if ((currTar_Info->TarLUN_CA == 0)
2339 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2340 == TAG_Q_TRYING)) {
2341
2342 if (currTar_Info->TarTagQ_Cnt != 0) {
2343 currTar_Info->TarLUNBusy[lun] = 1;
2344 FPT_queueSelectFail(CurrCard, p_card);
2345 SGRAM_ACCESS(port);
2346 return;
2347 }
2348
2349 else {
2350 currTar_Info->TarLUNBusy[lun] = 1;
2351 }
2352
2353 }
2354 /*End non-tagged */
2355 else {
2356 currTar_Info->TarLUNBusy[lun] = 1;
2357 }
2358
2359 }
2360 /*!Use cmd Q Tagged */
2361 else {
2362 if (currTar_Info->TarLUN_CA == 1) {
2363 FPT_queueSelectFail(CurrCard, p_card);
2364 SGRAM_ACCESS(port);
2365 return;
2366 }
2367
2368 currTar_Info->TarLUNBusy[lun] = 1;
2369
2370 } /*else use cmd Q tagged */
2371
2372 }
2373 /*if glob tagged started */
2374 else {
2375 currTar_Info->TarLUNBusy[lun] = 1;
2376 }
2377
2378 if ((((CurrCard->globalFlags & F_CONLUN_IO) &&
2379 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2380 || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) {
2381 if (CurrCard->discQCount >= QUEUE_DEPTH) {
2382 currTar_Info->TarLUNBusy[lun] = 1;
2383 FPT_queueSelectFail(CurrCard, p_card);
2384 SGRAM_ACCESS(port);
2385 return;
2386 }
2387 for (i = 1; i < QUEUE_DEPTH; i++) {
2388 if (++lastTag >= QUEUE_DEPTH)
2389 lastTag = 1;
2390 if (CurrCard->discQ_Tbl[lastTag] == NULL) {
2391 CurrCard->tagQ_Lst = lastTag;
2392 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2393 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2394 CurrCard->discQCount++;
2395 break;
2396 }
2397 }
2398 if (i == QUEUE_DEPTH) {
2399 currTar_Info->TarLUNBusy[lun] = 1;
2400 FPT_queueSelectFail(CurrCard, p_card);
2401 SGRAM_ACCESS(port);
2402 return;
2403 }
2404 }
2405
2406 auto_loaded = 0;
2407
2408 WR_HARPOON(port + hp_select_id, target);
2409 WR_HARPOON(port + hp_gp_reg_3, target); /* Use by new automation logic */
2410
2411 if (currSCCB->OperationCode == RESET_COMMAND) {
2412 WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2413 (currSCCB->
2414 Sccb_idmsg & ~DISC_PRIV)));
2415
2416 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
2417
2418 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2419
2420 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2421 auto_loaded = 1;
2422 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2423
2424 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2425 currTar_Info->TarSyncCtrl = 0;
2426 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2427 }
2428
2429 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2430 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2431 }
2432
2433 FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info);
2434 FPT_SccbMgrTableInitTarget(p_card, target);
2435
2436 }
2437
2438 else if (currSCCB->Sccb_scsistat == ABORT_ST) {
2439 WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2440 (currSCCB->
2441 Sccb_idmsg & ~DISC_PRIV)));
2442
2443 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
2444
2445 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT +
2446 (((unsigned
2447 char)(currSCCB->
2448 ControlByte &
2449 TAG_TYPE_MASK)
2450 >> 6) | (unsigned char)
2451 0x20)));
2452 WRW_HARPOON((port + SYNC_MSGS + 2),
2453 (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag));
2454 WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP));
2455
2456 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2457 auto_loaded = 1;
2458
2459 }
2460
2461 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2462 auto_loaded = FPT_siwidn(port, p_card);
2463 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2464 }
2465
2466 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2467 == SYNC_SUPPORTED)) {
2468 auto_loaded = FPT_sisyncn(port, p_card, 0);
2469 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2470 }
2471
2472 if (!auto_loaded) {
2473
2474 if (currSCCB->ControlByte & F_USE_CMD_Q) {
2475
2476 CurrCard->globalFlags |= F_TAG_STARTED;
2477
2478 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2479 == TAG_Q_REJECT) {
2480 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2481
2482 /* Fix up the start instruction with a jump to
2483 Non-Tag-CMD handling */
2484 WRW_HARPOON((port + ID_MSG_STRT),
2485 BRH_OP + ALWAYS + NTCMD);
2486
2487 WRW_HARPOON((port + NON_TAG_ID_MSG),
2488 (MPM_OP + AMSG_OUT +
2489 currSCCB->Sccb_idmsg));
2490
2491 WR_HARPOON(port + hp_autostart_3,
2492 (SELECT + SELCHK_STRT));
2493
2494 /* Setup our STATE so we know what happened when
2495 the wheels fall off. */
2496 currSCCB->Sccb_scsistat = SELECT_ST;
2497
2498 currTar_Info->TarLUNBusy[lun] = 1;
2499 }
2500
2501 else {
2502 WRW_HARPOON((port + ID_MSG_STRT),
2503 (MPM_OP + AMSG_OUT +
2504 currSCCB->Sccb_idmsg));
2505
2506 WRW_HARPOON((port + ID_MSG_STRT + 2),
2507 (MPM_OP + AMSG_OUT +
2508 (((unsigned char)(currSCCB->
2509 ControlByte &
2510 TAG_TYPE_MASK)
2511 >> 6) | (unsigned char)0x20)));
2512
2513 for (i = 1; i < QUEUE_DEPTH; i++) {
2514 if (++lastTag >= QUEUE_DEPTH)
2515 lastTag = 1;
2516 if (CurrCard->discQ_Tbl[lastTag] ==
2517 NULL) {
2518 WRW_HARPOON((port +
2519 ID_MSG_STRT + 6),
2520 (MPM_OP + AMSG_OUT +
2521 lastTag));
2522 CurrCard->tagQ_Lst = lastTag;
2523 currSCCB->Sccb_tag = lastTag;
2524 CurrCard->discQ_Tbl[lastTag] =
2525 currSCCB;
2526 CurrCard->discQCount++;
2527 break;
2528 }
2529 }
2530
2531 if (i == QUEUE_DEPTH) {
2532 currTar_Info->TarLUNBusy[lun] = 1;
2533 FPT_queueSelectFail(CurrCard, p_card);
2534 SGRAM_ACCESS(port);
2535 return;
2536 }
2537
2538 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2539
2540 WR_HARPOON(port + hp_autostart_3,
2541 (SELECT + SELCHK_STRT));
2542 }
2543 }
2544
2545 else {
2546
2547 WRW_HARPOON((port + ID_MSG_STRT),
2548 BRH_OP + ALWAYS + NTCMD);
2549
2550 WRW_HARPOON((port + NON_TAG_ID_MSG),
2551 (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg));
2552
2553 currSCCB->Sccb_scsistat = SELECT_ST;
2554
2555 WR_HARPOON(port + hp_autostart_3,
2556 (SELECT + SELCHK_STRT));
2557 }
2558
2559 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2560
2561 cdb_reg = port + CMD_STRT;
2562
2563 for (i = 0; i < currSCCB->CdbLength; i++) {
2564 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2565 cdb_reg += 2;
2566 theCCB++;
2567 }
2568
2569 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2570 WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
2571
2572 }
2573 /* auto_loaded */
2574 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2575 WR_HARPOON(port + hp_xferstat, 0x00);
2576
2577 WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2578
2579 WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT));
2580
2581 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) {
2582 WR_HARPOON(port + hp_scsictrl_0,
2583 (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2584 } else {
2585
2586/* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2587 auto_loaded |= AUTO_IMMED; */
2588 auto_loaded = AUTO_IMMED;
2589
2590 DISABLE_AUTO(port);
2591
2592 WR_HARPOON(port + hp_autostart_3, auto_loaded);
2593 }
2594
2595 SGRAM_ACCESS(port);
2596}
2597
2598/*---------------------------------------------------------------------
2599 *
2600 * Function: FPT_sres
2601 *
2602 * Description: Hookup the correct CCB and handle the incoming messages.
2603 *
2604 *---------------------------------------------------------------------*/
2605
2606static void FPT_sres(u32 port, unsigned char p_card,
2607 struct sccb_card *pCurrCard)
2608{
2609
2610 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2611
2612 struct sccb_mgr_tar_info *currTar_Info;
2613 struct sccb *currSCCB;
2614
2615 if (pCurrCard->currentSCCB != NULL) {
2616 currTar_Info =
2617 &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2618 DISABLE_AUTO(port);
2619
2620 WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL));
2621
2622 currSCCB = pCurrCard->currentSCCB;
2623 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
2624 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2625 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2626 }
2627 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2628 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2629 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2630 }
2631 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2632 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2633 TAG_Q_TRYING))) {
2634 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2635 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2636 pCurrCard->discQCount--;
2637 pCurrCard->discQ_Tbl[currTar_Info->
2638 LunDiscQ_Idx[currSCCB->
2639 Lun]]
2640 = NULL;
2641 }
2642 } else {
2643 currTar_Info->TarLUNBusy[0] = 0;
2644 if (currSCCB->Sccb_tag) {
2645 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2646 pCurrCard->discQCount--;
2647 pCurrCard->discQ_Tbl[currSCCB->
2648 Sccb_tag] = NULL;
2649 }
2650 } else {
2651 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2652 pCurrCard->discQCount--;
2653 pCurrCard->discQ_Tbl[currTar_Info->
2654 LunDiscQ_Idx[0]] =
2655 NULL;
2656 }
2657 }
2658 }
2659
2660 FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
2661 }
2662
2663 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2664
2665 our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4);
2666 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2667
2668 msgRetryCount = 0;
2669 do {
2670
2671 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2672 tag = 0;
2673
2674 while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2675 if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2676
2677 WRW_HARPOON((port + hp_intstat), PHASE);
2678 return;
2679 }
2680 }
2681
2682 WRW_HARPOON((port + hp_intstat), PHASE);
2683 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) {
2684
2685 message = FPT_sfm(port, pCurrCard->currentSCCB);
2686 if (message) {
2687
2688 if (message <= (0x80 | LUN_MASK)) {
2689 lun = message & (unsigned char)LUN_MASK;
2690
2691 if ((currTar_Info->
2692 TarStatus & TAR_TAG_Q_MASK) ==
2693 TAG_Q_TRYING) {
2694 if (currTar_Info->TarTagQ_Cnt !=
2695 0) {
2696
2697 if (!
2698 (currTar_Info->
2699 TarLUN_CA)) {
2700 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2701
2702 message =
2703 FPT_sfm
2704 (port,
2705 pCurrCard->
2706 currentSCCB);
2707 if (message) {
2708 ACCEPT_MSG
2709 (port);
2710 }
2711
2712 else
2713 message
2714 = 0;
2715
2716 if (message !=
2717 0) {
2718 tag =
2719 FPT_sfm
2720 (port,
2721 pCurrCard->
2722 currentSCCB);
2723
2724 if (!
2725 (tag))
2726 message
2727 =
2728 0;
2729 }
2730
2731 }
2732 /*C.A. exists! */
2733 }
2734 /*End Q cnt != 0 */
2735 }
2736 /*End Tag cmds supported! */
2737 }
2738 /*End valid ID message. */
2739 else {
2740
2741 ACCEPT_MSG_ATN(port);
2742 }
2743
2744 }
2745 /* End good id message. */
2746 else {
2747
2748 message = 0;
2749 }
2750 } else {
2751 ACCEPT_MSG_ATN(port);
2752
2753 while (!
2754 (RDW_HARPOON((port + hp_intstat)) &
2755 (PHASE | RESET))
2756 && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
2757 && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2758
2759 return;
2760 }
2761
2762 if (message == 0) {
2763 msgRetryCount++;
2764 if (msgRetryCount == 1) {
2765 FPT_SendMsg(port, SMPARITY);
2766 } else {
2767 FPT_SendMsg(port, SMDEV_RESET);
2768
2769 FPT_sssyncv(port, our_target, NARROW_SCSI,
2770 currTar_Info);
2771
2772 if (FPT_sccbMgrTbl[p_card][our_target].
2773 TarEEValue & EE_SYNC_MASK) {
2774
2775 FPT_sccbMgrTbl[p_card][our_target].
2776 TarStatus &= ~TAR_SYNC_MASK;
2777
2778 }
2779
2780 if (FPT_sccbMgrTbl[p_card][our_target].
2781 TarEEValue & EE_WIDE_SCSI) {
2782
2783 FPT_sccbMgrTbl[p_card][our_target].
2784 TarStatus &= ~TAR_WIDE_MASK;
2785 }
2786
2787 FPT_queueFlushTargSccb(p_card, our_target,
2788 SCCB_COMPLETE);
2789 FPT_SccbMgrTableInitTarget(p_card, our_target);
2790 return;
2791 }
2792 }
2793 } while (message == 0);
2794
2795 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2796 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
2797 currTar_Info->TarLUNBusy[lun] = 1;
2798 pCurrCard->currentSCCB =
2799 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
2800 if (pCurrCard->currentSCCB != NULL) {
2801 ACCEPT_MSG(port);
2802 } else {
2803 ACCEPT_MSG_ATN(port);
2804 }
2805 } else {
2806 currTar_Info->TarLUNBusy[0] = 1;
2807
2808 if (tag) {
2809 if (pCurrCard->discQ_Tbl[tag] != NULL) {
2810 pCurrCard->currentSCCB =
2811 pCurrCard->discQ_Tbl[tag];
2812 currTar_Info->TarTagQ_Cnt--;
2813 ACCEPT_MSG(port);
2814 } else {
2815 ACCEPT_MSG_ATN(port);
2816 }
2817 } else {
2818 pCurrCard->currentSCCB =
2819 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
2820 if (pCurrCard->currentSCCB != NULL) {
2821 ACCEPT_MSG(port);
2822 } else {
2823 ACCEPT_MSG_ATN(port);
2824 }
2825 }
2826 }
2827
2828 if (pCurrCard->currentSCCB != NULL) {
2829 if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) {
2830 /* During Abort Tag command, the target could have got re-selected
2831 and completed the command. Check the select Q and remove the CCB
2832 if it is in the Select Q */
2833 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
2834 }
2835 }
2836
2837 while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) &&
2838 !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) &&
2839 (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2840}
2841
2842static void FPT_SendMsg(u32 port, unsigned char message)
2843{
2844 while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2845 if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2846
2847 WRW_HARPOON((port + hp_intstat), PHASE);
2848 return;
2849 }
2850 }
2851
2852 WRW_HARPOON((port + hp_intstat), PHASE);
2853 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) {
2854 WRW_HARPOON((port + hp_intstat),
2855 (BUS_FREE | PHASE | XFER_CNT_0));
2856
2857 WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
2858
2859 WR_HARPOON(port + hp_scsidata_0, message);
2860
2861 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2862
2863 ACCEPT_MSG(port);
2864
2865 WR_HARPOON(port + hp_portctrl_0, 0x00);
2866
2867 if ((message == SMABORT) || (message == SMDEV_RESET) ||
2868 (message == SMABORT_TAG)) {
2869 while (!
2870 (RDW_HARPOON((port + hp_intstat)) &
2871 (BUS_FREE | PHASE))) {
2872 }
2873
2874 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2875 WRW_HARPOON((port + hp_intstat), BUS_FREE);
2876 }
2877 }
2878 }
2879}
2880
2881/*---------------------------------------------------------------------
2882 *
2883 * Function: FPT_sdecm
2884 *
2885 * Description: Determine the proper response to the message from the
2886 * target device.
2887 *
2888 *---------------------------------------------------------------------*/
2889static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
2890{
2891 struct sccb *currSCCB;
2892 struct sccb_card *CurrCard;
2893 struct sccb_mgr_tar_info *currTar_Info;
2894
2895 CurrCard = &FPT_BL_Card[p_card];
2896 currSCCB = CurrCard->currentSCCB;
2897
2898 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
2899
2900 if (message == SMREST_DATA_PTR) {
2901 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) {
2902 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
2903
2904 FPT_hostDataXferRestart(currSCCB);
2905 }
2906
2907 ACCEPT_MSG(port);
2908 WR_HARPOON(port + hp_autostart_1,
2909 (AUTO_IMMED + DISCONNECT_START));
2910 }
2911
2912 else if (message == SMCMD_COMP) {
2913
2914 if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
2915 currTar_Info->TarStatus &=
2916 ~(unsigned char)TAR_TAG_Q_MASK;
2917 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
2918 }
2919
2920 ACCEPT_MSG(port);
2921
2922 }
2923
2924 else if ((message == SMNO_OP) || (message >= SMIDENT)
2925 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY)) {
2926
2927 ACCEPT_MSG(port);
2928 WR_HARPOON(port + hp_autostart_1,
2929 (AUTO_IMMED + DISCONNECT_START));
2930 }
2931
2932 else if (message == SMREJECT) {
2933
2934 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
2935 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
2936 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)
2937 || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) ==
2938 TAG_Q_TRYING))
2939 {
2940 WRW_HARPOON((port + hp_intstat), BUS_FREE);
2941
2942 ACCEPT_MSG(port);
2943
2944 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2945 (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
2946 {
2947 }
2948
2949 if (currSCCB->Lun == 0x00) {
2950 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2951
2952 currTar_Info->TarStatus |=
2953 (unsigned char)SYNC_SUPPORTED;
2954
2955 currTar_Info->TarEEValue &=
2956 ~EE_SYNC_MASK;
2957 }
2958
2959 else if (currSCCB->Sccb_scsistat ==
2960 SELECT_WN_ST) {
2961
2962 currTar_Info->TarStatus =
2963 (currTar_Info->
2964 TarStatus & ~WIDE_ENABLED) |
2965 WIDE_NEGOCIATED;
2966
2967 currTar_Info->TarEEValue &=
2968 ~EE_WIDE_SCSI;
2969
2970 }
2971
2972 else if ((currTar_Info->
2973 TarStatus & TAR_TAG_Q_MASK) ==
2974 TAG_Q_TRYING) {
2975 currTar_Info->TarStatus =
2976 (currTar_Info->
2977 TarStatus & ~(unsigned char)
2978 TAR_TAG_Q_MASK) | TAG_Q_REJECT;
2979
2980 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2981 CurrCard->discQCount--;
2982 CurrCard->discQ_Tbl[currSCCB->
2983 Sccb_tag] = NULL;
2984 currSCCB->Sccb_tag = 0x00;
2985
2986 }
2987 }
2988
2989 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2990
2991 if (currSCCB->Lun == 0x00) {
2992 WRW_HARPOON((port + hp_intstat),
2993 BUS_FREE);
2994 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
2995 }
2996 }
2997
2998 else {
2999
3000 if ((CurrCard->globalFlags & F_CONLUN_IO) &&
3001 ((currTar_Info->
3002 TarStatus & TAR_TAG_Q_MASK) !=
3003 TAG_Q_TRYING))
3004 currTar_Info->TarLUNBusy[currSCCB->
3005 Lun] = 1;
3006 else
3007 currTar_Info->TarLUNBusy[0] = 1;
3008
3009 currSCCB->ControlByte &=
3010 ~(unsigned char)F_USE_CMD_Q;
3011
3012 WR_HARPOON(port + hp_autostart_1,
3013 (AUTO_IMMED + DISCONNECT_START));
3014
3015 }
3016 }
3017
3018 else {
3019 ACCEPT_MSG(port);
3020
3021 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
3022 (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
3023 {
3024 }
3025
3026 if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) {
3027 WR_HARPOON(port + hp_autostart_1,
3028 (AUTO_IMMED + DISCONNECT_START));
3029 }
3030 }
3031 }
3032
3033 else if (message == SMEXT) {
3034
3035 ACCEPT_MSG(port);
3036 FPT_shandem(port, p_card, currSCCB);
3037 }
3038
3039 else if (message == SMIGNORWR) {
3040
3041 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3042
3043 message = FPT_sfm(port, currSCCB);
3044
3045 if (currSCCB->Sccb_scsimsg != SMPARITY)
3046 ACCEPT_MSG(port);
3047 WR_HARPOON(port + hp_autostart_1,
3048 (AUTO_IMMED + DISCONNECT_START));
3049 }
3050
3051 else {
3052
3053 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3054 currSCCB->Sccb_scsimsg = SMREJECT;
3055
3056 ACCEPT_MSG_ATN(port);
3057 WR_HARPOON(port + hp_autostart_1,
3058 (AUTO_IMMED + DISCONNECT_START));
3059 }
3060}
3061
3062/*---------------------------------------------------------------------
3063 *
3064 * Function: FPT_shandem
3065 *
3066 * Description: Decide what to do with the extended message.
3067 *
3068 *---------------------------------------------------------------------*/
3069static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
3070{
3071 unsigned char length, message;
3072
3073 length = FPT_sfm(port, pCurrSCCB);
3074 if (length) {
3075
3076 ACCEPT_MSG(port);
3077 message = FPT_sfm(port, pCurrSCCB);
3078 if (message) {
3079
3080 if (message == SMSYNC) {
3081
3082 if (length == 0x03) {
3083
3084 ACCEPT_MSG(port);
3085 FPT_stsyncn(port, p_card);
3086 } else {
3087
3088 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3089 ACCEPT_MSG_ATN(port);
3090 }
3091 } else if (message == SMWDTR) {
3092
3093 if (length == 0x02) {
3094
3095 ACCEPT_MSG(port);
3096 FPT_stwidn(port, p_card);
3097 } else {
3098
3099 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3100 ACCEPT_MSG_ATN(port);
3101
3102 WR_HARPOON(port + hp_autostart_1,
3103 (AUTO_IMMED +
3104 DISCONNECT_START));
3105 }
3106 } else {
3107
3108 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3109 ACCEPT_MSG_ATN(port);
3110
3111 WR_HARPOON(port + hp_autostart_1,
3112 (AUTO_IMMED + DISCONNECT_START));
3113 }
3114 } else {
3115 if (pCurrSCCB->Sccb_scsimsg != SMPARITY)
3116 ACCEPT_MSG(port);
3117 WR_HARPOON(port + hp_autostart_1,
3118 (AUTO_IMMED + DISCONNECT_START));
3119 }
3120 } else {
3121 if (pCurrSCCB->Sccb_scsimsg == SMPARITY)
3122 WR_HARPOON(port + hp_autostart_1,
3123 (AUTO_IMMED + DISCONNECT_START));
3124 }
3125}
3126
3127/*---------------------------------------------------------------------
3128 *
3129 * Function: FPT_sisyncn
3130 *
3131 * Description: Read in a message byte from the SCSI bus, and check
3132 * for a parity error.
3133 *
3134 *---------------------------------------------------------------------*/
3135
3136static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
3137 unsigned char syncFlag)
3138{
3139 struct sccb *currSCCB;
3140 struct sccb_mgr_tar_info *currTar_Info;
3141
3142 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3143 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3144
3145 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3146
3147 WRW_HARPOON((port + ID_MSG_STRT),
3148 (MPM_OP + AMSG_OUT +
3149 (currSCCB->
3150 Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3151
3152 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3153
3154 WRW_HARPOON((port + SYNC_MSGS + 0),
3155 (MPM_OP + AMSG_OUT + SMEXT));
3156 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3157 WRW_HARPOON((port + SYNC_MSGS + 4),
3158 (MPM_OP + AMSG_OUT + SMSYNC));
3159
3160 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3161
3162 WRW_HARPOON((port + SYNC_MSGS + 6),
3163 (MPM_OP + AMSG_OUT + 12));
3164
3165 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3166 EE_SYNC_10MB)
3167
3168 WRW_HARPOON((port + SYNC_MSGS + 6),
3169 (MPM_OP + AMSG_OUT + 25));
3170
3171 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3172 EE_SYNC_5MB)
3173
3174 WRW_HARPOON((port + SYNC_MSGS + 6),
3175 (MPM_OP + AMSG_OUT + 50));
3176
3177 else
3178 WRW_HARPOON((port + SYNC_MSGS + 6),
3179 (MPM_OP + AMSG_OUT + 00));
3180
3181 WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3182 WRW_HARPOON((port + SYNC_MSGS + 10),
3183 (MPM_OP + AMSG_OUT + DEFAULT_OFFSET));
3184 WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3185
3186 if (syncFlag == 0) {
3187 WR_HARPOON(port + hp_autostart_3,
3188 (SELECT + SELCHK_STRT));
3189 currTar_Info->TarStatus =
3190 ((currTar_Info->
3191 TarStatus & ~(unsigned char)TAR_SYNC_MASK) |
3192 (unsigned char)SYNC_TRYING);
3193 } else {
3194 WR_HARPOON(port + hp_autostart_3,
3195 (AUTO_IMMED + CMD_ONLY_STRT));
3196 }
3197
3198 return 1;
3199 }
3200
3201 else {
3202
3203 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3204 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3205 return 0;
3206 }
3207}
3208
3209/*---------------------------------------------------------------------
3210 *
3211 * Function: FPT_stsyncn
3212 *
3213 * Description: The has sent us a Sync Nego message so handle it as
3214 * necessary.
3215 *
3216 *---------------------------------------------------------------------*/
3217static void FPT_stsyncn(u32 port, unsigned char p_card)
3218{
3219 unsigned char sync_msg, offset, sync_reg, our_sync_msg;
3220 struct sccb *currSCCB;
3221 struct sccb_mgr_tar_info *currTar_Info;
3222
3223 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3224 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3225
3226 sync_msg = FPT_sfm(port, currSCCB);
3227
3228 if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3229 WR_HARPOON(port + hp_autostart_1,
3230 (AUTO_IMMED + DISCONNECT_START));
3231 return;
3232 }
3233
3234 ACCEPT_MSG(port);
3235
3236 offset = FPT_sfm(port, currSCCB);
3237
3238 if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3239 WR_HARPOON(port + hp_autostart_1,
3240 (AUTO_IMMED + DISCONNECT_START));
3241 return;
3242 }
3243
3244 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3245
3246 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3247
3248 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3249
3250 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3251
3252 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3253
3254 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3255 else
3256
3257 our_sync_msg = 0; /* Message = Async */
3258
3259 if (sync_msg < our_sync_msg) {
3260 sync_msg = our_sync_msg; /*if faster, then set to max. */
3261 }
3262
3263 if (offset == ASYNC)
3264 sync_msg = ASYNC;
3265
3266 if (offset > MAX_OFFSET)
3267 offset = MAX_OFFSET;
3268
3269 sync_reg = 0x00;
3270
3271 if (sync_msg > 12)
3272
3273 sync_reg = 0x20; /* Use 10MB/s */
3274
3275 if (sync_msg > 25)
3276
3277 sync_reg = 0x40; /* Use 6.6MB/s */
3278
3279 if (sync_msg > 38)
3280
3281 sync_reg = 0x60; /* Use 5MB/s */
3282
3283 if (sync_msg > 50)
3284
3285 sync_reg = 0x80; /* Use 4MB/s */
3286
3287 if (sync_msg > 62)
3288
3289 sync_reg = 0xA0; /* Use 3.33MB/s */
3290
3291 if (sync_msg > 75)
3292
3293 sync_reg = 0xC0; /* Use 2.85MB/s */
3294
3295 if (sync_msg > 87)
3296
3297 sync_reg = 0xE0; /* Use 2.5MB/s */
3298
3299 if (sync_msg > 100) {
3300
3301 sync_reg = 0x00; /* Use ASYNC */
3302 offset = 0x00;
3303 }
3304
3305 if (currTar_Info->TarStatus & WIDE_ENABLED)
3306
3307 sync_reg |= offset;
3308
3309 else
3310
3311 sync_reg |= (offset | NARROW_SCSI);
3312
3313 FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info);
3314
3315 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3316
3317 ACCEPT_MSG(port);
3318
3319 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3320 ~(unsigned char)TAR_SYNC_MASK) |
3321 (unsigned char)SYNC_SUPPORTED);
3322
3323 WR_HARPOON(port + hp_autostart_1,
3324 (AUTO_IMMED + DISCONNECT_START));
3325 }
3326
3327 else {
3328
3329 ACCEPT_MSG_ATN(port);
3330
3331 FPT_sisyncr(port, sync_msg, offset);
3332
3333 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3334 ~(unsigned char)TAR_SYNC_MASK) |
3335 (unsigned char)SYNC_SUPPORTED);
3336 }
3337}
3338
3339/*---------------------------------------------------------------------
3340 *
3341 * Function: FPT_sisyncr
3342 *
3343 * Description: Answer the targets sync message.
3344 *
3345 *---------------------------------------------------------------------*/
3346static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
3347 unsigned char offset)
3348{
3349 ARAM_ACCESS(port);
3350 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
3351 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3352 WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMSYNC));
3353 WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse));
3354 WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3355 WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset));
3356 WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3357 SGRAM_ACCESS(port);
3358
3359 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3360 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3361
3362 WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3363
3364 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3365 }
3366}
3367
3368/*---------------------------------------------------------------------
3369 *
3370 * Function: FPT_siwidn
3371 *
3372 * Description: Read in a message byte from the SCSI bus, and check
3373 * for a parity error.
3374 *
3375 *---------------------------------------------------------------------*/
3376
3377static unsigned char FPT_siwidn(u32 port, unsigned char p_card)
3378{
3379 struct sccb *currSCCB;
3380 struct sccb_mgr_tar_info *currTar_Info;
3381
3382 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3383 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3384
3385 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3386
3387 WRW_HARPOON((port + ID_MSG_STRT),
3388 (MPM_OP + AMSG_OUT +
3389 (currSCCB->
3390 Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3391
3392 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3393
3394 WRW_HARPOON((port + SYNC_MSGS + 0),
3395 (MPM_OP + AMSG_OUT + SMEXT));
3396 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3397 WRW_HARPOON((port + SYNC_MSGS + 4),
3398 (MPM_OP + AMSG_OUT + SMWDTR));
3399 WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3400 WRW_HARPOON((port + SYNC_MSGS + 8),
3401 (MPM_OP + AMSG_OUT + SM16BIT));
3402 WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3403
3404 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
3405
3406 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3407 ~(unsigned char)TAR_WIDE_MASK) |
3408 (unsigned char)WIDE_ENABLED);
3409
3410 return 1;
3411 }
3412
3413 else {
3414
3415 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3416 ~(unsigned char)TAR_WIDE_MASK) |
3417 WIDE_NEGOCIATED);
3418
3419 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3420 return 0;
3421 }
3422}
3423
3424/*---------------------------------------------------------------------
3425 *
3426 * Function: FPT_stwidn
3427 *
3428 * Description: The has sent us a Wide Nego message so handle it as
3429 * necessary.
3430 *
3431 *---------------------------------------------------------------------*/
3432static void FPT_stwidn(u32 port, unsigned char p_card)
3433{
3434 unsigned char width;
3435 struct sccb *currSCCB;
3436 struct sccb_mgr_tar_info *currTar_Info;
3437
3438 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3439 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3440
3441 width = FPT_sfm(port, currSCCB);
3442
3443 if ((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3444 WR_HARPOON(port + hp_autostart_1,
3445 (AUTO_IMMED + DISCONNECT_START));
3446 return;
3447 }
3448
3449 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3450 width = 0;
3451
3452 if (width) {
3453 currTar_Info->TarStatus |= WIDE_ENABLED;
3454 width = 0;
3455 } else {
3456 width = NARROW_SCSI;
3457 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3458 }
3459
3460 FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info);
3461
3462 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
3463
3464 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3465
3466 if (!
3467 ((currTar_Info->TarStatus & TAR_SYNC_MASK) ==
3468 SYNC_SUPPORTED)) {
3469 ACCEPT_MSG_ATN(port);
3470 ARAM_ACCESS(port);
3471 FPT_sisyncn(port, p_card, 1);
3472 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3473 SGRAM_ACCESS(port);
3474 } else {
3475 ACCEPT_MSG(port);
3476 WR_HARPOON(port + hp_autostart_1,
3477 (AUTO_IMMED + DISCONNECT_START));
3478 }
3479 }
3480
3481 else {
3482
3483 ACCEPT_MSG_ATN(port);
3484
3485 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3486 width = SM16BIT;
3487 else
3488 width = SM8BIT;
3489
3490 FPT_siwidr(port, width);
3491
3492 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3493 }
3494}
3495
3496/*---------------------------------------------------------------------
3497 *
3498 * Function: FPT_siwidr
3499 *
3500 * Description: Answer the targets Wide nego message.
3501 *
3502 *---------------------------------------------------------------------*/
3503static void FPT_siwidr(u32 port, unsigned char width)
3504{
3505 ARAM_ACCESS(port);
3506 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
3507 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3508 WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMWDTR));
3509 WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3510 WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width));
3511 WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3512 SGRAM_ACCESS(port);
3513
3514 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3515 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3516
3517 WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3518
3519 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3520 }
3521}
3522
3523/*---------------------------------------------------------------------
3524 *
3525 * Function: FPT_sssyncv
3526 *
3527 * Description: Write the desired value to the Sync Register for the
3528 * ID specified.
3529 *
3530 *---------------------------------------------------------------------*/
3531static void FPT_sssyncv(u32 p_port, unsigned char p_id,
3532 unsigned char p_sync_value,
3533 struct sccb_mgr_tar_info *currTar_Info)
3534{
3535 unsigned char index;
3536
3537 index = p_id;
3538
3539 switch (index) {
3540
3541 case 0:
3542 index = 12; /* hp_synctarg_0 */
3543 break;
3544 case 1:
3545 index = 13; /* hp_synctarg_1 */
3546 break;
3547 case 2:
3548 index = 14; /* hp_synctarg_2 */
3549 break;
3550 case 3:
3551 index = 15; /* hp_synctarg_3 */
3552 break;
3553 case 4:
3554 index = 8; /* hp_synctarg_4 */
3555 break;
3556 case 5:
3557 index = 9; /* hp_synctarg_5 */
3558 break;
3559 case 6:
3560 index = 10; /* hp_synctarg_6 */
3561 break;
3562 case 7:
3563 index = 11; /* hp_synctarg_7 */
3564 break;
3565 case 8:
3566 index = 4; /* hp_synctarg_8 */
3567 break;
3568 case 9:
3569 index = 5; /* hp_synctarg_9 */
3570 break;
3571 case 10:
3572 index = 6; /* hp_synctarg_10 */
3573 break;
3574 case 11:
3575 index = 7; /* hp_synctarg_11 */
3576 break;
3577 case 12:
3578 index = 0; /* hp_synctarg_12 */
3579 break;
3580 case 13:
3581 index = 1; /* hp_synctarg_13 */
3582 break;
3583 case 14:
3584 index = 2; /* hp_synctarg_14 */
3585 break;
3586 case 15:
3587 index = 3; /* hp_synctarg_15 */
3588
3589 }
3590
3591 WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value);
3592
3593 currTar_Info->TarSyncCtrl = p_sync_value;
3594}
3595
3596/*---------------------------------------------------------------------
3597 *
3598 * Function: FPT_sresb
3599 *
3600 * Description: Reset the desired card's SCSI bus.
3601 *
3602 *---------------------------------------------------------------------*/
3603static void FPT_sresb(u32 port, unsigned char p_card)
3604{
3605 unsigned char scsiID, i;
3606
3607 struct sccb_mgr_tar_info *currTar_Info;
3608
3609 WR_HARPOON(port + hp_page_ctrl,
3610 (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE));
3611 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3612
3613 WR_HARPOON(port + hp_scsictrl_0, SCSI_RST);
3614
3615 scsiID = RD_HARPOON(port + hp_seltimeout);
3616 WR_HARPOON(port + hp_seltimeout, TO_5ms);
3617 WRW_HARPOON((port + hp_intstat), TIMEOUT);
3618
3619 WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO));
3620
3621 while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) {
3622 }
3623
3624 WR_HARPOON(port + hp_seltimeout, scsiID);
3625
3626 WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
3627
3628 FPT_Wait(port, TO_5ms);
3629
3630 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3631
3632 WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00));
3633
3634 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
3635 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3636
3637 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
3638 currTar_Info->TarSyncCtrl = 0;
3639 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3640 }
3641
3642 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
3643 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3644 }
3645
3646 FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
3647
3648 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3649 }
3650
3651 FPT_BL_Card[p_card].scanIndex = 0x00;
3652 FPT_BL_Card[p_card].currentSCCB = NULL;
3653 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3654 | F_NEW_SCCB_CMD);
3655 FPT_BL_Card[p_card].cmdCounter = 0x00;
3656 FPT_BL_Card[p_card].discQCount = 0x00;
3657 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3658
3659 for (i = 0; i < QUEUE_DEPTH; i++)
3660 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3661
3662 WR_HARPOON(port + hp_page_ctrl,
3663 (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE));
3664
3665}
3666
3667/*---------------------------------------------------------------------
3668 *
3669 * Function: FPT_ssenss
3670 *
3671 * Description: Setup for the Auto Sense command.
3672 *
3673 *---------------------------------------------------------------------*/
3674static void FPT_ssenss(struct sccb_card *pCurrCard)
3675{
3676 unsigned char i;
3677 struct sccb *currSCCB;
3678
3679 currSCCB = pCurrCard->currentSCCB;
3680
3681 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3682
3683 for (i = 0; i < 6; i++) {
3684
3685 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3686 }
3687
3688 currSCCB->CdbLength = SIX_BYTE_CMD;
3689 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3690 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3691 currSCCB->Cdb[2] = 0x00;
3692 currSCCB->Cdb[3] = 0x00;
3693 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3694 currSCCB->Cdb[5] = 0x00;
3695
3696 currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength;
3697
3698 currSCCB->Sccb_ATC = 0x00;
3699
3700 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3701
3702 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3703
3704 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3705
3706 currSCCB->ControlByte = 0x00;
3707
3708 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3709}
3710
3711/*---------------------------------------------------------------------
3712 *
3713 * Function: FPT_sxfrp
3714 *
3715 * Description: Transfer data into the bit bucket until the device
3716 * decides to switch phase.
3717 *
3718 *---------------------------------------------------------------------*/
3719
3720static void FPT_sxfrp(u32 p_port, unsigned char p_card)
3721{
3722 unsigned char curr_phz;
3723
3724 DISABLE_AUTO(p_port);
3725
3726 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3727
3728 FPT_hostDataXferAbort(p_port, p_card,
3729 FPT_BL_Card[p_card].currentSCCB);
3730
3731 }
3732
3733 /* If the Automation handled the end of the transfer then do not
3734 match the phase or we will get out of sync with the ISR. */
3735
3736 if (RDW_HARPOON((p_port + hp_intstat)) &
3737 (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3738 return;
3739
3740 WR_HARPOON(p_port + hp_xfercnt_0, 0x00);
3741
3742 curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3743
3744 WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0);
3745
3746 WR_HARPOON(p_port + hp_scsisig, curr_phz);
3747
3748 while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) &&
3749 (curr_phz ==
3750 (RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ)))
3751 {
3752 if (curr_phz & (unsigned char)SCSI_IOBIT) {
3753 WR_HARPOON(p_port + hp_portctrl_0,
3754 (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3755
3756 if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3757 RD_HARPOON(p_port + hp_fifodata_0);
3758 }
3759 } else {
3760 WR_HARPOON(p_port + hp_portctrl_0,
3761 (SCSI_PORT | HOST_PORT | HOST_WRT));
3762 if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) {
3763 WR_HARPOON(p_port + hp_fifodata_0, 0xFA);
3764 }
3765 }
3766 } /* End of While loop for padding data I/O phase */
3767
3768 while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3769 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ)
3770 break;
3771 }
3772
3773 WR_HARPOON(p_port + hp_portctrl_0,
3774 (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3775 while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3776 RD_HARPOON(p_port + hp_fifodata_0);
3777 }
3778
3779 if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3780 WR_HARPOON(p_port + hp_autostart_0,
3781 (AUTO_IMMED + DISCONNECT_START));
3782 while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) {
3783 }
3784
3785 if (RDW_HARPOON((p_port + hp_intstat)) &
3786 (ICMD_COMP | ITAR_DISC))
3787 while (!
3788 (RDW_HARPOON((p_port + hp_intstat)) &
3789 (BUS_FREE | RSEL))) ;
3790 }
3791}
3792
3793/*---------------------------------------------------------------------
3794 *
3795 * Function: FPT_schkdd
3796 *
3797 * Description: Make sure data has been flushed from both FIFOs and abort
3798 * the operations if necessary.
3799 *
3800 *---------------------------------------------------------------------*/
3801
3802static void FPT_schkdd(u32 port, unsigned char p_card)
3803{
3804 unsigned short TimeOutLoop;
3805 unsigned char sPhase;
3806
3807 struct sccb *currSCCB;
3808
3809 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3810
3811 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
3812 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
3813 return;
3814 }
3815
3816 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) {
3817
3818 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1);
3819
3820 currSCCB->Sccb_XferCnt = 1;
3821
3822 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
3823 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
3824 WR_HARPOON(port + hp_xferstat, 0x00);
3825 }
3826
3827 else {
3828
3829 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
3830
3831 currSCCB->Sccb_XferCnt = 0;
3832 }
3833
3834 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
3835 (currSCCB->HostStatus == SCCB_COMPLETE)) {
3836
3837 currSCCB->HostStatus = SCCB_PARITY_ERR;
3838 WRW_HARPOON((port + hp_intstat), PARITY);
3839 }
3840
3841 FPT_hostDataXferAbort(port, p_card, currSCCB);
3842
3843 while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) {
3844 }
3845
3846 TimeOutLoop = 0;
3847
3848 while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) {
3849 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
3850 return;
3851 }
3852 if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) {
3853 break;
3854 }
3855 if (RDW_HARPOON((port + hp_intstat)) & RESET) {
3856 return;
3857 }
3858 if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
3859 || (TimeOutLoop++ > 0x3000))
3860 break;
3861 }
3862
3863 sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
3864 if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) ||
3865 (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) ||
3866 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
3867 (sPhase == (SCSI_BSY | S_DATAI_PH))) {
3868
3869 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3870
3871 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) {
3872 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
3873 FPT_phaseDataIn(port, p_card);
3874 }
3875
3876 else {
3877 FPT_phaseDataOut(port, p_card);
3878 }
3879 } else {
3880 FPT_sxfrp(port, p_card);
3881 if (!(RDW_HARPOON((port + hp_intstat)) &
3882 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) {
3883 WRW_HARPOON((port + hp_intstat), AUTO_INT);
3884 FPT_phaseDecode(port, p_card);
3885 }
3886 }
3887
3888 }
3889
3890 else {
3891 WR_HARPOON(port + hp_portctrl_0, 0x00);
3892 }
3893}
3894
3895/*---------------------------------------------------------------------
3896 *
3897 * Function: FPT_sinits
3898 *
3899 * Description: Setup SCCB manager fields in this SCCB.
3900 *
3901 *---------------------------------------------------------------------*/
3902
3903static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
3904{
3905 struct sccb_mgr_tar_info *currTar_Info;
3906
3907 if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) {
3908 return;
3909 }
3910 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
3911
3912 p_sccb->Sccb_XferState = 0x00;
3913 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
3914
3915 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
3916 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
3917
3918 p_sccb->Sccb_SGoffset = 0;
3919 p_sccb->Sccb_XferState = F_SG_XFER;
3920 p_sccb->Sccb_XferCnt = 0x00;
3921 }
3922
3923 if (p_sccb->DataLength == 0x00)
3924
3925 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
3926
3927 if (p_sccb->ControlByte & F_USE_CMD_Q) {
3928 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
3929 p_sccb->ControlByte &= ~F_USE_CMD_Q;
3930
3931 else
3932 currTar_Info->TarStatus |= TAG_Q_TRYING;
3933 }
3934
3935/* For !single SCSI device in system & device allow Disconnect
3936 or command is tag_q type then send Cmd with Disconnect Enable
3937 else send Cmd with Disconnect Disable */
3938
3939/*
3940 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
3941 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
3942 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3943*/
3944 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
3945 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3946 p_sccb->Sccb_idmsg =
3947 (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
3948 }
3949
3950 else {
3951
3952 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
3953 }
3954
3955 p_sccb->HostStatus = 0x00;
3956 p_sccb->TargetStatus = 0x00;
3957 p_sccb->Sccb_tag = 0x00;
3958 p_sccb->Sccb_MGRFlags = 0x00;
3959 p_sccb->Sccb_sgseg = 0x00;
3960 p_sccb->Sccb_ATC = 0x00;
3961 p_sccb->Sccb_savedATC = 0x00;
3962/*
3963 p_sccb->SccbVirtDataPtr = 0x00;
3964 p_sccb->Sccb_forwardlink = NULL;
3965 p_sccb->Sccb_backlink = NULL;
3966 */
3967 p_sccb->Sccb_scsistat = BUS_FREE_ST;
3968 p_sccb->SccbStatus = SCCB_IN_PROCESS;
3969 p_sccb->Sccb_scsimsg = SMNO_OP;
3970
3971}
3972
3973/*---------------------------------------------------------------------
3974 *
3975 * Function: Phase Decode
3976 *
3977 * Description: Determine the phase and call the appropriate function.
3978 *
3979 *---------------------------------------------------------------------*/
3980
3981static void FPT_phaseDecode(u32 p_port, unsigned char p_card)
3982{
3983 unsigned char phase_ref;
3984 void (*phase) (u32, unsigned char);
3985
3986 DISABLE_AUTO(p_port);
3987
3988 phase_ref =
3989 (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ);
3990
3991 phase = FPT_s_PhaseTbl[phase_ref];
3992
3993 (*phase) (p_port, p_card); /* Call the correct phase func */
3994}
3995
3996/*---------------------------------------------------------------------
3997 *
3998 * Function: Data Out Phase
3999 *
4000 * Description: Start up both the BusMaster and Xbow.
4001 *
4002 *---------------------------------------------------------------------*/
4003
4004static void FPT_phaseDataOut(u32 port, unsigned char p_card)
4005{
4006
4007 struct sccb *currSCCB;
4008
4009 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4010 if (currSCCB == NULL) {
4011 return; /* Exit if No SCCB record */
4012 }
4013
4014 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4015 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4016
4017 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4018
4019 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4020
4021 WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4022
4023 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4024
4025 if (currSCCB->Sccb_XferCnt == 0) {
4026
4027 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4028 (currSCCB->HostStatus == SCCB_COMPLETE))
4029 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4030
4031 FPT_sxfrp(port, p_card);
4032 if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4033 FPT_phaseDecode(port, p_card);
4034 }
4035}
4036
4037/*---------------------------------------------------------------------
4038 *
4039 * Function: Data In Phase
4040 *
4041 * Description: Startup the BusMaster and the XBOW.
4042 *
4043 *---------------------------------------------------------------------*/
4044
4045static void FPT_phaseDataIn(u32 port, unsigned char p_card)
4046{
4047
4048 struct sccb *currSCCB;
4049
4050 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4051
4052 if (currSCCB == NULL) {
4053 return; /* Exit if No SCCB record */
4054 }
4055
4056 currSCCB->Sccb_scsistat = DATA_IN_ST;
4057 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4058 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4059
4060 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4061
4062 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4063
4064 WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4065
4066 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4067
4068 if (currSCCB->Sccb_XferCnt == 0) {
4069
4070 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4071 (currSCCB->HostStatus == SCCB_COMPLETE))
4072 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4073
4074 FPT_sxfrp(port, p_card);
4075 if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4076 FPT_phaseDecode(port, p_card);
4077
4078 }
4079}
4080
4081/*---------------------------------------------------------------------
4082 *
4083 * Function: Command Phase
4084 *
4085 * Description: Load the CDB into the automation and start it up.
4086 *
4087 *---------------------------------------------------------------------*/
4088
4089static void FPT_phaseCommand(u32 p_port, unsigned char p_card)
4090{
4091 struct sccb *currSCCB;
4092 u32 cdb_reg;
4093 unsigned char i;
4094
4095 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4096
4097 if (currSCCB->OperationCode == RESET_COMMAND) {
4098
4099 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4100 currSCCB->CdbLength = SIX_BYTE_CMD;
4101 }
4102
4103 WR_HARPOON(p_port + hp_scsisig, 0x00);
4104
4105 ARAM_ACCESS(p_port);
4106
4107 cdb_reg = p_port + CMD_STRT;
4108
4109 for (i = 0; i < currSCCB->CdbLength; i++) {
4110
4111 if (currSCCB->OperationCode == RESET_COMMAND)
4112
4113 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4114
4115 else
4116 WRW_HARPOON(cdb_reg,
4117 (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4118 cdb_reg += 2;
4119 }
4120
4121 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4122 WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
4123
4124 WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT));
4125
4126 currSCCB->Sccb_scsistat = COMMAND_ST;
4127
4128 WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4129 SGRAM_ACCESS(p_port);
4130}
4131
4132/*---------------------------------------------------------------------
4133 *
4134 * Function: Status phase
4135 *
4136 * Description: Bring in the status and command complete message bytes
4137 *
4138 *---------------------------------------------------------------------*/
4139
4140static void FPT_phaseStatus(u32 port, unsigned char p_card)
4141{
4142 /* Start-up the automation to finish off this command and let the
4143 isr handle the interrupt for command complete when it comes in.
4144 We could wait here for the interrupt to be generated?
4145 */
4146
4147 WR_HARPOON(port + hp_scsisig, 0x00);
4148
4149 WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START));
4150}
4151
4152/*---------------------------------------------------------------------
4153 *
4154 * Function: Phase Message Out
4155 *
4156 * Description: Send out our message (if we have one) and handle whatever
4157 * else is involed.
4158 *
4159 *---------------------------------------------------------------------*/
4160
4161static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
4162{
4163 unsigned char message, scsiID;
4164 struct sccb *currSCCB;
4165 struct sccb_mgr_tar_info *currTar_Info;
4166
4167 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4168
4169 if (currSCCB != NULL) {
4170
4171 message = currSCCB->Sccb_scsimsg;
4172 scsiID = currSCCB->TargID;
4173
4174 if (message == SMDEV_RESET) {
4175
4176 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4177 currTar_Info->TarSyncCtrl = 0;
4178 FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
4179
4180 if (FPT_sccbMgrTbl[p_card][scsiID].
4181 TarEEValue & EE_SYNC_MASK) {
4182
4183 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4184 ~TAR_SYNC_MASK;
4185
4186 }
4187
4188 if (FPT_sccbMgrTbl[p_card][scsiID].
4189 TarEEValue & EE_WIDE_SCSI) {
4190
4191 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4192 ~TAR_WIDE_MASK;
4193 }
4194
4195 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4196 FPT_SccbMgrTableInitTarget(p_card, scsiID);
4197 } else if (currSCCB->Sccb_scsistat == ABORT_ST) {
4198 currSCCB->HostStatus = SCCB_COMPLETE;
4199 if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] !=
4200 NULL) {
4201 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4202 Sccb_tag] = NULL;
4203 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4204 }
4205
4206 }
4207
4208 else if (currSCCB->Sccb_scsistat < COMMAND_ST) {
4209
4210 if (message == SMNO_OP) {
4211 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4212
4213 FPT_ssel(port, p_card);
4214 return;
4215 }
4216 } else {
4217
4218 if (message == SMABORT)
4219
4220 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4221 }
4222
4223 } else {
4224 message = SMABORT;
4225 }
4226
4227 WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4228
4229 WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
4230
4231 WR_HARPOON(port + hp_scsidata_0, message);
4232
4233 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
4234
4235 ACCEPT_MSG(port);
4236
4237 WR_HARPOON(port + hp_portctrl_0, 0x00);
4238
4239 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4240 (message == SMABORT_TAG)) {
4241
4242 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) {
4243 }
4244
4245 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
4246 WRW_HARPOON((port + hp_intstat), BUS_FREE);
4247
4248 if (currSCCB != NULL) {
4249
4250 if ((FPT_BL_Card[p_card].
4251 globalFlags & F_CONLUN_IO)
4252 &&
4253 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4254 TarStatus & TAR_TAG_Q_MASK) !=
4255 TAG_Q_TRYING))
4256 FPT_sccbMgrTbl[p_card][currSCCB->
4257 TargID].
4258 TarLUNBusy[currSCCB->Lun] = 0;
4259 else
4260 FPT_sccbMgrTbl[p_card][currSCCB->
4261 TargID].
4262 TarLUNBusy[0] = 0;
4263
4264 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
4265 currSCCB, p_card);
4266 }
4267
4268 else {
4269 FPT_BL_Card[p_card].globalFlags |=
4270 F_NEW_SCCB_CMD;
4271 }
4272 }
4273
4274 else {
4275
4276 FPT_sxfrp(port, p_card);
4277 }
4278 }
4279
4280 else {
4281
4282 if (message == SMPARITY) {
4283 currSCCB->Sccb_scsimsg = SMNO_OP;
4284 WR_HARPOON(port + hp_autostart_1,
4285 (AUTO_IMMED + DISCONNECT_START));
4286 } else {
4287 FPT_sxfrp(port, p_card);
4288 }
4289 }
4290}
4291
4292/*---------------------------------------------------------------------
4293 *
4294 * Function: Message In phase
4295 *
4296 * Description: Bring in the message and determine what to do with it.
4297 *
4298 *---------------------------------------------------------------------*/
4299
4300static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
4301{
4302 unsigned char message;
4303 struct sccb *currSCCB;
4304
4305 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4306
4307 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
4308
4309 FPT_phaseChkFifo(port, p_card);
4310 }
4311
4312 message = RD_HARPOON(port + hp_scsidata_0);
4313 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR)) {
4314
4315 WR_HARPOON(port + hp_autostart_1,
4316 (AUTO_IMMED + END_DATA_START));
4317
4318 }
4319
4320 else {
4321
4322 message = FPT_sfm(port, currSCCB);
4323 if (message) {
4324
4325 FPT_sdecm(message, port, p_card);
4326
4327 } else {
4328 if (currSCCB->Sccb_scsimsg != SMPARITY)
4329 ACCEPT_MSG(port);
4330 WR_HARPOON(port + hp_autostart_1,
4331 (AUTO_IMMED + DISCONNECT_START));
4332 }
4333 }
4334
4335}
4336
4337/*---------------------------------------------------------------------
4338 *
4339 * Function: Illegal phase
4340 *
4341 * Description: Target switched to some illegal phase, so all we can do
4342 * is report an error back to the host (if that is possible)
4343 * and send an ABORT message to the misbehaving target.
4344 *
4345 *---------------------------------------------------------------------*/
4346
4347static void FPT_phaseIllegal(u32 port, unsigned char p_card)
4348{
4349 struct sccb *currSCCB;
4350
4351 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4352
4353 WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig));
4354 if (currSCCB != NULL) {
4355
4356 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4357 currSCCB->Sccb_scsistat = ABORT_ST;
4358 currSCCB->Sccb_scsimsg = SMABORT;
4359 }
4360
4361 ACCEPT_MSG_ATN(port);
4362}
4363
4364/*---------------------------------------------------------------------
4365 *
4366 * Function: Phase Check FIFO
4367 *
4368 * Description: Make sure data has been flushed from both FIFOs and abort
4369 * the operations if necessary.
4370 *
4371 *---------------------------------------------------------------------*/
4372
4373static void FPT_phaseChkFifo(u32 port, unsigned char p_card)
4374{
4375 u32 xfercnt;
4376 struct sccb *currSCCB;
4377
4378 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4379
4380 if (currSCCB->Sccb_scsistat == DATA_IN_ST) {
4381
4382 while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) &&
4383 (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) {
4384 }
4385
4386 if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) {
4387 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4388
4389 currSCCB->Sccb_XferCnt = 0;
4390
4391 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4392 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4393 currSCCB->HostStatus = SCCB_PARITY_ERR;
4394 WRW_HARPOON((port + hp_intstat), PARITY);
4395 }
4396
4397 FPT_hostDataXferAbort(port, p_card, currSCCB);
4398
4399 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4400
4401 while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY))
4402 && (RD_HARPOON(port + hp_ext_status) &
4403 BM_CMD_BUSY)) {
4404 }
4405
4406 }
4407 }
4408
4409 /*End Data In specific code. */
4410 GET_XFER_CNT(port, xfercnt);
4411
4412 WR_HARPOON(port + hp_xfercnt_0, 0x00);
4413
4414 WR_HARPOON(port + hp_portctrl_0, 0x00);
4415
4416 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4417
4418 currSCCB->Sccb_XferCnt = xfercnt;
4419
4420 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4421 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4422
4423 currSCCB->HostStatus = SCCB_PARITY_ERR;
4424 WRW_HARPOON((port + hp_intstat), PARITY);
4425 }
4426
4427 FPT_hostDataXferAbort(port, p_card, currSCCB);
4428
4429 WR_HARPOON(port + hp_fifowrite, 0x00);
4430 WR_HARPOON(port + hp_fiforead, 0x00);
4431 WR_HARPOON(port + hp_xferstat, 0x00);
4432
4433 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4434}
4435
4436/*---------------------------------------------------------------------
4437 *
4438 * Function: Phase Bus Free
4439 *
4440 * Description: We just went bus free so figure out if it was
4441 * because of command complete or from a disconnect.
4442 *
4443 *---------------------------------------------------------------------*/
4444static void FPT_phaseBusFree(u32 port, unsigned char p_card)
4445{
4446 struct sccb *currSCCB;
4447
4448 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4449
4450 if (currSCCB != NULL) {
4451
4452 DISABLE_AUTO(port);
4453
4454 if (currSCCB->OperationCode == RESET_COMMAND) {
4455
4456 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4457 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4458 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4459 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4460 TarLUNBusy[currSCCB->Lun] = 0;
4461 else
4462 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4463 TarLUNBusy[0] = 0;
4464
4465 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4466 p_card);
4467
4468 FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card);
4469
4470 }
4471
4472 else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4473 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4474 (unsigned char)SYNC_SUPPORTED;
4475 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4476 ~EE_SYNC_MASK;
4477 }
4478
4479 else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4480 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4481 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4482 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4483
4484 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4485 ~EE_WIDE_SCSI;
4486 }
4487
4488 else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
4489 /* Make sure this is not a phony BUS_FREE. If we were
4490 reselected or if BUSY is NOT on then this is a
4491 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4492
4493 if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ||
4494 (RDW_HARPOON((port + hp_intstat)) & RSEL)) {
4495 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4496 TarStatus &= ~TAR_TAG_Q_MASK;
4497 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4498 TarStatus |= TAG_Q_REJECT;
4499 }
4500
4501 else {
4502 return;
4503 }
4504 }
4505
4506 else {
4507
4508 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4509
4510 if (!currSCCB->HostStatus) {
4511 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4512 }
4513
4514 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4515 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4516 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4517 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4518 TarLUNBusy[currSCCB->Lun] = 0;
4519 else
4520 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4521 TarLUNBusy[0] = 0;
4522
4523 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4524 p_card);
4525 return;
4526 }
4527
4528 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4529
4530 } /*end if !=null */
4531}
4532
4533/*---------------------------------------------------------------------
4534 *
4535 * Function: Auto Load Default Map
4536 *
4537 * Description: Load the Automation RAM with the defualt map values.
4538 *
4539 *---------------------------------------------------------------------*/
4540static void FPT_autoLoadDefaultMap(u32 p_port)
4541{
4542 u32 map_addr;
4543
4544 ARAM_ACCESS(p_port);
4545 map_addr = p_port + hp_aramBase;
4546
4547 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0)); /*ID MESSAGE */
4548 map_addr += 2;
4549 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20)); /*SIMPLE TAG QUEUEING MSG */
4550 map_addr += 2;
4551 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4552 map_addr += 2;
4553 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00)); /*TAG ID MSG */
4554 map_addr += 2;
4555 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 0 */
4556 map_addr += 2;
4557 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 1 */
4558 map_addr += 2;
4559 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 2 */
4560 map_addr += 2;
4561 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 3 */
4562 map_addr += 2;
4563 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 4 */
4564 map_addr += 2;
4565 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 5 */
4566 map_addr += 2;
4567 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 6 */
4568 map_addr += 2;
4569 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 7 */
4570 map_addr += 2;
4571 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 8 */
4572 map_addr += 2;
4573 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 9 */
4574 map_addr += 2;
4575 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 10 */
4576 map_addr += 2;
4577 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 11 */
4578 map_addr += 2;
4579 WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT)); /*JUMP IF DATA OUT */
4580 map_addr += 2;
4581 WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI)); /*JUMP IF NO DATA IN FIFO */
4582 map_addr += 2; /*This means AYNC DATA IN */
4583 WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4584 map_addr += 2;
4585 WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT)); /*JUMP IF NOT DATA IN PHZ */
4586 map_addr += 2;
4587 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4588 map_addr += 2;
4589 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02)); /*SAVE DATA PTR MSG? */
4590 map_addr += 2;
4591 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC)); /*GO CHECK FOR DISCONNECT MSG */
4592 map_addr += 2;
4593 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1)); /*SAVE DATA PTRS MSG */
4594 map_addr += 2;
4595 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK DATA IN */
4596 map_addr += 2;
4597 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04)); /*DISCONNECT MSG? */
4598 map_addr += 2;
4599 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN)); /*UKNKNOWN MSG */
4600 map_addr += 2;
4601 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*XFER DISCONNECT MSG */
4602 map_addr += 2;
4603 WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC)); /*STOP AND INTERRUPT */
4604 map_addr += 2;
4605 WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN)); /*JUMP IF NOT STATUS PHZ. */
4606 map_addr += 2;
4607 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0)); /*GET STATUS BYTE */
4608 map_addr += 2;
4609 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC)); /*ERROR IF NOT MSG IN PHZ */
4610 map_addr += 2;
4611 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4612 map_addr += 2;
4613 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4614 map_addr += 2;
4615 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*GET CMD COMPLETE MSG */
4616 map_addr += 2;
4617 WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP)); /*END OF COMMAND */
4618 map_addr += 2;
4619
4620 WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4621 map_addr += 2;
4622 WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4623 map_addr += 2;
4624 WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4625 map_addr += 2;
4626 WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4627 map_addr += 2; /* DIDN'T GET ONE */
4628 WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG)); /* comp SCSI SEL ID & AR3 */
4629 map_addr += 2;
4630 WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00)); /*SEL ID OK then Conti. */
4631 map_addr += 2;
4632 WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4633
4634 SGRAM_ACCESS(p_port);
4635}
4636
4637/*---------------------------------------------------------------------
4638 *
4639 * Function: Auto Command Complete
4640 *
4641 * Description: Post command back to host and find another command
4642 * to execute.
4643 *
4644 *---------------------------------------------------------------------*/
4645
4646static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
4647{
4648 struct sccb *currSCCB;
4649 unsigned char status_byte;
4650
4651 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4652
4653 status_byte = RD_HARPOON(p_port + hp_gp_reg_0);
4654
4655 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4656
4657 if (status_byte != SSGOOD) {
4658
4659 if (status_byte == SSQ_FULL) {
4660
4661 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4662 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4663 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4664 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4665 TarLUNBusy[currSCCB->Lun] = 1;
4666 if (FPT_BL_Card[p_card].discQCount != 0)
4667 FPT_BL_Card[p_card].discQCount--;
4668 FPT_BL_Card[p_card].
4669 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4670 [currSCCB->TargID].
4671 LunDiscQ_Idx[currSCCB->Lun]] =
4672 NULL;
4673 } else {
4674 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4675 TarLUNBusy[0] = 1;
4676 if (currSCCB->Sccb_tag) {
4677 if (FPT_BL_Card[p_card].discQCount != 0)
4678 FPT_BL_Card[p_card].
4679 discQCount--;
4680 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4681 Sccb_tag]
4682 = NULL;
4683 } else {
4684 if (FPT_BL_Card[p_card].discQCount != 0)
4685 FPT_BL_Card[p_card].
4686 discQCount--;
4687 FPT_BL_Card[p_card].
4688 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4689 [currSCCB->TargID].
4690 LunDiscQ_Idx[0]] = NULL;
4691 }
4692 }
4693
4694 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4695
4696 FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
4697
4698 return;
4699 }
4700
4701 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4702 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4703 (unsigned char)SYNC_SUPPORTED;
4704
4705 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4706 ~EE_SYNC_MASK;
4707 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4708
4709 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4710 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4711 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4712 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4713 TarLUNBusy[currSCCB->Lun] = 1;
4714 if (FPT_BL_Card[p_card].discQCount != 0)
4715 FPT_BL_Card[p_card].discQCount--;
4716 FPT_BL_Card[p_card].
4717 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4718 [currSCCB->TargID].
4719 LunDiscQ_Idx[currSCCB->Lun]] =
4720 NULL;
4721 } else {
4722 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4723 TarLUNBusy[0] = 1;
4724 if (currSCCB->Sccb_tag) {
4725 if (FPT_BL_Card[p_card].discQCount != 0)
4726 FPT_BL_Card[p_card].
4727 discQCount--;
4728 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4729 Sccb_tag]
4730 = NULL;
4731 } else {
4732 if (FPT_BL_Card[p_card].discQCount != 0)
4733 FPT_BL_Card[p_card].
4734 discQCount--;
4735 FPT_BL_Card[p_card].
4736 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4737 [currSCCB->TargID].
4738 LunDiscQ_Idx[0]] = NULL;
4739 }
4740 }
4741 return;
4742
4743 }
4744
4745 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4746
4747 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4748 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4749 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4750
4751 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4752 ~EE_WIDE_SCSI;
4753 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4754
4755 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4756 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4757 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4758 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4759 TarLUNBusy[currSCCB->Lun] = 1;
4760 if (FPT_BL_Card[p_card].discQCount != 0)
4761 FPT_BL_Card[p_card].discQCount--;
4762 FPT_BL_Card[p_card].
4763 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4764 [currSCCB->TargID].
4765 LunDiscQ_Idx[currSCCB->Lun]] =
4766 NULL;
4767 } else {
4768 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4769 TarLUNBusy[0] = 1;
4770 if (currSCCB->Sccb_tag) {
4771 if (FPT_BL_Card[p_card].discQCount != 0)
4772 FPT_BL_Card[p_card].
4773 discQCount--;
4774 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4775 Sccb_tag]
4776 = NULL;
4777 } else {
4778 if (FPT_BL_Card[p_card].discQCount != 0)
4779 FPT_BL_Card[p_card].
4780 discQCount--;
4781 FPT_BL_Card[p_card].
4782 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4783 [currSCCB->TargID].
4784 LunDiscQ_Idx[0]] = NULL;
4785 }
4786 }
4787 return;
4788
4789 }
4790
4791 if (status_byte == SSCHECK) {
4792 if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) {
4793 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4794 TarEEValue & EE_SYNC_MASK) {
4795 FPT_sccbMgrTbl[p_card][currSCCB->
4796 TargID].
4797 TarStatus &= ~TAR_SYNC_MASK;
4798 }
4799 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4800 TarEEValue & EE_WIDE_SCSI) {
4801 FPT_sccbMgrTbl[p_card][currSCCB->
4802 TargID].
4803 TarStatus &= ~TAR_WIDE_MASK;
4804 }
4805 }
4806 }
4807
4808 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
4809
4810 currSCCB->SccbStatus = SCCB_ERROR;
4811 currSCCB->TargetStatus = status_byte;
4812
4813 if (status_byte == SSCHECK) {
4814
4815 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4816 TarLUN_CA = 1;
4817
4818 if (currSCCB->RequestSenseLength !=
4819 NO_AUTO_REQUEST_SENSE) {
4820
4821 if (currSCCB->RequestSenseLength == 0)
4822 currSCCB->RequestSenseLength =
4823 14;
4824
4825 FPT_ssenss(&FPT_BL_Card[p_card]);
4826 FPT_BL_Card[p_card].globalFlags |=
4827 F_NEW_SCCB_CMD;
4828
4829 if (((FPT_BL_Card[p_card].
4830 globalFlags & F_CONLUN_IO)
4831 &&
4832 ((FPT_sccbMgrTbl[p_card]
4833 [currSCCB->TargID].
4834 TarStatus & TAR_TAG_Q_MASK) !=
4835 TAG_Q_TRYING))) {
4836 FPT_sccbMgrTbl[p_card]
4837 [currSCCB->TargID].
4838 TarLUNBusy[currSCCB->Lun] =
4839 1;
4840 if (FPT_BL_Card[p_card].
4841 discQCount != 0)
4842 FPT_BL_Card[p_card].
4843 discQCount--;
4844 FPT_BL_Card[p_card].
4845 discQ_Tbl[FPT_sccbMgrTbl
4846 [p_card]
4847 [currSCCB->
4848 TargID].
4849 LunDiscQ_Idx
4850 [currSCCB->Lun]] =
4851 NULL;
4852 } else {
4853 FPT_sccbMgrTbl[p_card]
4854 [currSCCB->TargID].
4855 TarLUNBusy[0] = 1;
4856 if (currSCCB->Sccb_tag) {
4857 if (FPT_BL_Card[p_card].
4858 discQCount != 0)
4859 FPT_BL_Card
4860 [p_card].
4861 discQCount--;
4862 FPT_BL_Card[p_card].
4863 discQ_Tbl[currSCCB->
4864 Sccb_tag]
4865 = NULL;
4866 } else {
4867 if (FPT_BL_Card[p_card].
4868 discQCount != 0)
4869 FPT_BL_Card
4870 [p_card].
4871 discQCount--;
4872 FPT_BL_Card[p_card].
4873 discQ_Tbl
4874 [FPT_sccbMgrTbl
4875 [p_card][currSCCB->
4876 TargID].
4877 LunDiscQ_Idx[0]] =
4878 NULL;
4879 }
4880 }
4881 return;
4882 }
4883 }
4884 }
4885 }
4886
4887 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4888 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4889 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4890 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->
4891 Lun] = 0;
4892 else
4893 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4894
4895 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4896}
4897
4898#define SHORT_WAIT 0x0000000F
4899#define LONG_WAIT 0x0000FFFFL
4900
4901/*---------------------------------------------------------------------
4902 *
4903 * Function: Data Transfer Processor
4904 *
4905 * Description: This routine performs two tasks.
4906 * (1) Start data transfer by calling HOST_DATA_XFER_START
4907 * function. Once data transfer is started, (2) Depends
4908 * on the type of data transfer mode Scatter/Gather mode
4909 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
4910 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
4911 * data transfer done. In Scatter/Gather mode, this routine
4912 * checks bus master command complete and dual rank busy
4913 * bit to keep chaining SC transfer command. Similarly,
4914 * in Scatter/Gather mode, it checks Sccb_MGRFlag
4915 * (F_HOST_XFER_ACT bit) for data transfer done.
4916 *
4917 *---------------------------------------------------------------------*/
4918
4919static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard)
4920{
4921 struct sccb *currSCCB;
4922
4923 currSCCB = pCurrCard->currentSCCB;
4924
4925 if (currSCCB->Sccb_XferState & F_SG_XFER) {
4926 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
4927 {
4928 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
4929 currSCCB->Sccb_SGoffset = 0x00;
4930 }
4931 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4932
4933 FPT_busMstrSGDataXferStart(port, currSCCB);
4934 }
4935
4936 else {
4937 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) {
4938 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4939
4940 FPT_busMstrDataXferStart(port, currSCCB);
4941 }
4942 }
4943}
4944
4945/*---------------------------------------------------------------------
4946 *
4947 * Function: BusMaster Scatter Gather Data Transfer Start
4948 *
4949 * Description:
4950 *
4951 *---------------------------------------------------------------------*/
4952static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
4953{
4954 u32 count, addr, tmpSGCnt;
4955 unsigned int sg_index;
4956 unsigned char sg_count, i;
4957 u32 reg_offset;
4958 struct blogic_sg_seg *segp;
4959
4960 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)
4961 count = ((u32)HOST_RD_CMD) << 24;
4962 else
4963 count = ((u32)HOST_WRT_CMD) << 24;
4964
4965 sg_count = 0;
4966 tmpSGCnt = 0;
4967 sg_index = pcurrSCCB->Sccb_sgseg;
4968 reg_offset = hp_aramBase;
4969
4970 i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
4971 ~(SGRAM_ARAM | SCATTER_EN));
4972
4973 WR_HARPOON(p_port + hp_page_ctrl, i);
4974
4975 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
4976 ((sg_index * (unsigned int)SG_ELEMENT_SIZE) <
4977 pcurrSCCB->DataLength)) {
4978
4979 segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) +
4980 sg_index;
4981 tmpSGCnt += segp->segbytes;
4982 count |= segp->segbytes;
4983 addr = segp->segdata;
4984
4985 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
4986 addr +=
4987 ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
4988 count =
4989 (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
4990 tmpSGCnt = count & 0x00FFFFFFL;
4991 }
4992
4993 WR_HARP32(p_port, reg_offset, addr);
4994 reg_offset += 4;
4995
4996 WR_HARP32(p_port, reg_offset, count);
4997 reg_offset += 4;
4998
4999 count &= 0xFF000000L;
5000 sg_index++;
5001 sg_count++;
5002
5003 } /*End While */
5004
5005 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5006
5007 WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4));
5008
5009 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5010
5011 WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
5012
5013 WR_HARPOON(p_port + hp_portctrl_0,
5014 (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5015 WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5016 }
5017
5018 else {
5019
5020 if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) &&
5021 (tmpSGCnt & 0x000000001)) {
5022
5023 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5024 tmpSGCnt--;
5025 }
5026
5027 WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
5028
5029 WR_HARPOON(p_port + hp_portctrl_0,
5030 (SCSI_PORT | DMA_PORT | DMA_RD));
5031 WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5032 }
5033
5034 WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN));
5035
5036}
5037
5038/*---------------------------------------------------------------------
5039 *
5040 * Function: BusMaster Data Transfer Start
5041 *
5042 * Description:
5043 *
5044 *---------------------------------------------------------------------*/
5045static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
5046{
5047 u32 addr, count;
5048
5049 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5050
5051 count = pcurrSCCB->Sccb_XferCnt;
5052
5053 addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5054 }
5055
5056 else {
5057 addr = pcurrSCCB->SensePointer;
5058 count = pcurrSCCB->RequestSenseLength;
5059
5060 }
5061
5062 HP_SETUP_ADDR_CNT(p_port, addr, count);
5063
5064 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5065
5066 WR_HARPOON(p_port + hp_portctrl_0,
5067 (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5068 WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5069
5070 WR_HARPOON(p_port + hp_xfer_cmd,
5071 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5072 }
5073
5074 else {
5075
5076 WR_HARPOON(p_port + hp_portctrl_0,
5077 (SCSI_PORT | DMA_PORT | DMA_RD));
5078 WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5079
5080 WR_HARPOON(p_port + hp_xfer_cmd,
5081 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5082
5083 }
5084}
5085
5086/*---------------------------------------------------------------------
5087 *
5088 * Function: BusMaster Timeout Handler
5089 *
5090 * Description: This function is called after a bus master command busy time
5091 * out is detected. This routines issue halt state machine
5092 * with a software time out for command busy. If command busy
5093 * is still asserted at the end of the time out, it issues
5094 * hard abort with another software time out. It hard abort
5095 * command busy is also time out, it'll just give up.
5096 *
5097 *---------------------------------------------------------------------*/
5098static unsigned char FPT_busMstrTimeOut(u32 p_port)
5099{
5100 unsigned long timeout;
5101
5102 timeout = LONG_WAIT;
5103
5104 WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH);
5105
5106 while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED))
5107 && timeout--) {
5108 }
5109
5110 if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5111 WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT);
5112
5113 timeout = LONG_WAIT;
5114 while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY)
5115 && timeout--) {
5116 }
5117 }
5118
5119 RD_HARPOON(p_port + hp_int_status); /*Clear command complete */
5120
5121 if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5122 return 1;
5123 }
5124
5125 else {
5126 return 0;
5127 }
5128}
5129
5130/*---------------------------------------------------------------------
5131 *
5132 * Function: Host Data Transfer Abort
5133 *
5134 * Description: Abort any in progress transfer.
5135 *
5136 *---------------------------------------------------------------------*/
5137static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
5138 struct sccb *pCurrSCCB)
5139{
5140
5141 unsigned long timeout;
5142 unsigned long remain_cnt;
5143 u32 sg_ptr;
5144 struct blogic_sg_seg *segp;
5145
5146 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5147
5148 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5149
5150 if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) {
5151
5152 WR_HARPOON(port + hp_bm_ctrl,
5153 (RD_HARPOON(port + hp_bm_ctrl) |
5154 FLUSH_XFER_CNTR));
5155 timeout = LONG_WAIT;
5156
5157 while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5158 && timeout--) {
5159 }
5160
5161 WR_HARPOON(port + hp_bm_ctrl,
5162 (RD_HARPOON(port + hp_bm_ctrl) &
5163 ~FLUSH_XFER_CNTR));
5164
5165 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5166
5167 if (FPT_busMstrTimeOut(port)) {
5168
5169 if (pCurrSCCB->HostStatus == 0x00)
5170
5171 pCurrSCCB->HostStatus =
5172 SCCB_BM_ERR;
5173
5174 }
5175
5176 if (RD_HARPOON(port + hp_int_status) &
5177 INT_EXT_STATUS)
5178
5179 if (RD_HARPOON(port + hp_ext_status) &
5180 BAD_EXT_STATUS)
5181
5182 if (pCurrSCCB->HostStatus ==
5183 0x00)
5184 {
5185 pCurrSCCB->HostStatus =
5186 SCCB_BM_ERR;
5187 }
5188 }
5189 }
5190 }
5191
5192 else if (pCurrSCCB->Sccb_XferCnt) {
5193
5194 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5195
5196 WR_HARPOON(port + hp_page_ctrl,
5197 (RD_HARPOON(port + hp_page_ctrl) &
5198 ~SCATTER_EN));
5199
5200 WR_HARPOON(port + hp_sg_addr, 0x00);
5201
5202 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5203
5204 if (sg_ptr >
5205 (unsigned int)(pCurrSCCB->DataLength /
5206 SG_ELEMENT_SIZE)) {
5207
5208 sg_ptr = (u32)(pCurrSCCB->DataLength /
5209 SG_ELEMENT_SIZE);
5210 }
5211
5212 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5213
5214 while (remain_cnt < 0x01000000L) {
5215
5216 sg_ptr--;
5217 segp = (struct blogic_sg_seg *)(pCurrSCCB->
5218 DataPointer) + (sg_ptr * 2);
5219 if (remain_cnt > (unsigned long)segp->segbytes)
5220 remain_cnt -=
5221 (unsigned long)segp->segbytes;
5222 else
5223 break;
5224 }
5225
5226 if (remain_cnt < 0x01000000L) {
5227
5228 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5229
5230 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5231
5232 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) ==
5233 pCurrSCCB->DataLength && (remain_cnt == 0))
5234
5235 pCurrSCCB->Sccb_XferState |=
5236 F_ALL_XFERRED;
5237 }
5238
5239 else {
5240
5241 if (pCurrSCCB->HostStatus == 0x00) {
5242
5243 pCurrSCCB->HostStatus =
5244 SCCB_GROSS_FW_ERR;
5245 }
5246 }
5247 }
5248
5249 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5250
5251 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5252
5253 FPT_busMstrTimeOut(port);
5254 }
5255
5256 else {
5257
5258 if (RD_HARPOON(port + hp_int_status) &
5259 INT_EXT_STATUS) {
5260
5261 if (RD_HARPOON(port + hp_ext_status) &
5262 BAD_EXT_STATUS) {
5263
5264 if (pCurrSCCB->HostStatus ==
5265 0x00) {
5266
5267 pCurrSCCB->HostStatus =
5268 SCCB_BM_ERR;
5269 }
5270 }
5271 }
5272
5273 }
5274 }
5275
5276 else {
5277
5278 if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) {
5279
5280 timeout = SHORT_WAIT;
5281
5282 while ((RD_HARPOON(port + hp_ext_status) &
5283 BM_CMD_BUSY)
5284 && ((RD_HARPOON(port + hp_fifo_cnt)) >=
5285 BM_THRESHOLD) && timeout--) {
5286 }
5287 }
5288
5289 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5290
5291 WR_HARPOON(port + hp_bm_ctrl,
5292 (RD_HARPOON(port + hp_bm_ctrl) |
5293 FLUSH_XFER_CNTR));
5294
5295 timeout = LONG_WAIT;
5296
5297 while ((RD_HARPOON(port + hp_ext_status) &
5298 BM_CMD_BUSY) && timeout--) {
5299 }
5300
5301 WR_HARPOON(port + hp_bm_ctrl,
5302 (RD_HARPOON(port + hp_bm_ctrl) &
5303 ~FLUSH_XFER_CNTR));
5304
5305 if (RD_HARPOON(port + hp_ext_status) &
5306 BM_CMD_BUSY) {
5307
5308 if (pCurrSCCB->HostStatus == 0x00) {
5309
5310 pCurrSCCB->HostStatus =
5311 SCCB_BM_ERR;
5312 }
5313
5314 FPT_busMstrTimeOut(port);
5315 }
5316 }
5317
5318 if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5319
5320 if (RD_HARPOON(port + hp_ext_status) &
5321 BAD_EXT_STATUS) {
5322
5323 if (pCurrSCCB->HostStatus == 0x00) {
5324
5325 pCurrSCCB->HostStatus =
5326 SCCB_BM_ERR;
5327 }
5328 }
5329 }
5330 }
5331
5332 }
5333
5334 else {
5335
5336 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5337
5338 timeout = LONG_WAIT;
5339
5340 while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5341 && timeout--) {
5342 }
5343
5344 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5345
5346 if (pCurrSCCB->HostStatus == 0x00) {
5347
5348 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5349 }
5350
5351 FPT_busMstrTimeOut(port);
5352 }
5353 }
5354
5355 if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5356
5357 if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) {
5358
5359 if (pCurrSCCB->HostStatus == 0x00) {
5360
5361 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5362 }
5363 }
5364
5365 }
5366
5367 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5368
5369 WR_HARPOON(port + hp_page_ctrl,
5370 (RD_HARPOON(port + hp_page_ctrl) &
5371 ~SCATTER_EN));
5372
5373 WR_HARPOON(port + hp_sg_addr, 0x00);
5374
5375 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5376
5377 pCurrSCCB->Sccb_SGoffset = 0x00;
5378
5379 if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5380 pCurrSCCB->DataLength) {
5381
5382 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5383 pCurrSCCB->Sccb_sgseg =
5384 (unsigned short)(pCurrSCCB->DataLength /
5385 SG_ELEMENT_SIZE);
5386 }
5387 }
5388
5389 else {
5390 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5391 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5392 }
5393 }
5394
5395 WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
5396}
5397
5398/*---------------------------------------------------------------------
5399 *
5400 * Function: Host Data Transfer Restart
5401 *
5402 * Description: Reset the available count due to a restore data
5403 * pointers message.
5404 *
5405 *---------------------------------------------------------------------*/
5406static void FPT_hostDataXferRestart(struct sccb *currSCCB)
5407{
5408 unsigned long data_count;
5409 unsigned int sg_index;
5410 struct blogic_sg_seg *segp;
5411
5412 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5413
5414 currSCCB->Sccb_XferCnt = 0;
5415
5416 sg_index = 0xffff; /*Index by long words into sg list. */
5417 data_count = 0; /*Running count of SG xfer counts. */
5418
5419
5420 while (data_count < currSCCB->Sccb_ATC) {
5421
5422 sg_index++;
5423 segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) +
5424 (sg_index * 2);
5425 data_count += segp->segbytes;
5426 }
5427
5428 if (data_count == currSCCB->Sccb_ATC) {
5429
5430 currSCCB->Sccb_SGoffset = 0;
5431 sg_index++;
5432 }
5433
5434 else {
5435 currSCCB->Sccb_SGoffset =
5436 data_count - currSCCB->Sccb_ATC;
5437 }
5438
5439 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5440 }
5441
5442 else {
5443 currSCCB->Sccb_XferCnt =
5444 currSCCB->DataLength - currSCCB->Sccb_ATC;
5445 }
5446}
5447
5448/*---------------------------------------------------------------------
5449 *
5450 * Function: FPT_scini
5451 *
5452 * Description: Setup all data structures necessary for SCAM selection.
5453 *
5454 *---------------------------------------------------------------------*/
5455
5456static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
5457 unsigned char p_power_up)
5458{
5459
5460 unsigned char loser, assigned_id;
5461 u32 p_port;
5462
5463 unsigned char i, k, ScamFlg;
5464 struct sccb_card *currCard;
5465 struct nvram_info *pCurrNvRam;
5466
5467 currCard = &FPT_BL_Card[p_card];
5468 p_port = currCard->ioPort;
5469 pCurrNvRam = currCard->pNvRamInfo;
5470
5471 if (pCurrNvRam) {
5472 ScamFlg = pCurrNvRam->niScamConf;
5473 i = pCurrNvRam->niSysConf;
5474 } else {
5475 ScamFlg =
5476 (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2);
5477 i = (unsigned
5478 char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2)));
5479 }
5480 if (!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5481 return;
5482
5483 FPT_inisci(p_card, p_port, p_our_id);
5484
5485 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5486 too slow to return to SCAM selection */
5487
5488 /* if (p_power_up)
5489 FPT_Wait1Second(p_port);
5490 else
5491 FPT_Wait(p_port, TO_250ms); */
5492
5493 FPT_Wait1Second(p_port);
5494
5495 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) {
5496 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5497 }
5498
5499 FPT_scsel(p_port);
5500
5501 do {
5502 FPT_scxferc(p_port, SYNC_PTRN);
5503 FPT_scxferc(p_port, DOM_MSTR);
5504 loser =
5505 FPT_scsendi(p_port,
5506 &FPT_scamInfo[p_our_id].id_string[0]);
5507 } while (loser == 0xFF);
5508
5509 FPT_scbusf(p_port);
5510
5511 if ((p_power_up) && (!loser)) {
5512 FPT_sresb(p_port, p_card);
5513 FPT_Wait(p_port, TO_250ms);
5514
5515 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5516 }
5517
5518 FPT_scsel(p_port);
5519
5520 do {
5521 FPT_scxferc(p_port, SYNC_PTRN);
5522 FPT_scxferc(p_port, DOM_MSTR);
5523 loser =
5524 FPT_scsendi(p_port,
5525 &FPT_scamInfo[p_our_id].
5526 id_string[0]);
5527 } while (loser == 0xFF);
5528
5529 FPT_scbusf(p_port);
5530 }
5531 }
5532
5533 else {
5534 loser = 0;
5535 }
5536
5537 if (!loser) {
5538
5539 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5540
5541 if (ScamFlg & SCAM_ENABLED) {
5542
5543 for (i = 0; i < MAX_SCSI_TAR; i++) {
5544 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5545 (FPT_scamInfo[i].state == ID_UNUSED)) {
5546 if (FPT_scsell(p_port, i)) {
5547 FPT_scamInfo[i].state = LEGACY;
5548 if ((FPT_scamInfo[i].
5549 id_string[0] != 0xFF)
5550 || (FPT_scamInfo[i].
5551 id_string[1] != 0xFA)) {
5552
5553 FPT_scamInfo[i].
5554 id_string[0] = 0xFF;
5555 FPT_scamInfo[i].
5556 id_string[1] = 0xFA;
5557 if (pCurrNvRam == NULL)
5558 currCard->
5559 globalFlags
5560 |=
5561 F_UPDATE_EEPROM;
5562 }
5563 }
5564 }
5565 }
5566
5567 FPT_sresb(p_port, p_card);
5568 FPT_Wait1Second(p_port);
5569 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5570 }
5571 FPT_scsel(p_port);
5572 FPT_scasid(p_card, p_port);
5573 }
5574
5575 }
5576
5577 else if ((loser) && (ScamFlg & SCAM_ENABLED)) {
5578 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5579 assigned_id = 0;
5580 FPT_scwtsel(p_port);
5581
5582 do {
5583 while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) {
5584 }
5585
5586 i = FPT_scxferc(p_port, 0x00);
5587 if (i == ASSIGN_ID) {
5588 if (!
5589 (FPT_scsendi
5590 (p_port,
5591 &FPT_scamInfo[p_our_id].id_string[0]))) {
5592 i = FPT_scxferc(p_port, 0x00);
5593 if (FPT_scvalq(i)) {
5594 k = FPT_scxferc(p_port, 0x00);
5595
5596 if (FPT_scvalq(k)) {
5597 currCard->ourId =
5598 ((unsigned char)(i
5599 <<
5600 3)
5601 +
5602 (k &
5603 (unsigned char)7))
5604 & (unsigned char)
5605 0x3F;
5606 FPT_inisci(p_card,
5607 p_port,
5608 p_our_id);
5609 FPT_scamInfo[currCard->
5610 ourId].
5611 state = ID_ASSIGNED;
5612 FPT_scamInfo[currCard->
5613 ourId].
5614 id_string[0]
5615 = SLV_TYPE_CODE0;
5616 assigned_id = 1;
5617 }
5618 }
5619 }
5620 }
5621
5622 else if (i == SET_P_FLAG) {
5623 if (!(FPT_scsendi(p_port,
5624 &FPT_scamInfo[p_our_id].
5625 id_string[0])))
5626 FPT_scamInfo[p_our_id].id_string[0] |=
5627 0x80;
5628 }
5629 } while (!assigned_id);
5630
5631 while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) {
5632 }
5633 }
5634
5635 if (ScamFlg & SCAM_ENABLED) {
5636 FPT_scbusf(p_port);
5637 if (currCard->globalFlags & F_UPDATE_EEPROM) {
5638 FPT_scsavdi(p_card, p_port);
5639 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5640 }
5641 }
5642
5643/*
5644 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5645 {
5646 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5647 (FPT_scamInfo[i].state == LEGACY))
5648 k++;
5649 }
5650
5651 if (k==2)
5652 currCard->globalFlags |= F_SINGLE_DEVICE;
5653 else
5654 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5655*/
5656}
5657
5658/*---------------------------------------------------------------------
5659 *
5660 * Function: FPT_scarb
5661 *
5662 * Description: Gain control of the bus and wait SCAM select time (250ms)
5663 *
5664 *---------------------------------------------------------------------*/
5665
5666static int FPT_scarb(u32 p_port, unsigned char p_sel_type)
5667{
5668 if (p_sel_type == INIT_SELTD) {
5669
5670 while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {
5671 }
5672
5673 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL)
5674 return 0;
5675
5676 if (RD_HARPOON(p_port + hp_scsidata_0) != 00)
5677 return 0;
5678
5679 WR_HARPOON(p_port + hp_scsisig,
5680 (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY));
5681
5682 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) {
5683
5684 WR_HARPOON(p_port + hp_scsisig,
5685 (RD_HARPOON(p_port + hp_scsisig) &
5686 ~SCSI_BSY));
5687 return 0;
5688 }
5689
5690 WR_HARPOON(p_port + hp_scsisig,
5691 (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL));
5692
5693 if (RD_HARPOON(p_port + hp_scsidata_0) != 00) {
5694
5695 WR_HARPOON(p_port + hp_scsisig,
5696 (RD_HARPOON(p_port + hp_scsisig) &
5697 ~(SCSI_BSY | SCSI_SEL)));
5698 return 0;
5699 }
5700 }
5701
5702 WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5703 & ~ACTdeassert));
5704 WR_HARPOON(p_port + hp_scsireset, SCAM_EN);
5705 WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5706 WR_HARPOON(p_port + hp_scsidata_1, 0x00);
5707 WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN);
5708
5709 WR_HARPOON(p_port + hp_scsisig,
5710 (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG));
5711
5712 WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig)
5713 & ~SCSI_BSY));
5714
5715 FPT_Wait(p_port, TO_250ms);
5716
5717 return 1;
5718}
5719
5720/*---------------------------------------------------------------------
5721 *
5722 * Function: FPT_scbusf
5723 *
5724 * Description: Release the SCSI bus and disable SCAM selection.
5725 *
5726 *---------------------------------------------------------------------*/
5727
5728static void FPT_scbusf(u32 p_port)
5729{
5730 WR_HARPOON(p_port + hp_page_ctrl,
5731 (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
5732
5733 WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5734
5735 WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0)
5736 & ~SCSI_BUS_EN));
5737
5738 WR_HARPOON(p_port + hp_scsisig, 0x00);
5739
5740 WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset)
5741 & ~SCAM_EN));
5742
5743 WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5744 | ACTdeassert));
5745
5746 WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5747
5748 WR_HARPOON(p_port + hp_page_ctrl,
5749 (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE));
5750}
5751
5752/*---------------------------------------------------------------------
5753 *
5754 * Function: FPT_scasid
5755 *
5756 * Description: Assign an ID to all the SCAM devices.
5757 *
5758 *---------------------------------------------------------------------*/
5759
5760static void FPT_scasid(unsigned char p_card, u32 p_port)
5761{
5762 unsigned char temp_id_string[ID_STRING_LENGTH];
5763
5764 unsigned char i, k, scam_id;
5765 unsigned char crcBytes[3];
5766 struct nvram_info *pCurrNvRam;
5767 unsigned short *pCrcBytes;
5768
5769 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
5770
5771 i = 0;
5772
5773 while (!i) {
5774
5775 for (k = 0; k < ID_STRING_LENGTH; k++) {
5776 temp_id_string[k] = (unsigned char)0x00;
5777 }
5778
5779 FPT_scxferc(p_port, SYNC_PTRN);
5780 FPT_scxferc(p_port, ASSIGN_ID);
5781
5782 if (!(FPT_sciso(p_port, &temp_id_string[0]))) {
5783 if (pCurrNvRam) {
5784 pCrcBytes = (unsigned short *)&crcBytes[0];
5785 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
5786 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
5787 temp_id_string[1] = crcBytes[2];
5788 temp_id_string[2] = crcBytes[0];
5789 temp_id_string[3] = crcBytes[1];
5790 for (k = 4; k < ID_STRING_LENGTH; k++)
5791 temp_id_string[k] = (unsigned char)0x00;
5792 }
5793 i = FPT_scmachid(p_card, temp_id_string);
5794
5795 if (i == CLR_PRIORITY) {
5796 FPT_scxferc(p_port, MISC_CODE);
5797 FPT_scxferc(p_port, CLR_P_FLAG);
5798 i = 0; /*Not the last ID yet. */
5799 }
5800
5801 else if (i != NO_ID_AVAIL) {
5802 if (i < 8)
5803 FPT_scxferc(p_port, ID_0_7);
5804 else
5805 FPT_scxferc(p_port, ID_8_F);
5806
5807 scam_id = (i & (unsigned char)0x07);
5808
5809 for (k = 1; k < 0x08; k <<= 1)
5810 if (!(k & i))
5811 scam_id += 0x08; /*Count number of zeros in DB0-3. */
5812
5813 FPT_scxferc(p_port, scam_id);
5814
5815 i = 0; /*Not the last ID yet. */
5816 }
5817 }
5818
5819 else {
5820 i = 1;
5821 }
5822
5823 } /*End while */
5824
5825 FPT_scxferc(p_port, SYNC_PTRN);
5826 FPT_scxferc(p_port, CFG_CMPLT);
5827}
5828
5829/*---------------------------------------------------------------------
5830 *
5831 * Function: FPT_scsel
5832 *
5833 * Description: Select all the SCAM devices.
5834 *
5835 *---------------------------------------------------------------------*/
5836
5837static void FPT_scsel(u32 p_port)
5838{
5839
5840 WR_HARPOON(p_port + hp_scsisig, SCSI_SEL);
5841 FPT_scwiros(p_port, SCSI_MSG);
5842
5843 WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY));
5844
5845 WR_HARPOON(p_port + hp_scsisig,
5846 (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5847 WR_HARPOON(p_port + hp_scsidata_0,
5848 (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) |
5849 (unsigned char)(BIT(7) + BIT(6))));
5850
5851 WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5852 FPT_scwiros(p_port, SCSI_SEL);
5853
5854 WR_HARPOON(p_port + hp_scsidata_0,
5855 (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) &
5856 ~(unsigned char)BIT(6)));
5857 FPT_scwirod(p_port, BIT(6));
5858
5859 WR_HARPOON(p_port + hp_scsisig,
5860 (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5861}
5862
5863/*---------------------------------------------------------------------
5864 *
5865 * Function: FPT_scxferc
5866 *
5867 * Description: Handshake the p_data (DB4-0) across the bus.
5868 *
5869 *---------------------------------------------------------------------*/
5870
5871static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data)
5872{
5873 unsigned char curr_data, ret_data;
5874
5875 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
5876
5877 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5878
5879 curr_data &= ~BIT(7);
5880
5881 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5882
5883 FPT_scwirod(p_port, BIT(7)); /*Wait for DB7 to be released. */
5884 while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ;
5885
5886 ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F);
5887
5888 curr_data |= BIT(6);
5889
5890 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5891
5892 curr_data &= ~BIT(5);
5893
5894 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5895
5896 FPT_scwirod(p_port, BIT(5)); /*Wait for DB5 to be released. */
5897
5898 curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */
5899 curr_data |= BIT(7);
5900
5901 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5902
5903 curr_data &= ~BIT(6);
5904
5905 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5906
5907 FPT_scwirod(p_port, BIT(6)); /*Wait for DB6 to be released. */
5908
5909 return ret_data;
5910}
5911
5912/*---------------------------------------------------------------------
5913 *
5914 * Function: FPT_scsendi
5915 *
5916 * Description: Transfer our Identification string to determine if we
5917 * will be the dominant master.
5918 *
5919 *---------------------------------------------------------------------*/
5920
5921static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[])
5922{
5923 unsigned char ret_data, byte_cnt, bit_cnt, defer;
5924
5925 defer = 0;
5926
5927 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5928
5929 for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) {
5930
5931 if (defer)
5932 ret_data = FPT_scxferc(p_port, 00);
5933
5934 else if (p_id_string[byte_cnt] & bit_cnt)
5935
5936 ret_data = FPT_scxferc(p_port, 02);
5937
5938 else {
5939
5940 ret_data = FPT_scxferc(p_port, 01);
5941 if (ret_data & 02)
5942 defer = 1;
5943 }
5944
5945 if ((ret_data & 0x1C) == 0x10)
5946 return 0x00; /*End of isolation stage, we won! */
5947
5948 if (ret_data & 0x1C)
5949 return 0xFF;
5950
5951 if ((defer) && (!(ret_data & 0x1F)))
5952 return 0x01; /*End of isolation stage, we lost. */
5953
5954 } /*bit loop */
5955
5956 } /*byte loop */
5957
5958 if (defer)
5959 return 0x01; /*We lost */
5960 else
5961 return 0; /*We WON! Yeeessss! */
5962}
5963
5964/*---------------------------------------------------------------------
5965 *
5966 * Function: FPT_sciso
5967 *
5968 * Description: Transfer the Identification string.
5969 *
5970 *---------------------------------------------------------------------*/
5971
5972static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[])
5973{
5974 unsigned char ret_data, the_data, byte_cnt, bit_cnt;
5975
5976 the_data = 0;
5977
5978 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5979
5980 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
5981
5982 ret_data = FPT_scxferc(p_port, 0);
5983
5984 if (ret_data & 0xFC)
5985 return 0xFF;
5986
5987 else {
5988
5989 the_data <<= 1;
5990 if (ret_data & BIT(1)) {
5991 the_data |= 1;
5992 }
5993 }
5994
5995 if ((ret_data & 0x1F) == 0) {
5996/*
5997 if(bit_cnt != 0 || bit_cnt != 8)
5998 {
5999 byte_cnt = 0;
6000 bit_cnt = 0;
6001 FPT_scxferc(p_port, SYNC_PTRN);
6002 FPT_scxferc(p_port, ASSIGN_ID);
6003 continue;
6004 }
6005*/
6006 if (byte_cnt)
6007 return 0x00;
6008 else
6009 return 0xFF;
6010 }
6011
6012 } /*bit loop */
6013
6014 p_id_string[byte_cnt] = the_data;
6015
6016 } /*byte loop */
6017
6018 return 0;
6019}
6020
6021/*---------------------------------------------------------------------
6022 *
6023 * Function: FPT_scwirod
6024 *
6025 * Description: Sample the SCSI data bus making sure the signal has been
6026 * deasserted for the correct number of consecutive samples.
6027 *
6028 *---------------------------------------------------------------------*/
6029
6030static void FPT_scwirod(u32 p_port, unsigned char p_data_bit)
6031{
6032 unsigned char i;
6033
6034 i = 0;
6035 while (i < MAX_SCSI_TAR) {
6036
6037 if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit)
6038
6039 i = 0;
6040
6041 else
6042
6043 i++;
6044
6045 }
6046}
6047
6048/*---------------------------------------------------------------------
6049 *
6050 * Function: FPT_scwiros
6051 *
6052 * Description: Sample the SCSI Signal lines making sure the signal has been
6053 * deasserted for the correct number of consecutive samples.
6054 *
6055 *---------------------------------------------------------------------*/
6056
6057static void FPT_scwiros(u32 p_port, unsigned char p_data_bit)
6058{
6059 unsigned char i;
6060
6061 i = 0;
6062 while (i < MAX_SCSI_TAR) {
6063
6064 if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit)
6065
6066 i = 0;
6067
6068 else
6069
6070 i++;
6071
6072 }
6073}
6074
6075/*---------------------------------------------------------------------
6076 *
6077 * Function: FPT_scvalq
6078 *
6079 * Description: Make sure we received a valid data byte.
6080 *
6081 *---------------------------------------------------------------------*/
6082
6083static unsigned char FPT_scvalq(unsigned char p_quintet)
6084{
6085 unsigned char count;
6086
6087 for (count = 1; count < 0x08; count <<= 1) {
6088 if (!(p_quintet & count))
6089 p_quintet -= 0x80;
6090 }
6091
6092 if (p_quintet & 0x18)
6093 return 0;
6094
6095 else
6096 return 1;
6097}
6098
6099/*---------------------------------------------------------------------
6100 *
6101 * Function: FPT_scsell
6102 *
6103 * Description: Select the specified device ID using a selection timeout
6104 * less than 4ms. If somebody responds then it is a legacy
6105 * drive and this ID must be marked as such.
6106 *
6107 *---------------------------------------------------------------------*/
6108
6109static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id)
6110{
6111 unsigned long i;
6112
6113 WR_HARPOON(p_port + hp_page_ctrl,
6114 (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
6115
6116 ARAM_ACCESS(p_port);
6117
6118 WR_HARPOON(p_port + hp_addstat,
6119 (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER));
6120 WR_HARPOON(p_port + hp_seltimeout, TO_4ms);
6121
6122 for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) {
6123 WRW_HARPOON(i, (MPM_OP + ACOMMAND));
6124 }
6125 WRW_HARPOON(i, (BRH_OP + ALWAYS + NP));
6126
6127 WRW_HARPOON((p_port + hp_intstat),
6128 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6129
6130 WR_HARPOON(p_port + hp_select_id, targ_id);
6131
6132 WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT);
6133 WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6134 WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6135
6136 while (!(RDW_HARPOON((p_port + hp_intstat)) &
6137 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {
6138 }
6139
6140 if (RDW_HARPOON((p_port + hp_intstat)) & RESET)
6141 FPT_Wait(p_port, TO_250ms);
6142
6143 DISABLE_AUTO(p_port);
6144
6145 WR_HARPOON(p_port + hp_addstat,
6146 (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER));
6147 WR_HARPOON(p_port + hp_seltimeout, TO_290ms);
6148
6149 SGRAM_ACCESS(p_port);
6150
6151 if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) {
6152
6153 WRW_HARPOON((p_port + hp_intstat),
6154 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6155
6156 WR_HARPOON(p_port + hp_page_ctrl,
6157 (RD_HARPOON(p_port + hp_page_ctrl) &
6158 ~G_INT_DISABLE));
6159
6160 return 0; /*No legacy device */
6161 }
6162
6163 else {
6164
6165 while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) {
6166 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) {
6167 WR_HARPOON(p_port + hp_scsisig,
6168 (SCSI_ACK + S_ILL_PH));
6169 ACCEPT_MSG(p_port);
6170 }
6171 }
6172
6173 WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1);
6174
6175 WR_HARPOON(p_port + hp_page_ctrl,
6176 (RD_HARPOON(p_port + hp_page_ctrl) &
6177 ~G_INT_DISABLE));
6178
6179 return 1; /*Found one of them oldies! */
6180 }
6181}
6182
6183/*---------------------------------------------------------------------
6184 *
6185 * Function: FPT_scwtsel
6186 *
6187 * Description: Wait to be selected by another SCAM initiator.
6188 *
6189 *---------------------------------------------------------------------*/
6190
6191static void FPT_scwtsel(u32 p_port)
6192{
6193 while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) {
6194 }
6195}
6196
6197/*---------------------------------------------------------------------
6198 *
6199 * Function: FPT_inisci
6200 *
6201 * Description: Setup the data Structure with the info from the EEPROM.
6202 *
6203 *---------------------------------------------------------------------*/
6204
6205static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id)
6206{
6207 unsigned char i, k, max_id;
6208 unsigned short ee_data;
6209 struct nvram_info *pCurrNvRam;
6210
6211 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6212
6213 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6214 max_id = 0x08;
6215
6216 else
6217 max_id = 0x10;
6218
6219 if (pCurrNvRam) {
6220 for (i = 0; i < max_id; i++) {
6221
6222 for (k = 0; k < 4; k++)
6223 FPT_scamInfo[i].id_string[k] =
6224 pCurrNvRam->niScamTbl[i][k];
6225 for (k = 4; k < ID_STRING_LENGTH; k++)
6226 FPT_scamInfo[i].id_string[k] =
6227 (unsigned char)0x00;
6228
6229 if (FPT_scamInfo[i].id_string[0] == 0x00)
6230 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6231 else
6232 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6233
6234 }
6235 } else {
6236 for (i = 0; i < max_id; i++) {
6237 for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6238 ee_data =
6239 FPT_utilEERead(p_port,
6240 (unsigned
6241 short)((EE_SCAMBASE / 2) +
6242 (unsigned short)(i *
6243 ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6244 FPT_scamInfo[i].id_string[k] =
6245 (unsigned char)ee_data;
6246 ee_data >>= 8;
6247 FPT_scamInfo[i].id_string[k + 1] =
6248 (unsigned char)ee_data;
6249 }
6250
6251 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6252 (FPT_scamInfo[i].id_string[0] == 0xFF))
6253
6254 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6255
6256 else
6257 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6258
6259 }
6260 }
6261 for (k = 0; k < ID_STRING_LENGTH; k++)
6262 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6263
6264}
6265
6266/*---------------------------------------------------------------------
6267 *
6268 * Function: FPT_scmachid
6269 *
6270 * Description: Match the Device ID string with our values stored in
6271 * the EEPROM.
6272 *
6273 *---------------------------------------------------------------------*/
6274
6275static unsigned char FPT_scmachid(unsigned char p_card,
6276 unsigned char p_id_string[])
6277{
6278
6279 unsigned char i, k, match;
6280
6281 for (i = 0; i < MAX_SCSI_TAR; i++) {
6282
6283 match = 1;
6284
6285 for (k = 0; k < ID_STRING_LENGTH; k++) {
6286 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6287 match = 0;
6288 }
6289
6290 if (match) {
6291 FPT_scamInfo[i].state = ID_ASSIGNED;
6292 return i;
6293 }
6294
6295 }
6296
6297 if (p_id_string[0] & BIT(5))
6298 i = 8;
6299 else
6300 i = MAX_SCSI_TAR;
6301
6302 if (((p_id_string[0] & 0x06) == 0x02)
6303 || ((p_id_string[0] & 0x06) == 0x04))
6304 match = p_id_string[1] & (unsigned char)0x1F;
6305 else
6306 match = 7;
6307
6308 while (i > 0) {
6309 i--;
6310
6311 if (FPT_scamInfo[match].state == ID_UNUSED) {
6312 for (k = 0; k < ID_STRING_LENGTH; k++) {
6313 FPT_scamInfo[match].id_string[k] =
6314 p_id_string[k];
6315 }
6316
6317 FPT_scamInfo[match].state = ID_ASSIGNED;
6318
6319 if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6320 FPT_BL_Card[p_card].globalFlags |=
6321 F_UPDATE_EEPROM;
6322 return match;
6323
6324 }
6325
6326 match--;
6327
6328 if (match == 0xFF) {
6329 if (p_id_string[0] & BIT(5))
6330 match = 7;
6331 else
6332 match = MAX_SCSI_TAR - 1;
6333 }
6334 }
6335
6336 if (p_id_string[0] & BIT(7)) {
6337 return CLR_PRIORITY;
6338 }
6339
6340 if (p_id_string[0] & BIT(5))
6341 i = 8;
6342 else
6343 i = MAX_SCSI_TAR;
6344
6345 if (((p_id_string[0] & 0x06) == 0x02)
6346 || ((p_id_string[0] & 0x06) == 0x04))
6347 match = p_id_string[1] & (unsigned char)0x1F;
6348 else
6349 match = 7;
6350
6351 while (i > 0) {
6352
6353 i--;
6354
6355 if (FPT_scamInfo[match].state == ID_UNASSIGNED) {
6356 for (k = 0; k < ID_STRING_LENGTH; k++) {
6357 FPT_scamInfo[match].id_string[k] =
6358 p_id_string[k];
6359 }
6360
6361 FPT_scamInfo[match].id_string[0] |= BIT(7);
6362 FPT_scamInfo[match].state = ID_ASSIGNED;
6363 if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6364 FPT_BL_Card[p_card].globalFlags |=
6365 F_UPDATE_EEPROM;
6366 return match;
6367
6368 }
6369
6370 match--;
6371
6372 if (match == 0xFF) {
6373 if (p_id_string[0] & BIT(5))
6374 match = 7;
6375 else
6376 match = MAX_SCSI_TAR - 1;
6377 }
6378 }
6379
6380 return NO_ID_AVAIL;
6381}
6382
6383/*---------------------------------------------------------------------
6384 *
6385 * Function: FPT_scsavdi
6386 *
6387 * Description: Save off the device SCAM ID strings.
6388 *
6389 *---------------------------------------------------------------------*/
6390
6391static void FPT_scsavdi(unsigned char p_card, u32 p_port)
6392{
6393 unsigned char i, k, max_id;
6394 unsigned short ee_data, sum_data;
6395
6396 sum_data = 0x0000;
6397
6398 for (i = 1; i < EE_SCAMBASE / 2; i++) {
6399 sum_data += FPT_utilEERead(p_port, i);
6400 }
6401
6402 FPT_utilEEWriteOnOff(p_port, 1); /* Enable write access to the EEPROM */
6403
6404 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6405 max_id = 0x08;
6406
6407 else
6408 max_id = 0x10;
6409
6410 for (i = 0; i < max_id; i++) {
6411
6412 for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6413 ee_data = FPT_scamInfo[i].id_string[k + 1];
6414 ee_data <<= 8;
6415 ee_data |= FPT_scamInfo[i].id_string[k];
6416 sum_data += ee_data;
6417 FPT_utilEEWrite(p_port, ee_data,
6418 (unsigned short)((EE_SCAMBASE / 2) +
6419 (unsigned short)(i *
6420 ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6421 }
6422 }
6423
6424 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2);
6425 FPT_utilEEWriteOnOff(p_port, 0); /* Turn off write access */
6426}
6427
6428/*---------------------------------------------------------------------
6429 *
6430 * Function: FPT_XbowInit
6431 *
6432 * Description: Setup the Xbow for normal operation.
6433 *
6434 *---------------------------------------------------------------------*/
6435
6436static void FPT_XbowInit(u32 port, unsigned char ScamFlg)
6437{
6438 unsigned char i;
6439
6440 i = RD_HARPOON(port + hp_page_ctrl);
6441 WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE));
6442
6443 WR_HARPOON(port + hp_scsireset, 0x00);
6444 WR_HARPOON(port + hp_portctrl_1, HOST_MODE8);
6445
6446 WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET |
6447 FIFO_CLR));
6448
6449 WR_HARPOON(port + hp_scsireset, SCSI_INI);
6450
6451 WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT);
6452
6453 WR_HARPOON(port + hp_scsisig, 0x00); /* Clear any signals we might */
6454 WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
6455
6456 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
6457
6458 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6459 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6460
6461 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6462 FPT_default_intena |= SCAM_SEL;
6463
6464 WRW_HARPOON((port + hp_intena), FPT_default_intena);
6465
6466 WR_HARPOON(port + hp_seltimeout, TO_290ms);
6467
6468 /* Turn on SCSI_MODE8 for narrow cards to fix the
6469 strapping issue with the DUAL CHANNEL card */
6470 if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD)
6471 WR_HARPOON(port + hp_addstat, SCSI_MODE8);
6472
6473 WR_HARPOON(port + hp_page_ctrl, i);
6474
6475}
6476
6477/*---------------------------------------------------------------------
6478 *
6479 * Function: FPT_BusMasterInit
6480 *
6481 * Description: Initialize the BusMaster for normal operations.
6482 *
6483 *---------------------------------------------------------------------*/
6484
6485static void FPT_BusMasterInit(u32 p_port)
6486{
6487
6488 WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST);
6489 WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
6490
6491 WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64);
6492
6493 WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT));
6494
6495 WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H));
6496
6497 RD_HARPOON(p_port + hp_int_status); /*Clear interrupts. */
6498 WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6499 WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) &
6500 ~SCATTER_EN));
6501}
6502
6503/*---------------------------------------------------------------------
6504 *
6505 * Function: FPT_DiagEEPROM
6506 *
6507 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6508 * necessary.
6509 *
6510 *---------------------------------------------------------------------*/
6511
6512static void FPT_DiagEEPROM(u32 p_port)
6513{
6514 unsigned short index, temp, max_wd_cnt;
6515
6516 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6517 max_wd_cnt = EEPROM_WD_CNT;
6518 else
6519 max_wd_cnt = EEPROM_WD_CNT * 2;
6520
6521 temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2);
6522
6523 if (temp == 0x4641) {
6524
6525 for (index = 2; index < max_wd_cnt; index++) {
6526
6527 temp += FPT_utilEERead(p_port, index);
6528
6529 }
6530
6531 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) {
6532
6533 return; /*EEPROM is Okay so return now! */
6534 }
6535 }
6536
6537 FPT_utilEEWriteOnOff(p_port, (unsigned char)1);
6538
6539 for (index = 0; index < max_wd_cnt; index++) {
6540
6541 FPT_utilEEWrite(p_port, 0x0000, index);
6542 }
6543
6544 temp = 0;
6545
6546 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2);
6547 temp += 0x4641;
6548 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2);
6549 temp += 0x3920;
6550 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2);
6551 temp += 0x3033;
6552 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2);
6553 temp += 0x2020;
6554 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2);
6555 temp += 0x70D3;
6556 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2);
6557 temp += 0x0010;
6558 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2);
6559 temp += 0x0003;
6560 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2);
6561 temp += 0x0007;
6562
6563 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2);
6564 temp += 0x0000;
6565 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2);
6566 temp += 0x0000;
6567 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2);
6568 temp += 0x0000;
6569
6570 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2);
6571 temp += 0x4242;
6572 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2);
6573 temp += 0x4242;
6574 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2);
6575 temp += 0x4242;
6576 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2);
6577 temp += 0x4242;
6578 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2);
6579 temp += 0x4242;
6580 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2);
6581 temp += 0x4242;
6582 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2);
6583 temp += 0x4242;
6584 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2);
6585 temp += 0x4242;
6586
6587 FPT_utilEEWrite(p_port, 0x6C46, 64 / 2); /*PRODUCT ID */
6588 temp += 0x6C46;
6589 FPT_utilEEWrite(p_port, 0x7361, 66 / 2); /* FlashPoint LT */
6590 temp += 0x7361;
6591 FPT_utilEEWrite(p_port, 0x5068, 68 / 2);
6592 temp += 0x5068;
6593 FPT_utilEEWrite(p_port, 0x696F, 70 / 2);
6594 temp += 0x696F;
6595 FPT_utilEEWrite(p_port, 0x746E, 72 / 2);
6596 temp += 0x746E;
6597 FPT_utilEEWrite(p_port, 0x4C20, 74 / 2);
6598 temp += 0x4C20;
6599 FPT_utilEEWrite(p_port, 0x2054, 76 / 2);
6600 temp += 0x2054;
6601 FPT_utilEEWrite(p_port, 0x2020, 78 / 2);
6602 temp += 0x2020;
6603
6604 index = ((EE_SCAMBASE / 2) + (7 * 16));
6605 FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index);
6606 temp += (0x0700 + TYPE_CODE0);
6607 index++;
6608 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6609 temp += 0x5542; /* BUSLOGIC */
6610 index++;
6611 FPT_utilEEWrite(p_port, 0x4C53, index);
6612 temp += 0x4C53;
6613 index++;
6614 FPT_utilEEWrite(p_port, 0x474F, index);
6615 temp += 0x474F;
6616 index++;
6617 FPT_utilEEWrite(p_port, 0x4349, index);
6618 temp += 0x4349;
6619 index++;
6620 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6621 temp += 0x5442; /* BT- 930 */
6622 index++;
6623 FPT_utilEEWrite(p_port, 0x202D, index);
6624 temp += 0x202D;
6625 index++;
6626 FPT_utilEEWrite(p_port, 0x3339, index);
6627 temp += 0x3339;
6628 index++; /*Serial # */
6629 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6630 temp += 0x2030;
6631 index++;
6632 FPT_utilEEWrite(p_port, 0x5453, index);
6633 temp += 0x5453;
6634 index++;
6635 FPT_utilEEWrite(p_port, 0x5645, index);
6636 temp += 0x5645;
6637 index++;
6638 FPT_utilEEWrite(p_port, 0x2045, index);
6639 temp += 0x2045;
6640 index++;
6641 FPT_utilEEWrite(p_port, 0x202F, index);
6642 temp += 0x202F;
6643 index++;
6644 FPT_utilEEWrite(p_port, 0x4F4A, index);
6645 temp += 0x4F4A;
6646 index++;
6647 FPT_utilEEWrite(p_port, 0x204E, index);
6648 temp += 0x204E;
6649 index++;
6650 FPT_utilEEWrite(p_port, 0x3539, index);
6651 temp += 0x3539;
6652
6653 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2);
6654
6655 FPT_utilEEWriteOnOff(p_port, (unsigned char)0);
6656
6657}
6658
6659/*---------------------------------------------------------------------
6660 *
6661 * Function: Queue Search Select
6662 *
6663 * Description: Try to find a new command to execute.
6664 *
6665 *---------------------------------------------------------------------*/
6666
6667static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
6668 unsigned char p_card)
6669{
6670 unsigned char scan_ptr, lun;
6671 struct sccb_mgr_tar_info *currTar_Info;
6672 struct sccb *pOldSccb;
6673
6674 scan_ptr = pCurrCard->scanIndex;
6675 do {
6676 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6677 if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
6678 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6679 TAG_Q_TRYING)) {
6680 if (currTar_Info->TarSelQ_Cnt != 0) {
6681
6682 scan_ptr++;
6683 if (scan_ptr == MAX_SCSI_TAR)
6684 scan_ptr = 0;
6685
6686 for (lun = 0; lun < MAX_LUN; lun++) {
6687 if (currTar_Info->TarLUNBusy[lun] == 0) {
6688
6689 pCurrCard->currentSCCB =
6690 currTar_Info->TarSelQ_Head;
6691 pOldSccb = NULL;
6692
6693 while ((pCurrCard->
6694 currentSCCB != NULL)
6695 && (lun !=
6696 pCurrCard->
6697 currentSCCB->Lun)) {
6698 pOldSccb =
6699 pCurrCard->
6700 currentSCCB;
6701 pCurrCard->currentSCCB =
6702 (struct sccb
6703 *)(pCurrCard->
6704 currentSCCB)->
6705 Sccb_forwardlink;
6706 }
6707 if (pCurrCard->currentSCCB ==
6708 NULL)
6709 continue;
6710 if (pOldSccb != NULL) {
6711 pOldSccb->
6712 Sccb_forwardlink =
6713 (struct sccb
6714 *)(pCurrCard->
6715 currentSCCB)->
6716 Sccb_forwardlink;
6717 pOldSccb->
6718 Sccb_backlink =
6719 (struct sccb
6720 *)(pCurrCard->
6721 currentSCCB)->
6722 Sccb_backlink;
6723 currTar_Info->
6724 TarSelQ_Cnt--;
6725 } else {
6726 currTar_Info->
6727 TarSelQ_Head =
6728 (struct sccb
6729 *)(pCurrCard->
6730 currentSCCB)->
6731 Sccb_forwardlink;
6732
6733 if (currTar_Info->
6734 TarSelQ_Head ==
6735 NULL) {
6736 currTar_Info->
6737 TarSelQ_Tail
6738 = NULL;
6739 currTar_Info->
6740 TarSelQ_Cnt
6741 = 0;
6742 } else {
6743 currTar_Info->
6744 TarSelQ_Cnt--;
6745 currTar_Info->
6746 TarSelQ_Head->
6747 Sccb_backlink
6748 =
6749 (struct sccb
6750 *)NULL;
6751 }
6752 }
6753 pCurrCard->scanIndex = scan_ptr;
6754
6755 pCurrCard->globalFlags |=
6756 F_NEW_SCCB_CMD;
6757
6758 break;
6759 }
6760 }
6761 }
6762
6763 else {
6764 scan_ptr++;
6765 if (scan_ptr == MAX_SCSI_TAR) {
6766 scan_ptr = 0;
6767 }
6768 }
6769
6770 } else {
6771 if ((currTar_Info->TarSelQ_Cnt != 0) &&
6772 (currTar_Info->TarLUNBusy[0] == 0)) {
6773
6774 pCurrCard->currentSCCB =
6775 currTar_Info->TarSelQ_Head;
6776
6777 currTar_Info->TarSelQ_Head =
6778 (struct sccb *)(pCurrCard->currentSCCB)->
6779 Sccb_forwardlink;
6780
6781 if (currTar_Info->TarSelQ_Head == NULL) {
6782 currTar_Info->TarSelQ_Tail = NULL;
6783 currTar_Info->TarSelQ_Cnt = 0;
6784 } else {
6785 currTar_Info->TarSelQ_Cnt--;
6786 currTar_Info->TarSelQ_Head->
6787 Sccb_backlink = (struct sccb *)NULL;
6788 }
6789
6790 scan_ptr++;
6791 if (scan_ptr == MAX_SCSI_TAR)
6792 scan_ptr = 0;
6793
6794 pCurrCard->scanIndex = scan_ptr;
6795
6796 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6797
6798 break;
6799 }
6800
6801 else {
6802 scan_ptr++;
6803 if (scan_ptr == MAX_SCSI_TAR) {
6804 scan_ptr = 0;
6805 }
6806 }
6807 }
6808 } while (scan_ptr != pCurrCard->scanIndex);
6809}
6810
6811/*---------------------------------------------------------------------
6812 *
6813 * Function: Queue Select Fail
6814 *
6815 * Description: Add the current SCCB to the head of the Queue.
6816 *
6817 *---------------------------------------------------------------------*/
6818
6819static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
6820 unsigned char p_card)
6821{
6822 unsigned char thisTarg;
6823 struct sccb_mgr_tar_info *currTar_Info;
6824
6825 if (pCurrCard->currentSCCB != NULL) {
6826 thisTarg =
6827 (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->
6828 TargID);
6829 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6830
6831 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
6832
6833 pCurrCard->currentSCCB->Sccb_forwardlink =
6834 currTar_Info->TarSelQ_Head;
6835
6836 if (currTar_Info->TarSelQ_Cnt == 0) {
6837 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
6838 }
6839
6840 else {
6841 currTar_Info->TarSelQ_Head->Sccb_backlink =
6842 pCurrCard->currentSCCB;
6843 }
6844
6845 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
6846
6847 pCurrCard->currentSCCB = NULL;
6848 currTar_Info->TarSelQ_Cnt++;
6849 }
6850}
6851
6852/*---------------------------------------------------------------------
6853 *
6854 * Function: Queue Command Complete
6855 *
6856 * Description: Call the callback function with the current SCCB.
6857 *
6858 *---------------------------------------------------------------------*/
6859
6860static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
6861 struct sccb *p_sccb, unsigned char p_card)
6862{
6863
6864 unsigned char i, SCSIcmd;
6865 CALL_BK_FN callback;
6866 struct sccb_mgr_tar_info *currTar_Info;
6867
6868 SCSIcmd = p_sccb->Cdb[0];
6869
6870 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
6871
6872 if ((p_sccb->
6873 ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN))
6874 && (p_sccb->HostStatus == SCCB_COMPLETE)
6875 && (p_sccb->TargetStatus != SSCHECK))
6876
6877 if ((SCSIcmd == SCSI_READ) ||
6878 (SCSIcmd == SCSI_WRITE) ||
6879 (SCSIcmd == SCSI_READ_EXTENDED) ||
6880 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
6881 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
6882 (SCSIcmd == SCSI_START_STOP_UNIT) ||
6883 (pCurrCard->globalFlags & F_NO_FILTER)
6884 )
6885 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
6886 }
6887
6888 if (p_sccb->SccbStatus == SCCB_IN_PROCESS) {
6889 if (p_sccb->HostStatus || p_sccb->TargetStatus)
6890 p_sccb->SccbStatus = SCCB_ERROR;
6891 else
6892 p_sccb->SccbStatus = SCCB_SUCCESS;
6893 }
6894
6895 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
6896
6897 p_sccb->CdbLength = p_sccb->Save_CdbLen;
6898 for (i = 0; i < 6; i++) {
6899 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
6900 }
6901 }
6902
6903 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
6904 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
6905
6906 FPT_utilUpdateResidual(p_sccb);
6907 }
6908
6909 pCurrCard->cmdCounter--;
6910 if (!pCurrCard->cmdCounter) {
6911
6912 if (pCurrCard->globalFlags & F_GREEN_PC) {
6913 WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0,
6914 (PWR_DWN | CLKCTRL_DEFAULT));
6915 WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK);
6916 }
6917
6918 WR_HARPOON(pCurrCard->ioPort + hp_semaphore,
6919 (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) &
6920 ~SCCB_MGR_ACTIVE));
6921
6922 }
6923
6924 if (pCurrCard->discQCount != 0) {
6925 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6926 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
6927 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6928 TAG_Q_TRYING))) {
6929 pCurrCard->discQCount--;
6930 pCurrCard->discQ_Tbl[currTar_Info->
6931 LunDiscQ_Idx[p_sccb->Lun]] = NULL;
6932 } else {
6933 if (p_sccb->Sccb_tag) {
6934 pCurrCard->discQCount--;
6935 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
6936 } else {
6937 pCurrCard->discQCount--;
6938 pCurrCard->discQ_Tbl[currTar_Info->
6939 LunDiscQ_Idx[0]] = NULL;
6940 }
6941 }
6942
6943 }
6944
6945 callback = (CALL_BK_FN) p_sccb->SccbCallback;
6946 callback(p_sccb);
6947 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6948 pCurrCard->currentSCCB = NULL;
6949}
6950
6951/*---------------------------------------------------------------------
6952 *
6953 * Function: Queue Disconnect
6954 *
6955 * Description: Add SCCB to our disconnect array.
6956 *
6957 *---------------------------------------------------------------------*/
6958static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card)
6959{
6960 struct sccb_mgr_tar_info *currTar_Info;
6961
6962 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6963
6964 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
6965 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
6966 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6967 LunDiscQ_Idx[p_sccb->Lun]] =
6968 p_sccb;
6969 } else {
6970 if (p_sccb->Sccb_tag) {
6971 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] =
6972 p_sccb;
6973 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] =
6974 0;
6975 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
6976 } else {
6977 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6978 LunDiscQ_Idx[0]] = p_sccb;
6979 }
6980 }
6981 FPT_BL_Card[p_card].currentSCCB = NULL;
6982}
6983
6984/*---------------------------------------------------------------------
6985 *
6986 * Function: Queue Flush SCCB
6987 *
6988 * Description: Flush all SCCB's back to the host driver for this target.
6989 *
6990 *---------------------------------------------------------------------*/
6991
6992static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
6993{
6994 unsigned char qtag, thisTarg;
6995 struct sccb *currSCCB;
6996 struct sccb_mgr_tar_info *currTar_Info;
6997
6998 currSCCB = FPT_BL_Card[p_card].currentSCCB;
6999 if (currSCCB != NULL) {
7000 thisTarg = (unsigned char)currSCCB->TargID;
7001 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7002
7003 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7004
7005 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7006 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
7007 thisTarg)) {
7008
7009 FPT_BL_Card[p_card].discQ_Tbl[qtag]->
7010 HostStatus = (unsigned char)error_code;
7011
7012 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7013 FPT_BL_Card[p_card].
7014 discQ_Tbl[qtag], p_card);
7015
7016 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7017 currTar_Info->TarTagQ_Cnt--;
7018
7019 }
7020 }
7021 }
7022
7023}
7024
7025/*---------------------------------------------------------------------
7026 *
7027 * Function: Queue Flush Target SCCB
7028 *
7029 * Description: Flush all SCCB's back to the host driver for this target.
7030 *
7031 *---------------------------------------------------------------------*/
7032
7033static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7034 unsigned char error_code)
7035{
7036 unsigned char qtag;
7037 struct sccb_mgr_tar_info *currTar_Info;
7038
7039 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7040
7041 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7042
7043 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7044 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) {
7045
7046 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus =
7047 (unsigned char)error_code;
7048
7049 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7050 FPT_BL_Card[p_card].
7051 discQ_Tbl[qtag], p_card);
7052
7053 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7054 currTar_Info->TarTagQ_Cnt--;
7055
7056 }
7057 }
7058
7059}
7060
7061static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card)
7062{
7063 struct sccb_mgr_tar_info *currTar_Info;
7064 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7065
7066 p_SCCB->Sccb_forwardlink = NULL;
7067
7068 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7069
7070 if (currTar_Info->TarSelQ_Cnt == 0) {
7071
7072 currTar_Info->TarSelQ_Head = p_SCCB;
7073 }
7074
7075 else {
7076
7077 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7078 }
7079
7080 currTar_Info->TarSelQ_Tail = p_SCCB;
7081 currTar_Info->TarSelQ_Cnt++;
7082}
7083
7084/*---------------------------------------------------------------------
7085 *
7086 * Function: Queue Find SCCB
7087 *
7088 * Description: Search the target select Queue for this SCCB, and
7089 * remove it if found.
7090 *
7091 *---------------------------------------------------------------------*/
7092
7093static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
7094 unsigned char p_card)
7095{
7096 struct sccb *q_ptr;
7097 struct sccb_mgr_tar_info *currTar_Info;
7098
7099 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7100
7101 q_ptr = currTar_Info->TarSelQ_Head;
7102
7103 while (q_ptr != NULL) {
7104
7105 if (q_ptr == p_SCCB) {
7106
7107 if (currTar_Info->TarSelQ_Head == q_ptr) {
7108
7109 currTar_Info->TarSelQ_Head =
7110 q_ptr->Sccb_forwardlink;
7111 }
7112
7113 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7114
7115 currTar_Info->TarSelQ_Tail =
7116 q_ptr->Sccb_backlink;
7117 }
7118
7119 if (q_ptr->Sccb_forwardlink != NULL) {
7120 q_ptr->Sccb_forwardlink->Sccb_backlink =
7121 q_ptr->Sccb_backlink;
7122 }
7123
7124 if (q_ptr->Sccb_backlink != NULL) {
7125 q_ptr->Sccb_backlink->Sccb_forwardlink =
7126 q_ptr->Sccb_forwardlink;
7127 }
7128
7129 currTar_Info->TarSelQ_Cnt--;
7130
7131 return 1;
7132 }
7133
7134 else {
7135 q_ptr = q_ptr->Sccb_forwardlink;
7136 }
7137 }
7138
7139 return 0;
7140
7141}
7142
7143/*---------------------------------------------------------------------
7144 *
7145 * Function: Utility Update Residual Count
7146 *
7147 * Description: Update the XferCnt to the remaining byte count.
7148 * If we transferred all the data then just write zero.
7149 * If Non-SG transfer then report Total Cnt - Actual Transfer
7150 * Cnt. For SG transfers add the count fields of all
7151 * remaining SG elements, as well as any partial remaining
7152 * element.
7153 *
7154 *---------------------------------------------------------------------*/
7155
7156static void FPT_utilUpdateResidual(struct sccb *p_SCCB)
7157{
7158 unsigned long partial_cnt;
7159 unsigned int sg_index;
7160 struct blogic_sg_seg *segp;
7161
7162 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7163
7164 p_SCCB->DataLength = 0x0000;
7165 }
7166
7167 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7168
7169 partial_cnt = 0x0000;
7170
7171 sg_index = p_SCCB->Sccb_sgseg;
7172
7173
7174 if (p_SCCB->Sccb_SGoffset) {
7175
7176 partial_cnt = p_SCCB->Sccb_SGoffset;
7177 sg_index++;
7178 }
7179
7180 while (((unsigned long)sg_index *
7181 (unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) {
7182 segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) +
7183 (sg_index * 2);
7184 partial_cnt += segp->segbytes;
7185 sg_index++;
7186 }
7187
7188 p_SCCB->DataLength = partial_cnt;
7189 }
7190
7191 else {
7192
7193 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7194 }
7195}
7196
7197/*---------------------------------------------------------------------
7198 *
7199 * Function: Wait 1 Second
7200 *
7201 * Description: Wait for 1 second.
7202 *
7203 *---------------------------------------------------------------------*/
7204
7205static void FPT_Wait1Second(u32 p_port)
7206{
7207 unsigned char i;
7208
7209 for (i = 0; i < 4; i++) {
7210
7211 FPT_Wait(p_port, TO_250ms);
7212
7213 if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7214 break;
7215
7216 if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7217 break;
7218 }
7219}
7220
7221/*---------------------------------------------------------------------
7222 *
7223 * Function: FPT_Wait
7224 *
7225 * Description: Wait the desired delay.
7226 *
7227 *---------------------------------------------------------------------*/
7228
7229static void FPT_Wait(u32 p_port, unsigned char p_delay)
7230{
7231 unsigned char old_timer;
7232 unsigned char green_flag;
7233
7234 old_timer = RD_HARPOON(p_port + hp_seltimeout);
7235
7236 green_flag = RD_HARPOON(p_port + hp_clkctrl_0);
7237 WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
7238
7239 WR_HARPOON(p_port + hp_seltimeout, p_delay);
7240 WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7241 WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT));
7242
7243 WR_HARPOON(p_port + hp_portctrl_0,
7244 (RD_HARPOON(p_port + hp_portctrl_0) | START_TO));
7245
7246 while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) {
7247
7248 if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7249 break;
7250
7251 if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7252 break;
7253 }
7254
7255 WR_HARPOON(p_port + hp_portctrl_0,
7256 (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO));
7257
7258 WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7259 WRW_HARPOON((p_port + hp_intena), FPT_default_intena);
7260
7261 WR_HARPOON(p_port + hp_clkctrl_0, green_flag);
7262
7263 WR_HARPOON(p_port + hp_seltimeout, old_timer);
7264}
7265
7266/*---------------------------------------------------------------------
7267 *
7268 * Function: Enable/Disable Write to EEPROM
7269 *
7270 * Description: The EEPROM must first be enabled for writes
7271 * A total of 9 clocks are needed.
7272 *
7273 *---------------------------------------------------------------------*/
7274
7275static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode)
7276{
7277 unsigned char ee_value;
7278
7279 ee_value =
7280 (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
7281 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7282
7283 if (p_mode)
7284
7285 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7286
7287 else
7288
7289 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7290
7291 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7292 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
7293}
7294
7295/*---------------------------------------------------------------------
7296 *
7297 * Function: Write EEPROM
7298 *
7299 * Description: Write a word to the EEPROM at the specified
7300 * address.
7301 *
7302 *---------------------------------------------------------------------*/
7303
7304static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
7305 unsigned short ee_addr)
7306{
7307
7308 unsigned char ee_value;
7309 unsigned short i;
7310
7311 ee_value =
7312 (unsigned
7313 char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7314 (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7315
7316 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7317
7318 ee_value |= (SEE_MS + SEE_CS);
7319
7320 for (i = 0x8000; i != 0; i >>= 1) {
7321
7322 if (i & ee_data)
7323 ee_value |= SEE_DO;
7324 else
7325 ee_value &= ~SEE_DO;
7326
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; /* Clock data! */
7330 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7331 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7332 ee_value &= ~SEE_CLK;
7333 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7334 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7335 }
7336 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7337 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));
7338
7339 FPT_Wait(p_port, TO_10ms);
7340
7341 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7342 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7343 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /* Turn off Master Select */
7344}
7345
7346/*---------------------------------------------------------------------
7347 *
7348 * Function: Read EEPROM
7349 *
7350 * Description: Read a word from the EEPROM at the desired
7351 * address.
7352 *
7353 *---------------------------------------------------------------------*/
7354
7355static unsigned short FPT_utilEERead(u32 p_port,
7356 unsigned short ee_addr)
7357{
7358 unsigned short i, ee_data1, ee_data2;
7359
7360 i = 0;
7361 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7362 do {
7363 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7364
7365 if (ee_data1 == ee_data2)
7366 return ee_data1;
7367
7368 ee_data1 = ee_data2;
7369 i++;
7370
7371 } while (i < 4);
7372
7373 return ee_data1;
7374}
7375
7376/*---------------------------------------------------------------------
7377 *
7378 * Function: Read EEPROM Original
7379 *
7380 * Description: Read a word from the EEPROM at the desired
7381 * address.
7382 *
7383 *---------------------------------------------------------------------*/
7384
7385static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr)
7386{
7387
7388 unsigned char ee_value;
7389 unsigned short i, ee_data;
7390
7391 ee_value =
7392 (unsigned
7393 char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7394 (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7395
7396 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7397
7398 ee_value |= (SEE_MS + SEE_CS);
7399 ee_data = 0;
7400
7401 for (i = 1; i <= 16; i++) {
7402
7403 ee_value |= SEE_CLK; /* Clock data! */
7404 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7405 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7406 ee_value &= ~SEE_CLK;
7407 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7408 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7409
7410 ee_data <<= 1;
7411
7412 if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI)
7413 ee_data |= 1;
7414 }
7415
7416 ee_value &= ~(SEE_MS + SEE_CS);
7417 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7418 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
7419
7420 return ee_data;
7421}
7422
7423/*---------------------------------------------------------------------
7424 *
7425 * Function: Send EE command and Address to the EEPROM
7426 *
7427 * Description: Transfers the correct command and sends the address
7428 * to the eeprom.
7429 *
7430 *---------------------------------------------------------------------*/
7431
7432static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
7433 unsigned short ee_addr)
7434{
7435 unsigned char ee_value;
7436 unsigned char narrow_flg;
7437
7438 unsigned short i;
7439
7440 narrow_flg =
7441 (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
7442 NARROW_SCSI_CARD);
7443
7444 ee_value = SEE_MS;
7445 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7446
7447 ee_value |= SEE_CS; /* Set CS to EEPROM */
7448 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7449
7450 for (i = 0x04; i != 0; i >>= 1) {
7451
7452 if (i & ee_cmd)
7453 ee_value |= SEE_DO;
7454 else
7455 ee_value &= ~SEE_DO;
7456
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; /* Clock data! */
7460 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7461 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7462 ee_value &= ~SEE_CLK;
7463 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7464 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7465 }
7466
7467 if (narrow_flg)
7468 i = 0x0080;
7469
7470 else
7471 i = 0x0200;
7472
7473 while (i != 0) {
7474
7475 if (i & ee_addr)
7476 ee_value |= SEE_DO;
7477 else
7478 ee_value &= ~SEE_DO;
7479
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; /* Clock data! */
7483 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7484 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7485 ee_value &= ~SEE_CLK;
7486 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7487 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7488
7489 i >>= 1;
7490 }
7491}
7492
7493static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7494{
7495 unsigned short crc = 0;
7496 int i, j;
7497 unsigned short ch;
7498 for (i = 0; i < ID_STRING_LENGTH; i++) {
7499 ch = (unsigned short)buffer[i];
7500 for (j = 0; j < 8; j++) {
7501 if ((crc ^ ch) & 1)
7502 crc = (crc >> 1) ^ CRCMASK;
7503 else
7504 crc >>= 1;
7505 ch >>= 1;
7506 }
7507 }
7508 return crc;
7509}
7510
7511static unsigned char FPT_CalcLrc(unsigned char buffer[])
7512{
7513 int i;
7514 unsigned char lrc;
7515 lrc = 0;
7516 for (i = 0; i < ID_STRING_LENGTH; i++)
7517 lrc ^= buffer[i];
7518 return lrc;
7519}
7520
7521/*
7522 The following inline definitions avoid type conflicts.
7523*/
7524
7525static inline unsigned char
7526FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo)
7527{
7528 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *)
7529 FlashPointInfo);
7530}
7531
7532static inline void *
7533FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo)
7534{
7535 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *)
7536 FlashPointInfo);
7537}
7538
7539static inline void
7540FlashPoint__ReleaseHostAdapter(void *CardHandle)
7541{
7542 FlashPoint_ReleaseHostAdapter(CardHandle);
7543}
7544
7545static inline void
7546FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB)
7547{
7548 FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB);
7549}
7550
7551static inline void
7552FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB)
7553{
7554 FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
7555}
7556
7557static inline bool
7558FlashPoint__InterruptPending(void *CardHandle)
7559{
7560 return FlashPoint_InterruptPending(CardHandle);
7561}
7562
7563static inline int
7564FlashPoint__HandleInterrupt(void *CardHandle)
7565{
7566 return FlashPoint_HandleInterrupt(CardHandle);
7567}
7568
7569#define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7570#define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7571#define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7572#define FlashPoint_StartCCB FlashPoint__StartCCB
7573#define FlashPoint_AbortCCB FlashPoint__AbortCCB
7574#define FlashPoint_InterruptPending FlashPoint__InterruptPending
7575#define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7576
7577#else /* !CONFIG_SCSI_FLASHPOINT */
7578
7579/*
7580 Define prototypes for the FlashPoint SCCB Manager Functions.
7581*/
7582
7583extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *);
7584extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *);
7585extern void FlashPoint_StartCCB(void *, struct blogic_ccb *);
7586extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *);
7587extern bool FlashPoint_InterruptPending(void *);
7588extern int FlashPoint_HandleInterrupt(void *);
7589extern void FlashPoint_ReleaseHostAdapter(void *);
7590
7591#endif /* CONFIG_SCSI_FLASHPOINT */