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