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