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