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