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