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