3 FlashPoint.c -- FlashPoint SCCB Manager for Linux
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.
11 Copyright 1995-1996 by Mylex Corporation. All Rights Reserved
13 This file is available under both the GNU General Public License
14 and a BSD-style copyright; see LICENSE.FlashPoint for details.
19 #ifndef CONFIG_SCSI_OMIT_FLASHPOINT
24 #define CRCMASK 0xA001
26 #define FAILURE 0xFFFFFFFFL
28 #define BITW(x) ((unsigned short)(1<<(x))) /* single-bit mask in bit position x */
31 typedef void (*CALL_BK_FN
) (struct sccb
*);
33 struct sccb_mgr_info
{
34 unsigned long si_baseaddr
;
35 unsigned char si_present
;
36 unsigned char si_intvect
;
39 unsigned short si_fw_revision
;
40 unsigned short si_per_targ_init_sync
;
41 unsigned short si_per_targ_fast_nego
;
42 unsigned short si_per_targ_ultra_nego
;
43 unsigned short si_per_targ_no_disc
;
44 unsigned short si_per_targ_wide_nego
;
45 unsigned short si_flags
;
46 unsigned char si_card_family
;
47 unsigned char si_bustype
;
48 unsigned char si_card_model
[3];
49 unsigned char si_relative_cardnum
;
50 unsigned char si_reserved
[4];
51 unsigned long si_OS_reserved
;
52 unsigned char si_XlatInfo
[4];
53 unsigned long si_reserved2
[5];
54 unsigned long si_secondary_range
;
57 #define SCSI_PARITY_ENA 0x0001
58 #define LOW_BYTE_TERM 0x0010
59 #define HIGH_BYTE_TERM 0x0020
60 #define BUSTYPE_PCI 0x3
62 #define SUPPORT_16TAR_32LUN 0x0002
63 #define SOFT_RESET 0x0004
64 #define EXTENDED_TRANSLATION 0x0008
65 #define POST_ALL_UNDERRRUNS 0x0040
66 #define FLAG_SCAM_ENABLED 0x0080
67 #define FLAG_SCAM_LEVEL2 0x0100
69 #define HARPOON_FAMILY 0x02
71 /* SCCB struct used for both SCCB and UCB manager compiles!
72 * The UCB Manager treats the SCCB as it's 'native hardware structure'
77 unsigned char OperationCode
;
78 unsigned char ControlByte
;
79 unsigned char CdbLength
;
80 unsigned char RequestSenseLength
;
81 unsigned long DataLength
;
82 unsigned long DataPointer
;
83 unsigned char CcbRes
[2];
84 unsigned char HostStatus
;
85 unsigned char TargetStatus
;
88 unsigned char Cdb
[12];
89 unsigned char CcbRes1
;
90 unsigned char Reserved1
;
91 unsigned long Reserved2
;
92 unsigned long SensePointer
;
94 CALL_BK_FN SccbCallback
; /* VOID (*SccbCallback)(); */
95 unsigned long SccbIOPort
; /* Identifies board base port */
96 unsigned char SccbStatus
;
97 unsigned char SCCBRes2
;
98 unsigned short SccbOSFlags
;
100 unsigned long Sccb_XferCnt
; /* actual transfer count */
101 unsigned long Sccb_ATC
;
102 unsigned long SccbVirtDataPtr
; /* virtual addr for OS/2 */
103 unsigned long Sccb_res1
;
104 unsigned short Sccb_MGRFlags
;
105 unsigned short Sccb_sgseg
;
106 unsigned char Sccb_scsimsg
; /* identify msg for selection */
107 unsigned char Sccb_tag
;
108 unsigned char Sccb_scsistat
;
109 unsigned char Sccb_idmsg
; /* image of last msg in */
110 struct sccb
*Sccb_forwardlink
;
111 struct sccb
*Sccb_backlink
;
112 unsigned long Sccb_savedATC
;
113 unsigned char Save_Cdb
[6];
114 unsigned char Save_CdbLen
;
115 unsigned char Sccb_XferState
;
116 unsigned long Sccb_SGoffset
;
121 #define SCATTER_GATHER_COMMAND 0x02
122 #define RESIDUAL_COMMAND 0x03
123 #define RESIDUAL_SG_COMMAND 0x04
124 #define RESET_COMMAND 0x81
126 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
127 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
128 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
129 #define SCCB_DATA_XFER_IN 0x08 /* Read */
131 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
133 #define BUS_FREE_ST 0
135 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
136 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
137 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
138 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
140 #define DATA_OUT_ST 7
142 #define DISCONNECT_ST 9
145 #define F_HOST_XFER_DIR 0x01
146 #define F_ALL_XFERRED 0x02
147 #define F_SG_XFER 0x04
148 #define F_AUTO_SENSE 0x08
149 #define F_ODD_BALL_CNT 0x10
150 #define F_NO_DATA_YET 0x80
152 #define F_STATUSLOADED 0x01
153 #define F_DEV_SELECTED 0x04
155 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
156 #define SCCB_DATA_UNDER_RUN 0x0C
157 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
158 #define SCCB_DATA_OVER_RUN 0x12
159 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
161 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
162 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
163 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
165 #define SCCB_IN_PROCESS 0x00
166 #define SCCB_SUCCESS 0x01
167 #define SCCB_ABORT 0x02
168 #define SCCB_ERROR 0x04
170 #define ORION_FW_REV 3110
172 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
174 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
176 #define MAX_SCSI_TAR 16
178 #define LUN_MASK 0x1f
180 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
182 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
184 #define RD_HARPOON(ioport) inb((u32)ioport)
185 #define RDW_HARPOON(ioport) inw((u32)ioport)
186 #define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
187 #define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
188 #define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
189 #define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
191 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
192 #define SYNC_TRYING BIT(6)
193 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
195 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
196 #define WIDE_ENABLED BIT(4)
197 #define WIDE_NEGOCIATED BIT(5)
199 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
200 #define TAG_Q_TRYING BIT(2)
201 #define TAG_Q_REJECT BIT(3)
203 #define TAR_ALLOW_DISC BIT(0)
205 #define EE_SYNC_MASK (BIT(0)+BIT(1))
206 #define EE_SYNC_5MB BIT(0)
207 #define EE_SYNC_10MB BIT(1)
208 #define EE_SYNC_20MB (BIT(0)+BIT(1))
210 #define EE_WIDE_SCSI BIT(7)
212 struct sccb_mgr_tar_info
{
214 struct sccb
*TarSelQ_Head
;
215 struct sccb
*TarSelQ_Tail
;
216 unsigned char TarLUN_CA
; /*Contingent Allgiance */
217 unsigned char TarTagQ_Cnt
;
218 unsigned char TarSelQ_Cnt
;
219 unsigned char TarStatus
;
220 unsigned char TarEEValue
;
221 unsigned char TarSyncCtrl
;
222 unsigned char TarReserved
[2]; /* for alignment */
223 unsigned char LunDiscQ_Idx
[MAX_LUN
];
224 unsigned char TarLUNBusy
[MAX_LUN
];
228 unsigned char niModel
; /* Model No. of card */
229 unsigned char niCardNo
; /* Card no. */
230 unsigned long niBaseAddr
; /* Port Address of card */
231 unsigned char niSysConf
; /* Adapter Configuration byte - Byte 16 of eeprom map */
232 unsigned char niScsiConf
; /* SCSI Configuration byte - Byte 17 of eeprom map */
233 unsigned char niScamConf
; /* SCAM Configuration byte - Byte 20 of eeprom map */
234 unsigned char niAdapId
; /* Host Adapter ID - Byte 24 of eerpom map */
235 unsigned char niSyncTbl
[MAX_SCSI_TAR
/ 2]; /* Sync/Wide byte of targets */
236 unsigned char niScamTbl
[MAX_SCSI_TAR
][4]; /* Compressed Scam name string of Targets */
245 struct sccb
*currentSCCB
;
246 struct sccb_mgr_info
*cardInfo
;
248 unsigned long ioPort
;
250 unsigned short cmdCounter
;
251 unsigned char discQCount
;
252 unsigned char tagQ_Lst
;
253 unsigned char cardIndex
;
254 unsigned char scanIndex
;
255 unsigned char globalFlags
;
257 struct nvram_info
*pNvRamInfo
;
258 struct sccb
*discQ_Tbl
[QUEUE_DEPTH
];
262 #define F_TAG_STARTED 0x01
263 #define F_CONLUN_IO 0x02
264 #define F_DO_RENEGO 0x04
265 #define F_NO_FILTER 0x08
266 #define F_GREEN_PC 0x10
267 #define F_HOST_XFER_ACT 0x20
268 #define F_NEW_SCCB_CMD 0x40
269 #define F_UPDATE_EEPROM 0x80
271 #define ID_STRING_LENGTH 32
272 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
274 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
276 #define ASSIGN_ID 0x00
277 #define SET_P_FLAG 0x01
278 #define CFG_CMPLT 0x03
279 #define DOM_MSTR 0x0F
280 #define SYNC_PTRN 0x1F
284 #define MISC_CODE 0x14
285 #define CLR_P_FLAG 0x18
287 #define INIT_SELTD 0x01
288 #define LEVEL2_TAR 0x02
290 enum scam_id_st
{ ID0
, ID1
, ID2
, ID3
, ID4
, ID5
, ID6
, ID7
, ID8
, ID9
, ID10
, ID11
,
292 ID13
, ID14
, ID15
, ID_UNUSED
, ID_UNASSIGNED
, ID_ASSIGNED
, LEGACY
,
293 CLR_PRIORITY
, NO_ID_AVAIL
296 typedef struct SCCBscam_info
{
298 unsigned char id_string
[ID_STRING_LENGTH
];
299 enum scam_id_st state
;
303 #define SCSI_REQUEST_SENSE 0x03
304 #define SCSI_READ 0x08
305 #define SCSI_WRITE 0x0A
306 #define SCSI_START_STOP_UNIT 0x1B
307 #define SCSI_READ_EXTENDED 0x28
308 #define SCSI_WRITE_EXTENDED 0x2A
309 #define SCSI_WRITE_AND_VERIFY 0x2E
313 #define SSQ_FULL 0x28
315 #define SMCMD_COMP 0x00
317 #define SMSAVE_DATA_PTR 0x02
318 #define SMREST_DATA_PTR 0x03
321 #define SMREJECT 0x07
323 #define SMPARITY 0x09
324 #define SMDEV_RESET 0x0C
325 #define SMABORT_TAG 0x0D
326 #define SMINIT_RECOVERY 0x0F
327 #define SMREL_RECOVERY 0x10
330 #define DISC_PRIV 0x40
336 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
338 #define SIX_BYTE_CMD 0x06
339 #define TWELVE_BYTE_CMD 0x0C
342 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
344 #define EEPROM_WD_CNT 256
346 #define EEPROM_CHECK_SUM 0
347 #define FW_SIGNATURE 2
348 #define MODEL_NUMB_0 4
349 #define MODEL_NUMB_2 6
350 #define MODEL_NUMB_4 8
351 #define SYSTEM_CONFIG 16
352 #define SCSI_CONFIG 17
353 #define BIOS_CONFIG 18
354 #define SCAM_CONFIG 20
355 #define ADAPTER_SCSI_ID 24
357 #define IGNORE_B_SCAN 32
358 #define SEND_START_ENA 34
359 #define DEVICE_ENABLE 36
361 #define SYNC_RATE_TBL 38
362 #define SYNC_RATE_TBL01 38
363 #define SYNC_RATE_TBL23 40
364 #define SYNC_RATE_TBL45 42
365 #define SYNC_RATE_TBL67 44
366 #define SYNC_RATE_TBL89 46
367 #define SYNC_RATE_TBLab 48
368 #define SYNC_RATE_TBLcd 50
369 #define SYNC_RATE_TBLef 52
371 #define EE_SCAMBASE 256
373 #define SCAM_ENABLED BIT(2)
374 #define SCAM_LEVEL2 BIT(3)
376 #define RENEGO_ENA BITW(10)
377 #define CONNIO_ENA BITW(11)
378 #define GREEN_PC_ENA BITW(12)
380 #define AUTO_RATE_00 00
381 #define AUTO_RATE_05 01
382 #define AUTO_RATE_10 02
383 #define AUTO_RATE_20 03
385 #define WIDE_NEGO_BIT BIT(7)
386 #define DISC_ENABLE_BIT BIT(6)
388 #define hp_vendor_id_0 0x00 /* LSB */
389 #define ORION_VEND_0 0x4B
391 #define hp_vendor_id_1 0x01 /* MSB */
392 #define ORION_VEND_1 0x10
394 #define hp_device_id_0 0x02 /* LSB */
395 #define ORION_DEV_0 0x30
397 #define hp_device_id_1 0x03 /* MSB */
398 #define ORION_DEV_1 0x81
400 /* Sub Vendor ID and Sub Device ID only available in
401 Harpoon Version 2 and higher */
403 #define hp_sub_device_id_0 0x06 /* LSB */
405 #define hp_semaphore 0x0C
406 #define SCCB_MGR_ACTIVE BIT(0)
407 #define TICKLE_ME BIT(1)
408 #define SCCB_MGR_PRESENT BIT(3)
409 #define BIOS_IN_USE BIT(4)
411 #define hp_sys_ctrl 0x0F
413 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
414 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
415 #define HALT_MACH BIT(3) /*Halt State Machine */
416 #define HARD_ABORT BIT(4) /*Hard Abort */
418 #define hp_host_blk_cnt 0x13
420 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block */
422 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes */
424 #define hp_int_mask 0x17
426 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
427 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
429 #define hp_xfer_cnt_lo 0x18
430 #define hp_xfer_cnt_hi 0x1A
431 #define hp_xfer_cmd 0x1B
433 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
434 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
436 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
438 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
440 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
442 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
443 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
445 #define hp_host_addr_lo 0x1C
446 #define hp_host_addr_hmi 0x1E
448 #define hp_ee_ctrl 0x22
450 #define EXT_ARB_ACK BIT(7)
451 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
452 #define SEE_MS BIT(5)
453 #define SEE_CS BIT(3)
454 #define SEE_CLK BIT(2)
455 #define SEE_DO BIT(1)
456 #define SEE_DI BIT(0)
459 #define EE_WRITE 0x05
461 #define EWEN_ADDR 0x03C0
463 #define EWDS_ADDR 0x0000
465 #define hp_bm_ctrl 0x26
467 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
468 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
469 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
470 #define FAST_SINGLE BIT(6) /*?? */
472 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
474 #define hp_sg_addr 0x28
475 #define hp_page_ctrl 0x29
477 #define SCATTER_EN BIT(0)
478 #define SGRAM_ARAM BIT(1)
479 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
480 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
482 #define hp_pci_stat_cfg 0x2D
484 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
486 #define hp_rev_num 0x33
488 #define hp_stack_data 0x34
489 #define hp_stack_addr 0x35
491 #define hp_ext_status 0x36
493 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
494 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
495 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
496 #define CMD_ABORTED BIT(4) /*Command aborted */
497 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
498 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
499 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
500 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
501 BM_PARITY_ERR | PIO_OVERRUN)
503 #define hp_int_status 0x37
505 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
506 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
507 #define INT_ASSERTED BIT(5) /* */
509 #define hp_fifo_cnt 0x38
511 #define hp_intena 0x40
513 #define RESET BITW(7)
514 #define PROG_HLT BITW(6)
515 #define PARITY BITW(5)
518 #define SCAM_SEL BITW(2)
520 #define TIMEOUT BITW(0)
521 #define BUS_FREE BITW(15)
522 #define XFER_CNT_0 BITW(14)
523 #define PHASE BITW(13)
524 #define IUNKWN BITW(12)
525 #define ICMD_COMP BITW(11)
526 #define ITICKLE BITW(10)
527 #define IDO_STRT BITW(9)
528 #define ITAR_DISC BITW(8)
529 #define AUTO_INT (BITW(12)+BITW(11)+BITW(10)+BITW(9)+BITW(8))
530 #define CLR_ALL_INT 0xFFFF
531 #define CLR_ALL_INT_1 0xFF00
533 #define hp_intstat 0x42
535 #define hp_scsisig 0x44
537 #define SCSI_SEL BIT(7)
538 #define SCSI_BSY BIT(6)
539 #define SCSI_REQ BIT(5)
540 #define SCSI_ACK BIT(4)
541 #define SCSI_ATN BIT(3)
542 #define SCSI_CD BIT(2)
543 #define SCSI_MSG BIT(1)
544 #define SCSI_IOBIT BIT(0)
546 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
547 #define S_MSGO_PH (BIT(2)+BIT(1) )
548 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
549 #define S_DATAI_PH ( BIT(0))
550 #define S_DATAO_PH 0x00
551 #define S_ILL_PH ( BIT(1) )
553 #define hp_scsictrl_0 0x45
555 #define SEL_TAR BIT(6)
556 #define ENA_ATN BIT(4)
557 #define ENA_RESEL BIT(2)
558 #define SCSI_RST BIT(1)
559 #define ENA_SCAM_SEL BIT(0)
561 #define hp_portctrl_0 0x46
563 #define SCSI_PORT BIT(7)
564 #define SCSI_INBIT BIT(6)
565 #define DMA_PORT BIT(5)
566 #define DMA_RD BIT(4)
567 #define HOST_PORT BIT(3)
568 #define HOST_WRT BIT(2)
569 #define SCSI_BUS_EN BIT(1)
570 #define START_TO BIT(0)
572 #define hp_scsireset 0x47
574 #define SCSI_INI BIT(6)
575 #define SCAM_EN BIT(5)
576 #define DMA_RESET BIT(3)
577 #define HPSCSI_RESET BIT(2)
578 #define PROG_RESET BIT(1)
579 #define FIFO_CLR BIT(0)
581 #define hp_xfercnt_0 0x48
582 #define hp_xfercnt_2 0x4A
584 #define hp_fifodata_0 0x4C
585 #define hp_addstat 0x4E
587 #define SCAM_TIMER BIT(7)
588 #define SCSI_MODE8 BIT(3)
589 #define SCSI_PAR_ERR BIT(0)
591 #define hp_prgmcnt_0 0x4F
593 #define hp_selfid_0 0x50
594 #define hp_selfid_1 0x51
595 #define hp_arb_id 0x52
597 #define hp_select_id 0x53
599 #define hp_synctarg_base 0x54
600 #define hp_synctarg_12 0x54
601 #define hp_synctarg_13 0x55
602 #define hp_synctarg_14 0x56
603 #define hp_synctarg_15 0x57
605 #define hp_synctarg_8 0x58
606 #define hp_synctarg_9 0x59
607 #define hp_synctarg_10 0x5A
608 #define hp_synctarg_11 0x5B
610 #define hp_synctarg_4 0x5C
611 #define hp_synctarg_5 0x5D
612 #define hp_synctarg_6 0x5E
613 #define hp_synctarg_7 0x5F
615 #define hp_synctarg_0 0x60
616 #define hp_synctarg_1 0x61
617 #define hp_synctarg_2 0x62
618 #define hp_synctarg_3 0x63
620 #define NARROW_SCSI BIT(4)
621 #define DEFAULT_OFFSET 0x0F
623 #define hp_autostart_0 0x64
624 #define hp_autostart_1 0x65
625 #define hp_autostart_3 0x67
627 #define AUTO_IMMED BIT(5)
628 #define SELECT BIT(6)
629 #define END_DATA (BIT(7)+BIT(6))
631 #define hp_gp_reg_0 0x68
632 #define hp_gp_reg_1 0x69
633 #define hp_gp_reg_3 0x6B
635 #define hp_seltimeout 0x6C
637 #define TO_4ms 0x67 /* 3.9959ms */
639 #define TO_5ms 0x03 /* 4.9152ms */
640 #define TO_10ms 0x07 /* 11.xxxms */
641 #define TO_250ms 0x99 /* 250.68ms */
642 #define TO_290ms 0xB1 /* 289.99ms */
644 #define hp_clkctrl_0 0x6D
646 #define PWR_DWN BIT(6)
647 #define ACTdeassert BIT(4)
648 #define CLK_40MHZ (BIT(1) + BIT(0))
650 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
652 #define hp_fiforead 0x6E
653 #define hp_fifowrite 0x6F
655 #define hp_offsetctr 0x70
656 #define hp_xferstat 0x71
658 #define FIFO_EMPTY BIT(6)
660 #define hp_portctrl_1 0x72
662 #define CHK_SCSI_P BIT(3)
663 #define HOST_MODE8 BIT(0)
665 #define hp_xfer_pad 0x73
667 #define ID_UNLOCK BIT(3)
669 #define hp_scsidata_0 0x74
670 #define hp_scsidata_1 0x75
672 #define hp_aramBase 0x80
673 #define BIOS_DATA_OFFSET 0x60
674 #define BIOS_RELATIVE_CARD 0x64
676 #define AR3 (BITW(9) + BITW(8))
677 #define SDATA BITW(10)
679 #define CRD_OP BITW(11) /* Cmp Reg. w/ Data */
681 #define CRR_OP BITW(12) /* Cmp Reg. w. Reg. */
683 #define CPE_OP (BITW(14)+BITW(11)) /* Cmp SCSI phs & Branch EQ */
685 #define CPN_OP (BITW(14)+BITW(12)) /* Cmp SCSI phs & Branch NOT EQ */
687 #define ADATA_OUT 0x00
688 #define ADATA_IN BITW(8)
689 #define ACOMMAND BITW(10)
690 #define ASTATUS (BITW(10)+BITW(8))
691 #define AMSG_OUT (BITW(10)+BITW(9))
692 #define AMSG_IN (BITW(10)+BITW(9)+BITW(8))
694 #define BRH_OP BITW(13) /* Branch */
697 #define EQUAL BITW(8)
698 #define NOT_EQ BITW(9)
700 #define TCB_OP (BITW(13)+BITW(11)) /* Test condition & branch */
702 #define FIFO_0 BITW(10)
704 #define MPM_OP BITW(15) /* Match phase and move data */
706 #define MRR_OP BITW(14) /* Move DReg. to Reg. */
708 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
712 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
714 #define RAT_OP (BITW(14)+BITW(13)+BITW(11))
716 #define SSI_OP (BITW(15)+BITW(11))
718 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
719 #define SSI_IDO_STRT (IDO_STRT >> 8)
721 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
722 #define SSI_ITICKLE (ITICKLE >> 8)
724 #define SSI_IUNKWN (IUNKWN >> 8)
725 #define SSI_INO_CC (IUNKWN >> 8)
726 #define SSI_IRFAIL (IUNKWN >> 8)
728 #define NP 0x10 /*Next Phase */
729 #define NTCMD 0x02 /*Non- Tagged Command start */
730 #define CMDPZ 0x04 /*Command phase */
731 #define DINT 0x12 /*Data Out/In interrupt */
732 #define DI 0x13 /*Data Out */
733 #define DC 0x19 /*Disconnect Message */
734 #define ST 0x1D /*Status Phase */
735 #define UNKNWN 0x24 /*Unknown bus action */
736 #define CC 0x25 /*Command Completion failure */
737 #define TICK 0x26 /*New target reselected us. */
738 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
740 #define ID_MSG_STRT hp_aramBase + 0x00
741 #define NON_TAG_ID_MSG hp_aramBase + 0x06
742 #define CMD_STRT hp_aramBase + 0x08
743 #define SYNC_MSGS hp_aramBase + 0x08
745 #define TAG_STRT 0x00
746 #define DISCONNECT_START 0x10/2
747 #define END_DATA_START 0x14/2
748 #define CMD_ONLY_STRT CMDPZ/2
749 #define SELCHK_STRT SELCHK/2
751 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
752 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
754 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
756 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
758 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
759 WR_HARP32(port,hp_xfercnt_0,count),\
760 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
762 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
764 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
765 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
767 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
768 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
770 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
771 WR_HARPOON(port+hp_scsireset, 0x00))
773 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
774 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
776 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
777 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
779 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
780 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
782 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
783 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
785 static unsigned char FPT_sisyncn(unsigned long port
, unsigned char p_card
,
786 unsigned char syncFlag
);
787 static void FPT_ssel(unsigned long port
, unsigned char p_card
);
788 static void FPT_sres(unsigned long port
, unsigned char p_card
,
789 struct sccb_card
*pCurrCard
);
790 static void FPT_shandem(unsigned long port
, unsigned char p_card
,
791 struct sccb
*pCurrSCCB
);
792 static void FPT_stsyncn(unsigned long port
, unsigned char p_card
);
793 static void FPT_sisyncr(unsigned long port
, unsigned char sync_pulse
,
794 unsigned char offset
);
795 static void FPT_sssyncv(unsigned long p_port
, unsigned char p_id
,
796 unsigned char p_sync_value
,
797 struct sccb_mgr_tar_info
*currTar_Info
);
798 static void FPT_sresb(unsigned long port
, unsigned char p_card
);
799 static void FPT_sxfrp(unsigned long p_port
, unsigned char p_card
);
800 static void FPT_schkdd(unsigned long port
, unsigned char p_card
);
801 static unsigned char FPT_RdStack(unsigned long port
, unsigned char index
);
802 static void FPT_WrStack(unsigned long portBase
, unsigned char index
,
804 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort
);
806 static void FPT_SendMsg(unsigned long port
, unsigned char message
);
807 static void FPT_queueFlushTargSccb(unsigned char p_card
, unsigned char thisTarg
,
808 unsigned char error_code
);
810 static void FPT_sinits(struct sccb
*p_sccb
, unsigned char p_card
);
811 static void FPT_RNVRamData(struct nvram_info
*pNvRamInfo
);
813 static unsigned char FPT_siwidn(unsigned long port
, unsigned char p_card
);
814 static void FPT_stwidn(unsigned long port
, unsigned char p_card
);
815 static void FPT_siwidr(unsigned long port
, unsigned char width
);
817 static void FPT_queueSelectFail(struct sccb_card
*pCurrCard
,
818 unsigned char p_card
);
819 static void FPT_queueDisconnect(struct sccb
*p_SCCB
, unsigned char p_card
);
820 static void FPT_queueCmdComplete(struct sccb_card
*pCurrCard
,
821 struct sccb
*p_SCCB
, unsigned char p_card
);
822 static void FPT_queueSearchSelect(struct sccb_card
*pCurrCard
,
823 unsigned char p_card
);
824 static void FPT_queueFlushSccb(unsigned char p_card
, unsigned char error_code
);
825 static void FPT_queueAddSccb(struct sccb
*p_SCCB
, unsigned char card
);
826 static unsigned char FPT_queueFindSccb(struct sccb
*p_SCCB
,
827 unsigned char p_card
);
828 static void FPT_utilUpdateResidual(struct sccb
*p_SCCB
);
829 static unsigned short FPT_CalcCrc16(unsigned char buffer
[]);
830 static unsigned char FPT_CalcLrc(unsigned char buffer
[]);
832 static void FPT_Wait1Second(unsigned long p_port
);
833 static void FPT_Wait(unsigned long p_port
, unsigned char p_delay
);
834 static void FPT_utilEEWriteOnOff(unsigned long p_port
, unsigned char p_mode
);
835 static void FPT_utilEEWrite(unsigned long p_port
, unsigned short ee_data
,
836 unsigned short ee_addr
);
837 static unsigned short FPT_utilEERead(unsigned long p_port
,
838 unsigned short ee_addr
);
839 static unsigned short FPT_utilEEReadOrg(unsigned long p_port
,
840 unsigned short ee_addr
);
841 static void FPT_utilEESendCmdAddr(unsigned long p_port
, unsigned char ee_cmd
,
842 unsigned short ee_addr
);
844 static void FPT_phaseDataOut(unsigned long port
, unsigned char p_card
);
845 static void FPT_phaseDataIn(unsigned long port
, unsigned char p_card
);
846 static void FPT_phaseCommand(unsigned long port
, unsigned char p_card
);
847 static void FPT_phaseStatus(unsigned long port
, unsigned char p_card
);
848 static void FPT_phaseMsgOut(unsigned long port
, unsigned char p_card
);
849 static void FPT_phaseMsgIn(unsigned long port
, unsigned char p_card
);
850 static void FPT_phaseIllegal(unsigned long port
, unsigned char p_card
);
852 static void FPT_phaseDecode(unsigned long port
, unsigned char p_card
);
853 static void FPT_phaseChkFifo(unsigned long port
, unsigned char p_card
);
854 static void FPT_phaseBusFree(unsigned long p_port
, unsigned char p_card
);
856 static void FPT_XbowInit(unsigned long port
, unsigned char scamFlg
);
857 static void FPT_BusMasterInit(unsigned long p_port
);
858 static void FPT_DiagEEPROM(unsigned long p_port
);
860 static void FPT_dataXferProcessor(unsigned long port
,
861 struct sccb_card
*pCurrCard
);
862 static void FPT_busMstrSGDataXferStart(unsigned long port
,
863 struct sccb
*pCurrSCCB
);
864 static void FPT_busMstrDataXferStart(unsigned long port
,
865 struct sccb
*pCurrSCCB
);
866 static void FPT_hostDataXferAbort(unsigned long port
, unsigned char p_card
,
867 struct sccb
*pCurrSCCB
);
868 static void FPT_hostDataXferRestart(struct sccb
*currSCCB
);
870 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port
,
871 unsigned char p_card
,
872 struct sccb_card
*pCurrCard
,
873 unsigned short p_int
);
875 static void FPT_SccbMgrTableInitAll(void);
876 static void FPT_SccbMgrTableInitCard(struct sccb_card
*pCurrCard
,
877 unsigned char p_card
);
878 static void FPT_SccbMgrTableInitTarget(unsigned char p_card
,
879 unsigned char target
);
881 static void FPT_scini(unsigned char p_card
, unsigned char p_our_id
,
882 unsigned char p_power_up
);
884 static int FPT_scarb(unsigned long p_port
, unsigned char p_sel_type
);
885 static void FPT_scbusf(unsigned long p_port
);
886 static void FPT_scsel(unsigned long p_port
);
887 static void FPT_scasid(unsigned char p_card
, unsigned long p_port
);
888 static unsigned char FPT_scxferc(unsigned long p_port
, unsigned char p_data
);
889 static unsigned char FPT_scsendi(unsigned long p_port
,
890 unsigned char p_id_string
[]);
891 static unsigned char FPT_sciso(unsigned long p_port
,
892 unsigned char p_id_string
[]);
893 static void FPT_scwirod(unsigned long p_port
, unsigned char p_data_bit
);
894 static void FPT_scwiros(unsigned long p_port
, unsigned char p_data_bit
);
895 static unsigned char FPT_scvalq(unsigned char p_quintet
);
896 static unsigned char FPT_scsell(unsigned long p_port
, unsigned char targ_id
);
897 static void FPT_scwtsel(unsigned long p_port
);
898 static void FPT_inisci(unsigned char p_card
, unsigned long p_port
,
899 unsigned char p_our_id
);
900 static void FPT_scsavdi(unsigned char p_card
, unsigned long p_port
);
901 static unsigned char FPT_scmachid(unsigned char p_card
,
902 unsigned char p_id_string
[]);
904 static void FPT_autoCmdCmplt(unsigned long p_port
, unsigned char p_card
);
905 static void FPT_autoLoadDefaultMap(unsigned long p_port
);
907 static struct sccb_mgr_tar_info FPT_sccbMgrTbl
[MAX_CARDS
][MAX_SCSI_TAR
] =
909 static struct sccb_card FPT_BL_Card
[MAX_CARDS
] = { {0} };
910 static SCCBSCAM_INFO FPT_scamInfo
[MAX_SCSI_TAR
] = { {{0}} };
911 static struct nvram_info FPT_nvRamInfo
[MAX_MB_CARDS
] = { {0} };
913 static unsigned char FPT_mbCards
= 0;
914 static unsigned char FPT_scamHAString
[] =
915 { 0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C',
916 ' ', 'B', 'T', '-', '9', '3', '0',
917 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
918 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
921 static unsigned short FPT_default_intena
= 0;
923 static void (*FPT_s_PhaseTbl
[8]) (unsigned long, unsigned char) = {
926 /*---------------------------------------------------------------------
928 * Function: FlashPoint_ProbeHostAdapter
930 * Description: Setup and/or Search for cards and return info to caller.
932 *---------------------------------------------------------------------*/
934 static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info
*pCardInfo
)
936 static unsigned char first_time
= 1;
938 unsigned char i
, j
, id
, ScamFlg
;
939 unsigned short temp
, temp2
, temp3
, temp4
, temp5
, temp6
;
940 unsigned long ioport
;
941 struct nvram_info
*pCurrNvRam
;
943 ioport
= pCardInfo
->si_baseaddr
;
945 if (RD_HARPOON(ioport
+ hp_vendor_id_0
) != ORION_VEND_0
)
948 if ((RD_HARPOON(ioport
+ hp_vendor_id_1
) != ORION_VEND_1
))
951 if ((RD_HARPOON(ioport
+ hp_device_id_0
) != ORION_DEV_0
))
954 if ((RD_HARPOON(ioport
+ hp_device_id_1
) != ORION_DEV_1
))
957 if (RD_HARPOON(ioport
+ hp_rev_num
) != 0x0f) {
959 /* For new Harpoon then check for sub_device ID LSB
960 the bits(0-3) must be all ZERO for compatible with
961 current version of SCCBMgr, else skip this Harpoon
964 if (RD_HARPOON(ioport
+ hp_sub_device_id_0
) & 0x0f)
969 FPT_SccbMgrTableInitAll();
974 if (FPT_RdStack(ioport
, 0) != 0x00) {
975 if (FPT_ChkIfChipInitialized(ioport
) == 0) {
977 WR_HARPOON(ioport
+ hp_semaphore
, 0x00);
978 FPT_XbowInit(ioport
, 0); /*Must Init the SCSI before attempting */
979 FPT_DiagEEPROM(ioport
);
981 if (FPT_mbCards
< MAX_MB_CARDS
) {
982 pCurrNvRam
= &FPT_nvRamInfo
[FPT_mbCards
];
984 pCurrNvRam
->niBaseAddr
= ioport
;
985 FPT_RNVRamData(pCurrNvRam
);
992 WR_HARPOON(ioport
+ hp_clkctrl_0
, CLKCTRL_DEFAULT
);
993 WR_HARPOON(ioport
+ hp_sys_ctrl
, 0x00);
996 pCardInfo
->si_id
= pCurrNvRam
->niAdapId
;
1000 char)(FPT_utilEERead(ioport
,
1002 2)) & (unsigned char)0x0FF);
1004 pCardInfo
->si_lun
= 0x00;
1005 pCardInfo
->si_fw_revision
= ORION_FW_REV
;
1012 for (id
= 0; id
< (16 / 2); id
++) {
1015 temp
= (unsigned short)pCurrNvRam
->niSyncTbl
[id
];
1016 temp
= ((temp
& 0x03) + ((temp
<< 4) & 0xc0)) +
1017 (((temp
<< 4) & 0x0300) + ((temp
<< 8) & 0xc000));
1020 FPT_utilEERead(ioport
,
1021 (unsigned short)((SYNC_RATE_TBL
/ 2)
1024 for (i
= 0; i
< 2; temp
>>= 8, i
++) {
1031 switch (temp
& 0x3) {
1032 case AUTO_RATE_20
: /* Synchronous, 20 mega-transfers/second */
1033 temp6
|= 0x8000; /* Fall through */
1034 case AUTO_RATE_10
: /* Synchronous, 10 mega-transfers/second */
1035 temp5
|= 0x8000; /* Fall through */
1036 case AUTO_RATE_05
: /* Synchronous, 5 mega-transfers/second */
1037 temp2
|= 0x8000; /* Fall through */
1038 case AUTO_RATE_00
: /* Asynchronous */
1042 if (temp
& DISC_ENABLE_BIT
)
1045 if (temp
& WIDE_NEGO_BIT
)
1051 pCardInfo
->si_per_targ_init_sync
= temp2
;
1052 pCardInfo
->si_per_targ_no_disc
= temp3
;
1053 pCardInfo
->si_per_targ_wide_nego
= temp4
;
1054 pCardInfo
->si_per_targ_fast_nego
= temp5
;
1055 pCardInfo
->si_per_targ_ultra_nego
= temp6
;
1058 i
= pCurrNvRam
->niSysConf
;
1061 char)(FPT_utilEERead(ioport
, (SYSTEM_CONFIG
/ 2)));
1064 ScamFlg
= pCurrNvRam
->niScamConf
;
1067 (unsigned char)FPT_utilEERead(ioport
, SCAM_CONFIG
/ 2);
1069 pCardInfo
->si_flags
= 0x0000;
1072 pCardInfo
->si_flags
|= SCSI_PARITY_ENA
;
1075 pCardInfo
->si_flags
|= SOFT_RESET
;
1078 pCardInfo
->si_flags
|= EXTENDED_TRANSLATION
;
1080 if (ScamFlg
& SCAM_ENABLED
)
1081 pCardInfo
->si_flags
|= FLAG_SCAM_ENABLED
;
1083 if (ScamFlg
& SCAM_LEVEL2
)
1084 pCardInfo
->si_flags
|= FLAG_SCAM_LEVEL2
;
1086 j
= (RD_HARPOON(ioport
+ hp_bm_ctrl
) & ~SCSI_TERM_ENA_L
);
1088 j
|= SCSI_TERM_ENA_L
;
1090 WR_HARPOON(ioport
+ hp_bm_ctrl
, j
);
1092 j
= (RD_HARPOON(ioport
+ hp_ee_ctrl
) & ~SCSI_TERM_ENA_H
);
1094 j
|= SCSI_TERM_ENA_H
;
1096 WR_HARPOON(ioport
+ hp_ee_ctrl
, j
);
1098 if (!(RD_HARPOON(ioport
+ hp_page_ctrl
) & NARROW_SCSI_CARD
))
1100 pCardInfo
->si_flags
|= SUPPORT_16TAR_32LUN
;
1102 pCardInfo
->si_card_family
= HARPOON_FAMILY
;
1103 pCardInfo
->si_bustype
= BUSTYPE_PCI
;
1106 pCardInfo
->si_card_model
[0] = '9';
1107 switch (pCurrNvRam
->niModel
& 0x0f) {
1109 pCardInfo
->si_card_model
[1] = '3';
1110 pCardInfo
->si_card_model
[2] = '0';
1113 pCardInfo
->si_card_model
[1] = '5';
1114 pCardInfo
->si_card_model
[2] = '0';
1117 pCardInfo
->si_card_model
[1] = '3';
1118 pCardInfo
->si_card_model
[2] = '2';
1121 pCardInfo
->si_card_model
[1] = '5';
1122 pCardInfo
->si_card_model
[2] = '2';
1126 temp
= FPT_utilEERead(ioport
, (MODEL_NUMB_0
/ 2));
1127 pCardInfo
->si_card_model
[0] = (unsigned char)(temp
>> 8);
1128 temp
= FPT_utilEERead(ioport
, (MODEL_NUMB_2
/ 2));
1130 pCardInfo
->si_card_model
[1] = (unsigned char)(temp
& 0x00FF);
1131 pCardInfo
->si_card_model
[2] = (unsigned char)(temp
>> 8);
1134 if (pCardInfo
->si_card_model
[1] == '3') {
1135 if (RD_HARPOON(ioport
+ hp_ee_ctrl
) & BIT(7))
1136 pCardInfo
->si_flags
|= LOW_BYTE_TERM
;
1137 } else if (pCardInfo
->si_card_model
[2] == '0') {
1138 temp
= RD_HARPOON(ioport
+ hp_xfer_pad
);
1139 WR_HARPOON(ioport
+ hp_xfer_pad
, (temp
& ~BIT(4)));
1140 if (RD_HARPOON(ioport
+ hp_ee_ctrl
) & BIT(7))
1141 pCardInfo
->si_flags
|= LOW_BYTE_TERM
;
1142 WR_HARPOON(ioport
+ hp_xfer_pad
, (temp
| BIT(4)));
1143 if (RD_HARPOON(ioport
+ hp_ee_ctrl
) & BIT(7))
1144 pCardInfo
->si_flags
|= HIGH_BYTE_TERM
;
1145 WR_HARPOON(ioport
+ hp_xfer_pad
, temp
);
1147 temp
= RD_HARPOON(ioport
+ hp_ee_ctrl
);
1148 temp2
= RD_HARPOON(ioport
+ hp_xfer_pad
);
1149 WR_HARPOON(ioport
+ hp_ee_ctrl
, (temp
| SEE_CS
));
1150 WR_HARPOON(ioport
+ hp_xfer_pad
, (temp2
| BIT(4)));
1152 for (i
= 0; i
< 8; i
++) {
1154 if (!(RD_HARPOON(ioport
+ hp_ee_ctrl
) & BIT(7)))
1156 WR_HARPOON(ioport
+ hp_xfer_pad
, (temp2
& ~BIT(4)));
1157 WR_HARPOON(ioport
+ hp_xfer_pad
, (temp2
| BIT(4)));
1159 WR_HARPOON(ioport
+ hp_ee_ctrl
, temp
);
1160 WR_HARPOON(ioport
+ hp_xfer_pad
, temp2
);
1161 if (!(temp3
& BIT(7)))
1162 pCardInfo
->si_flags
|= LOW_BYTE_TERM
;
1163 if (!(temp3
& BIT(6)))
1164 pCardInfo
->si_flags
|= HIGH_BYTE_TERM
;
1167 ARAM_ACCESS(ioport
);
1169 for (i
= 0; i
< 4; i
++) {
1171 pCardInfo
->si_XlatInfo
[i
] =
1172 RD_HARPOON(ioport
+ hp_aramBase
+ BIOS_DATA_OFFSET
+ i
);
1175 /* return with -1 if no sort, else return with
1176 logical card number sorted by BIOS (zero-based) */
1178 pCardInfo
->si_relative_cardnum
=
1180 char)(RD_HARPOON(ioport
+ hp_aramBase
+ BIOS_RELATIVE_CARD
) - 1);
1182 SGRAM_ACCESS(ioport
);
1184 FPT_s_PhaseTbl
[0] = FPT_phaseDataOut
;
1185 FPT_s_PhaseTbl
[1] = FPT_phaseDataIn
;
1186 FPT_s_PhaseTbl
[2] = FPT_phaseIllegal
;
1187 FPT_s_PhaseTbl
[3] = FPT_phaseIllegal
;
1188 FPT_s_PhaseTbl
[4] = FPT_phaseCommand
;
1189 FPT_s_PhaseTbl
[5] = FPT_phaseStatus
;
1190 FPT_s_PhaseTbl
[6] = FPT_phaseMsgOut
;
1191 FPT_s_PhaseTbl
[7] = FPT_phaseMsgIn
;
1193 pCardInfo
->si_present
= 0x01;
1198 /*---------------------------------------------------------------------
1200 * Function: FlashPoint_HardwareResetHostAdapter
1202 * Description: Setup adapter for normal operation (hard reset).
1204 *---------------------------------------------------------------------*/
1206 static unsigned long FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
1209 struct sccb_card
*CurrCard
= NULL
;
1210 struct nvram_info
*pCurrNvRam
;
1211 unsigned char i
, j
, thisCard
, ScamFlg
;
1212 unsigned short temp
, sync_bit_map
, id
;
1213 unsigned long ioport
;
1215 ioport
= pCardInfo
->si_baseaddr
;
1217 for (thisCard
= 0; thisCard
<= MAX_CARDS
; thisCard
++) {
1219 if (thisCard
== MAX_CARDS
) {
1224 if (FPT_BL_Card
[thisCard
].ioPort
== ioport
) {
1226 CurrCard
= &FPT_BL_Card
[thisCard
];
1227 FPT_SccbMgrTableInitCard(CurrCard
, thisCard
);
1231 else if (FPT_BL_Card
[thisCard
].ioPort
== 0x00) {
1233 FPT_BL_Card
[thisCard
].ioPort
= ioport
;
1234 CurrCard
= &FPT_BL_Card
[thisCard
];
1237 for (i
= 0; i
< FPT_mbCards
; i
++) {
1238 if (CurrCard
->ioPort
==
1239 FPT_nvRamInfo
[i
].niBaseAddr
)
1240 CurrCard
->pNvRamInfo
=
1243 FPT_SccbMgrTableInitCard(CurrCard
, thisCard
);
1244 CurrCard
->cardIndex
= thisCard
;
1245 CurrCard
->cardInfo
= pCardInfo
;
1251 pCurrNvRam
= CurrCard
->pNvRamInfo
;
1254 ScamFlg
= pCurrNvRam
->niScamConf
;
1257 (unsigned char)FPT_utilEERead(ioport
, SCAM_CONFIG
/ 2);
1260 FPT_BusMasterInit(ioport
);
1261 FPT_XbowInit(ioport
, ScamFlg
);
1263 FPT_autoLoadDefaultMap(ioport
);
1265 for (i
= 0, id
= 0x01; i
!= pCardInfo
->si_id
; i
++, id
<<= 1) {
1268 WR_HARPOON(ioport
+ hp_selfid_0
, id
);
1269 WR_HARPOON(ioport
+ hp_selfid_1
, 0x00);
1270 WR_HARPOON(ioport
+ hp_arb_id
, pCardInfo
->si_id
);
1271 CurrCard
->ourId
= pCardInfo
->si_id
;
1273 i
= (unsigned char)pCardInfo
->si_flags
;
1274 if (i
& SCSI_PARITY_ENA
)
1275 WR_HARPOON(ioport
+ hp_portctrl_1
, (HOST_MODE8
| CHK_SCSI_P
));
1277 j
= (RD_HARPOON(ioport
+ hp_bm_ctrl
) & ~SCSI_TERM_ENA_L
);
1278 if (i
& LOW_BYTE_TERM
)
1279 j
|= SCSI_TERM_ENA_L
;
1280 WR_HARPOON(ioport
+ hp_bm_ctrl
, j
);
1282 j
= (RD_HARPOON(ioport
+ hp_ee_ctrl
) & ~SCSI_TERM_ENA_H
);
1283 if (i
& HIGH_BYTE_TERM
)
1284 j
|= SCSI_TERM_ENA_H
;
1285 WR_HARPOON(ioport
+ hp_ee_ctrl
, j
);
1287 if (!(pCardInfo
->si_flags
& SOFT_RESET
)) {
1289 FPT_sresb(ioport
, thisCard
);
1291 FPT_scini(thisCard
, pCardInfo
->si_id
, 0);
1294 if (pCardInfo
->si_flags
& POST_ALL_UNDERRRUNS
)
1295 CurrCard
->globalFlags
|= F_NO_FILTER
;
1298 if (pCurrNvRam
->niSysConf
& 0x10)
1299 CurrCard
->globalFlags
|= F_GREEN_PC
;
1301 if (FPT_utilEERead(ioport
, (SYSTEM_CONFIG
/ 2)) & GREEN_PC_ENA
)
1302 CurrCard
->globalFlags
|= F_GREEN_PC
;
1305 /* Set global flag to indicate Re-Negotiation to be done on all
1308 if (pCurrNvRam
->niScsiConf
& 0x04)
1309 CurrCard
->globalFlags
|= F_DO_RENEGO
;
1311 if (FPT_utilEERead(ioport
, (SCSI_CONFIG
/ 2)) & RENEGO_ENA
)
1312 CurrCard
->globalFlags
|= F_DO_RENEGO
;
1316 if (pCurrNvRam
->niScsiConf
& 0x08)
1317 CurrCard
->globalFlags
|= F_CONLUN_IO
;
1319 if (FPT_utilEERead(ioport
, (SCSI_CONFIG
/ 2)) & CONNIO_ENA
)
1320 CurrCard
->globalFlags
|= F_CONLUN_IO
;
1323 temp
= pCardInfo
->si_per_targ_no_disc
;
1325 for (i
= 0, id
= 1; i
< MAX_SCSI_TAR
; i
++, id
<<= 1) {
1328 FPT_sccbMgrTbl
[thisCard
][i
].TarStatus
|= TAR_ALLOW_DISC
;
1331 sync_bit_map
= 0x0001;
1333 for (id
= 0; id
< (MAX_SCSI_TAR
/ 2); id
++) {
1336 temp
= (unsigned short)pCurrNvRam
->niSyncTbl
[id
];
1337 temp
= ((temp
& 0x03) + ((temp
<< 4) & 0xc0)) +
1338 (((temp
<< 4) & 0x0300) + ((temp
<< 8) & 0xc000));
1341 FPT_utilEERead(ioport
,
1342 (unsigned short)((SYNC_RATE_TBL
/ 2)
1345 for (i
= 0; i
< 2; temp
>>= 8, i
++) {
1347 if (pCardInfo
->si_per_targ_init_sync
& sync_bit_map
) {
1349 FPT_sccbMgrTbl
[thisCard
][id
* 2 +
1351 (unsigned char)temp
;
1355 FPT_sccbMgrTbl
[thisCard
][id
* 2 +
1358 FPT_sccbMgrTbl
[thisCard
][id
* 2 +
1360 (unsigned char)(temp
& ~EE_SYNC_MASK
);
1363 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1366 if (pCardInfo
->si_per_targ_wide_nego
& sync_bit_map
) {
1368 FPT_sccbMgrTbl
[thisCard
][id
* 2 +
1374 else { /* NARROW SCSI */
1375 FPT_sccbMgrTbl
[thisCard
][id
* 2 +
1385 WR_HARPOON((ioport
+ hp_semaphore
),
1386 (unsigned char)(RD_HARPOON((ioport
+ hp_semaphore
)) |
1389 return (unsigned long)CurrCard
;
1392 static void FlashPoint_ReleaseHostAdapter(unsigned long pCurrCard
)
1395 unsigned long portBase
;
1396 unsigned long regOffset
;
1397 unsigned long scamData
;
1398 unsigned long *pScamTbl
;
1399 struct nvram_info
*pCurrNvRam
;
1401 pCurrNvRam
= ((struct sccb_card
*)pCurrCard
)->pNvRamInfo
;
1404 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 0, pCurrNvRam
->niModel
);
1405 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 1, pCurrNvRam
->niSysConf
);
1406 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 2, pCurrNvRam
->niScsiConf
);
1407 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 3, pCurrNvRam
->niScamConf
);
1408 FPT_WrStack(pCurrNvRam
->niBaseAddr
, 4, pCurrNvRam
->niAdapId
);
1410 for (i
= 0; i
< MAX_SCSI_TAR
/ 2; i
++)
1411 FPT_WrStack(pCurrNvRam
->niBaseAddr
,
1412 (unsigned char)(i
+ 5),
1413 pCurrNvRam
->niSyncTbl
[i
]);
1415 portBase
= pCurrNvRam
->niBaseAddr
;
1417 for (i
= 0; i
< MAX_SCSI_TAR
; i
++) {
1418 regOffset
= hp_aramBase
+ 64 + i
* 4;
1419 pScamTbl
= (unsigned long *)&pCurrNvRam
->niScamTbl
[i
];
1420 scamData
= *pScamTbl
;
1421 WR_HARP32(portBase
, regOffset
, scamData
);
1425 FPT_WrStack(((struct sccb_card
*)pCurrCard
)->ioPort
, 0, 0);
1429 static void FPT_RNVRamData(struct nvram_info
*pNvRamInfo
)
1432 unsigned long portBase
;
1433 unsigned long regOffset
;
1434 unsigned long scamData
;
1435 unsigned long *pScamTbl
;
1437 pNvRamInfo
->niModel
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 0);
1438 pNvRamInfo
->niSysConf
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 1);
1439 pNvRamInfo
->niScsiConf
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 2);
1440 pNvRamInfo
->niScamConf
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 3);
1441 pNvRamInfo
->niAdapId
= FPT_RdStack(pNvRamInfo
->niBaseAddr
, 4);
1443 for (i
= 0; i
< MAX_SCSI_TAR
/ 2; i
++)
1444 pNvRamInfo
->niSyncTbl
[i
] =
1445 FPT_RdStack(pNvRamInfo
->niBaseAddr
, (unsigned char)(i
+ 5));
1447 portBase
= pNvRamInfo
->niBaseAddr
;
1449 for (i
= 0; i
< MAX_SCSI_TAR
; i
++) {
1450 regOffset
= hp_aramBase
+ 64 + i
* 4;
1451 RD_HARP32(portBase
, regOffset
, scamData
);
1452 pScamTbl
= (unsigned long *)&pNvRamInfo
->niScamTbl
[i
];
1453 *pScamTbl
= scamData
;
1458 static unsigned char FPT_RdStack(unsigned long portBase
, unsigned char index
)
1460 WR_HARPOON(portBase
+ hp_stack_addr
, index
);
1461 return RD_HARPOON(portBase
+ hp_stack_data
);
1464 static void FPT_WrStack(unsigned long portBase
, unsigned char index
,
1467 WR_HARPOON(portBase
+ hp_stack_addr
, index
);
1468 WR_HARPOON(portBase
+ hp_stack_data
, data
);
1471 static unsigned char FPT_ChkIfChipInitialized(unsigned long ioPort
)
1473 if ((RD_HARPOON(ioPort
+ hp_arb_id
) & 0x0f) != FPT_RdStack(ioPort
, 4))
1475 if ((RD_HARPOON(ioPort
+ hp_clkctrl_0
) & CLKCTRL_DEFAULT
)
1478 if ((RD_HARPOON(ioPort
+ hp_seltimeout
) == TO_250ms
) ||
1479 (RD_HARPOON(ioPort
+ hp_seltimeout
) == TO_290ms
))
1485 /*---------------------------------------------------------------------
1487 * Function: FlashPoint_StartCCB
1489 * Description: Start a command pointed to by p_Sccb. When the
1490 * command is completed it will be returned via the
1491 * callback function.
1493 *---------------------------------------------------------------------*/
1494 static void FlashPoint_StartCCB(unsigned long pCurrCard
, struct sccb
*p_Sccb
)
1496 unsigned long ioport
;
1497 unsigned char thisCard
, lun
;
1498 struct sccb
*pSaveSccb
;
1499 CALL_BK_FN callback
;
1501 thisCard
= ((struct sccb_card
*)pCurrCard
)->cardIndex
;
1502 ioport
= ((struct sccb_card
*)pCurrCard
)->ioPort
;
1504 if ((p_Sccb
->TargID
> MAX_SCSI_TAR
) || (p_Sccb
->Lun
> MAX_LUN
)) {
1506 p_Sccb
->HostStatus
= SCCB_COMPLETE
;
1507 p_Sccb
->SccbStatus
= SCCB_ERROR
;
1508 callback
= (CALL_BK_FN
) p_Sccb
->SccbCallback
;
1515 FPT_sinits(p_Sccb
, thisCard
);
1517 if (!((struct sccb_card
*)pCurrCard
)->cmdCounter
) {
1518 WR_HARPOON(ioport
+ hp_semaphore
,
1519 (RD_HARPOON(ioport
+ hp_semaphore
)
1520 | SCCB_MGR_ACTIVE
));
1522 if (((struct sccb_card
*)pCurrCard
)->globalFlags
& F_GREEN_PC
) {
1523 WR_HARPOON(ioport
+ hp_clkctrl_0
, CLKCTRL_DEFAULT
);
1524 WR_HARPOON(ioport
+ hp_sys_ctrl
, 0x00);
1528 ((struct sccb_card
*)pCurrCard
)->cmdCounter
++;
1530 if (RD_HARPOON(ioport
+ hp_semaphore
) & BIOS_IN_USE
) {
1532 WR_HARPOON(ioport
+ hp_semaphore
,
1533 (RD_HARPOON(ioport
+ hp_semaphore
)
1535 if (p_Sccb
->OperationCode
== RESET_COMMAND
) {
1537 ((struct sccb_card
*)pCurrCard
)->currentSCCB
;
1538 ((struct sccb_card
*)pCurrCard
)->currentSCCB
= p_Sccb
;
1539 FPT_queueSelectFail(&FPT_BL_Card
[thisCard
], thisCard
);
1540 ((struct sccb_card
*)pCurrCard
)->currentSCCB
=
1543 FPT_queueAddSccb(p_Sccb
, thisCard
);
1547 else if ((RD_HARPOON(ioport
+ hp_page_ctrl
) & G_INT_DISABLE
)) {
1549 if (p_Sccb
->OperationCode
== RESET_COMMAND
) {
1551 ((struct sccb_card
*)pCurrCard
)->currentSCCB
;
1552 ((struct sccb_card
*)pCurrCard
)->currentSCCB
= p_Sccb
;
1553 FPT_queueSelectFail(&FPT_BL_Card
[thisCard
], thisCard
);
1554 ((struct sccb_card
*)pCurrCard
)->currentSCCB
=
1557 FPT_queueAddSccb(p_Sccb
, thisCard
);
1563 MDISABLE_INT(ioport
);
1565 if ((((struct sccb_card
*)pCurrCard
)->globalFlags
& F_CONLUN_IO
)
1567 ((FPT_sccbMgrTbl
[thisCard
][p_Sccb
->TargID
].
1568 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
1572 if ((((struct sccb_card
*)pCurrCard
)->currentSCCB
== NULL
) &&
1573 (FPT_sccbMgrTbl
[thisCard
][p_Sccb
->TargID
].TarSelQ_Cnt
== 0)
1574 && (FPT_sccbMgrTbl
[thisCard
][p_Sccb
->TargID
].TarLUNBusy
[lun
]
1577 ((struct sccb_card
*)pCurrCard
)->currentSCCB
= p_Sccb
;
1578 FPT_ssel(p_Sccb
->SccbIOPort
, thisCard
);
1583 if (p_Sccb
->OperationCode
== RESET_COMMAND
) {
1585 ((struct sccb_card
*)pCurrCard
)->
1587 ((struct sccb_card
*)pCurrCard
)->currentSCCB
=
1589 FPT_queueSelectFail(&FPT_BL_Card
[thisCard
],
1591 ((struct sccb_card
*)pCurrCard
)->currentSCCB
=
1594 FPT_queueAddSccb(p_Sccb
, thisCard
);
1598 MENABLE_INT(ioport
);
1603 /*---------------------------------------------------------------------
1605 * Function: FlashPoint_AbortCCB
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.
1611 *---------------------------------------------------------------------*/
1612 static int FlashPoint_AbortCCB(unsigned long pCurrCard
, struct sccb
*p_Sccb
)
1614 unsigned long ioport
;
1616 unsigned char thisCard
;
1617 CALL_BK_FN callback
;
1619 struct sccb
*pSaveSCCB
;
1620 struct sccb_mgr_tar_info
*currTar_Info
;
1622 ioport
= ((struct sccb_card
*)pCurrCard
)->ioPort
;
1624 thisCard
= ((struct sccb_card
*)pCurrCard
)->cardIndex
;
1626 if (!(RD_HARPOON(ioport
+ hp_page_ctrl
) & G_INT_DISABLE
)) {
1628 if (FPT_queueFindSccb(p_Sccb
, thisCard
)) {
1630 ((struct sccb_card
*)pCurrCard
)->cmdCounter
--;
1632 if (!((struct sccb_card
*)pCurrCard
)->cmdCounter
)
1633 WR_HARPOON(ioport
+ hp_semaphore
,
1634 (RD_HARPOON(ioport
+ hp_semaphore
)
1636 char)(~(SCCB_MGR_ACTIVE
|
1639 p_Sccb
->SccbStatus
= SCCB_ABORT
;
1640 callback
= p_Sccb
->SccbCallback
;
1647 if (((struct sccb_card
*)pCurrCard
)->currentSCCB
==
1649 p_Sccb
->SccbStatus
= SCCB_ABORT
;
1656 TID
= p_Sccb
->TargID
;
1658 if (p_Sccb
->Sccb_tag
) {
1659 MDISABLE_INT(ioport
);
1660 if (((struct sccb_card
*)pCurrCard
)->
1661 discQ_Tbl
[p_Sccb
->Sccb_tag
] ==
1663 p_Sccb
->SccbStatus
= SCCB_ABORT
;
1664 p_Sccb
->Sccb_scsistat
=
1666 p_Sccb
->Sccb_scsimsg
=
1669 if (((struct sccb_card
*)
1670 pCurrCard
)->currentSCCB
==
1672 ((struct sccb_card
*)
1674 currentSCCB
= p_Sccb
;
1682 ((struct sccb_card
*)
1684 currentSCCB
= p_Sccb
;
1685 FPT_queueSelectFail((struct sccb_card
*)pCurrCard
, thisCard
);
1686 ((struct sccb_card
*)
1688 currentSCCB
= pSaveSCCB
;
1691 MENABLE_INT(ioport
);
1695 &FPT_sccbMgrTbl
[thisCard
][p_Sccb
->
1698 if (FPT_BL_Card
[thisCard
].
1699 discQ_Tbl
[currTar_Info
->
1700 LunDiscQ_Idx
[p_Sccb
->Lun
]]
1702 p_Sccb
->SccbStatus
= SCCB_ABORT
;
1712 /*---------------------------------------------------------------------
1714 * Function: FlashPoint_InterruptPending
1716 * Description: Do a quick check to determine if there is a pending
1717 * interrupt for this card and disable the IRQ Pin if so.
1719 *---------------------------------------------------------------------*/
1720 static unsigned char FlashPoint_InterruptPending(unsigned long pCurrCard
)
1722 unsigned long ioport
;
1724 ioport
= ((struct sccb_card
*)pCurrCard
)->ioPort
;
1726 if (RD_HARPOON(ioport
+ hp_int_status
) & INT_ASSERTED
) {
1735 /*---------------------------------------------------------------------
1737 * Function: FlashPoint_HandleInterrupt
1739 * Description: This is our entry point when an interrupt is generated
1740 * by the card and the upper level driver passes it on to
1743 *---------------------------------------------------------------------*/
1744 static int FlashPoint_HandleInterrupt(unsigned long pCurrCard
)
1746 struct sccb
*currSCCB
;
1747 unsigned char thisCard
, result
, bm_status
, bm_int_st
;
1748 unsigned short hp_int
;
1749 unsigned char i
, target
;
1750 unsigned long ioport
;
1752 thisCard
= ((struct sccb_card
*)pCurrCard
)->cardIndex
;
1753 ioport
= ((struct sccb_card
*)pCurrCard
)->ioPort
;
1755 MDISABLE_INT(ioport
);
1757 if ((bm_int_st
= RD_HARPOON(ioport
+ hp_int_status
)) & EXT_STATUS_ON
)
1760 hp_ext_status
) & (unsigned char)BAD_EXT_STATUS
;
1764 WR_HARPOON(ioport
+ hp_int_mask
, (INT_CMD_COMPL
| SCSI_INTERRUPT
));
1767 RDW_HARPOON((ioport
+
1768 hp_intstat
)) & FPT_default_intena
) | bm_status
) {
1770 currSCCB
= ((struct sccb_card
*)pCurrCard
)->currentSCCB
;
1772 if (hp_int
& (FIFO
| TIMEOUT
| RESET
| SCAM_SEL
) || bm_status
) {
1774 FPT_SccbMgr_bad_isr(ioport
, thisCard
,
1775 ((struct sccb_card
*)pCurrCard
),
1777 WRW_HARPOON((ioport
+ hp_intstat
),
1778 (FIFO
| TIMEOUT
| RESET
| SCAM_SEL
));
1783 MENABLE_INT(ioport
);
1788 else if (hp_int
& ICMD_COMP
) {
1790 if (!(hp_int
& BUS_FREE
)) {
1791 /* Wait for the BusFree before starting a new command. We
1792 must also check for being reselected since the BusFree
1793 may not show up if another device reselects us in 1.5us or
1794 less. SRR Wednesday, 3/8/1995.
1797 (RDW_HARPOON((ioport
+ hp_intstat
)) &
1798 (BUS_FREE
| RSEL
))) ;
1801 if (((struct sccb_card
*)pCurrCard
)->
1802 globalFlags
& F_HOST_XFER_ACT
)
1804 FPT_phaseChkFifo(ioport
, thisCard
);
1806 /* WRW_HARPOON((ioport+hp_intstat),
1807 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1810 WRW_HARPOON((ioport
+ hp_intstat
), CLR_ALL_INT_1
);
1812 FPT_autoCmdCmplt(ioport
, thisCard
);
1816 else if (hp_int
& ITAR_DISC
) {
1818 if (((struct sccb_card
*)pCurrCard
)->
1819 globalFlags
& F_HOST_XFER_ACT
) {
1821 FPT_phaseChkFifo(ioport
, thisCard
);
1825 if (RD_HARPOON(ioport
+ hp_gp_reg_1
) == SMSAVE_DATA_PTR
) {
1827 WR_HARPOON(ioport
+ hp_gp_reg_1
, 0x00);
1828 currSCCB
->Sccb_XferState
|= F_NO_DATA_YET
;
1830 currSCCB
->Sccb_savedATC
= currSCCB
->Sccb_ATC
;
1833 currSCCB
->Sccb_scsistat
= DISCONNECT_ST
;
1834 FPT_queueDisconnect(currSCCB
, thisCard
);
1836 /* Wait for the BusFree before starting a new command. We
1837 must also check for being reselected since the BusFree
1838 may not show up if another device reselects us in 1.5us or
1839 less. SRR Wednesday, 3/8/1995.
1842 (RDW_HARPOON((ioport
+ hp_intstat
)) &
1844 && !((RDW_HARPOON((ioport
+ hp_intstat
)) & PHASE
)
1845 && RD_HARPOON((ioport
+ hp_scsisig
)) ==
1846 (SCSI_BSY
| SCSI_REQ
| SCSI_CD
| SCSI_MSG
|
1850 The additional loop exit condition above detects a timing problem
1851 with the revision D/E harpoon chips. The caller should reset the
1852 host adapter to recover when 0xFE is returned.
1855 (RDW_HARPOON((ioport
+ hp_intstat
)) &
1856 (BUS_FREE
| RSEL
))) {
1857 MENABLE_INT(ioport
);
1861 WRW_HARPOON((ioport
+ hp_intstat
),
1862 (BUS_FREE
| ITAR_DISC
));
1864 ((struct sccb_card
*)pCurrCard
)->globalFlags
|=
1869 else if (hp_int
& RSEL
) {
1871 WRW_HARPOON((ioport
+ hp_intstat
),
1872 (PROG_HLT
| RSEL
| PHASE
| BUS_FREE
));
1874 if (RDW_HARPOON((ioport
+ hp_intstat
)) & ITAR_DISC
) {
1875 if (((struct sccb_card
*)pCurrCard
)->
1876 globalFlags
& F_HOST_XFER_ACT
) {
1877 FPT_phaseChkFifo(ioport
, thisCard
);
1880 if (RD_HARPOON(ioport
+ hp_gp_reg_1
) ==
1882 WR_HARPOON(ioport
+ hp_gp_reg_1
, 0x00);
1883 currSCCB
->Sccb_XferState
|=
1885 currSCCB
->Sccb_savedATC
=
1889 WRW_HARPOON((ioport
+ hp_intstat
),
1890 (BUS_FREE
| ITAR_DISC
));
1891 currSCCB
->Sccb_scsistat
= DISCONNECT_ST
;
1892 FPT_queueDisconnect(currSCCB
, thisCard
);
1895 FPT_sres(ioport
, thisCard
,
1896 ((struct sccb_card
*)pCurrCard
));
1897 FPT_phaseDecode(ioport
, thisCard
);
1901 else if ((hp_int
& IDO_STRT
) && (!(hp_int
& BUS_FREE
))) {
1903 WRW_HARPOON((ioport
+ hp_intstat
),
1904 (IDO_STRT
| XFER_CNT_0
));
1905 FPT_phaseDecode(ioport
, thisCard
);
1909 else if ((hp_int
& IUNKWN
) || (hp_int
& PROG_HLT
)) {
1910 WRW_HARPOON((ioport
+ hp_intstat
),
1911 (PHASE
| IUNKWN
| PROG_HLT
));
1912 if ((RD_HARPOON(ioport
+ hp_prgmcnt_0
) & (unsigned char)
1913 0x3f) < (unsigned char)SELCHK
) {
1914 FPT_phaseDecode(ioport
, thisCard
);
1916 /* Harpoon problem some SCSI target device respond to selection
1917 with short BUSY pulse (<400ns) this will make the Harpoon is not able
1918 to latch the correct Target ID into reg. x53.
1919 The work around require to correct this reg. But when write to this
1920 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
1921 need to read this reg first then restore it later. After update to 0x53 */
1924 char)(RD_HARPOON(ioport
+ hp_fifowrite
));
1927 char)(RD_HARPOON(ioport
+ hp_gp_reg_3
));
1928 WR_HARPOON(ioport
+ hp_xfer_pad
,
1929 (unsigned char)ID_UNLOCK
);
1930 WR_HARPOON(ioport
+ hp_select_id
,
1931 (unsigned char)(target
| target
<<
1933 WR_HARPOON(ioport
+ hp_xfer_pad
,
1934 (unsigned char)0x00);
1935 WR_HARPOON(ioport
+ hp_fifowrite
, i
);
1936 WR_HARPOON(ioport
+ hp_autostart_3
,
1937 (AUTO_IMMED
+ TAG_STRT
));
1941 else if (hp_int
& XFER_CNT_0
) {
1943 WRW_HARPOON((ioport
+ hp_intstat
), XFER_CNT_0
);
1945 FPT_schkdd(ioport
, thisCard
);
1949 else if (hp_int
& BUS_FREE
) {
1951 WRW_HARPOON((ioport
+ hp_intstat
), BUS_FREE
);
1953 if (((struct sccb_card
*)pCurrCard
)->
1954 globalFlags
& F_HOST_XFER_ACT
) {
1956 FPT_hostDataXferAbort(ioport
, thisCard
,
1960 FPT_phaseBusFree(ioport
, thisCard
);
1963 else if (hp_int
& ITICKLE
) {
1965 WRW_HARPOON((ioport
+ hp_intstat
), ITICKLE
);
1966 ((struct sccb_card
*)pCurrCard
)->globalFlags
|=
1970 if (((struct sccb_card
*)pCurrCard
)->
1971 globalFlags
& F_NEW_SCCB_CMD
) {
1973 ((struct sccb_card
*)pCurrCard
)->globalFlags
&=
1976 if (((struct sccb_card
*)pCurrCard
)->currentSCCB
==
1979 FPT_queueSearchSelect(((struct sccb_card
*)
1980 pCurrCard
), thisCard
);
1983 if (((struct sccb_card
*)pCurrCard
)->currentSCCB
!=
1985 ((struct sccb_card
*)pCurrCard
)->globalFlags
&=
1987 FPT_ssel(ioport
, thisCard
);
1996 MENABLE_INT(ioport
);
2001 /*---------------------------------------------------------------------
2003 * Function: Sccb_bad_isr
2005 * Description: Some type of interrupt has occurred which is slightly
2006 * out of the ordinary. We will now decode it fully, in
2007 * this routine. This is broken up in an attempt to save
2010 *---------------------------------------------------------------------*/
2011 static unsigned char FPT_SccbMgr_bad_isr(unsigned long p_port
,
2012 unsigned char p_card
,
2013 struct sccb_card
*pCurrCard
,
2014 unsigned short p_int
)
2016 unsigned char temp
, ScamFlg
;
2017 struct sccb_mgr_tar_info
*currTar_Info
;
2018 struct nvram_info
*pCurrNvRam
;
2020 if (RD_HARPOON(p_port
+ hp_ext_status
) &
2021 (BM_FORCE_OFF
| PCI_DEV_TMOUT
| BM_PARITY_ERR
| PIO_OVERRUN
)) {
2023 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
) {
2025 FPT_hostDataXferAbort(p_port
, p_card
,
2026 pCurrCard
->currentSCCB
);
2029 if (RD_HARPOON(p_port
+ hp_pci_stat_cfg
) & REC_MASTER_ABORT
)
2031 WR_HARPOON(p_port
+ hp_pci_stat_cfg
,
2032 (RD_HARPOON(p_port
+ hp_pci_stat_cfg
) &
2033 ~REC_MASTER_ABORT
));
2035 WR_HARPOON(p_port
+ hp_host_blk_cnt
, 0x00);
2039 if (pCurrCard
->currentSCCB
!= NULL
) {
2041 if (!pCurrCard
->currentSCCB
->HostStatus
)
2042 pCurrCard
->currentSCCB
->HostStatus
=
2045 FPT_sxfrp(p_port
, p_card
);
2047 temp
= (unsigned char)(RD_HARPOON(p_port
+ hp_ee_ctrl
) &
2048 (EXT_ARB_ACK
| SCSI_TERM_ENA_H
));
2049 WR_HARPOON(p_port
+ hp_ee_ctrl
,
2050 ((unsigned char)temp
| SEE_MS
| SEE_CS
));
2051 WR_HARPOON(p_port
+ hp_ee_ctrl
, temp
);
2054 (RDW_HARPOON((p_port
+ hp_intstat
)) &
2055 (BUS_FREE
| RESET
))) {
2056 FPT_phaseDecode(p_port
, p_card
);
2061 else if (p_int
& RESET
) {
2063 WR_HARPOON(p_port
+ hp_clkctrl_0
, CLKCTRL_DEFAULT
);
2064 WR_HARPOON(p_port
+ hp_sys_ctrl
, 0x00);
2065 if (pCurrCard
->currentSCCB
!= NULL
) {
2067 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
)
2069 FPT_hostDataXferAbort(p_port
, p_card
,
2070 pCurrCard
->currentSCCB
);
2073 DISABLE_AUTO(p_port
);
2075 FPT_sresb(p_port
, p_card
);
2077 while (RD_HARPOON(p_port
+ hp_scsictrl_0
) & SCSI_RST
) {
2080 pCurrNvRam
= pCurrCard
->pNvRamInfo
;
2082 ScamFlg
= pCurrNvRam
->niScamConf
;
2085 (unsigned char)FPT_utilEERead(p_port
,
2089 FPT_XbowInit(p_port
, ScamFlg
);
2091 FPT_scini(p_card
, pCurrCard
->ourId
, 0);
2096 else if (p_int
& FIFO
) {
2098 WRW_HARPOON((p_port
+ hp_intstat
), FIFO
);
2100 if (pCurrCard
->currentSCCB
!= NULL
)
2101 FPT_sxfrp(p_port
, p_card
);
2104 else if (p_int
& TIMEOUT
) {
2106 DISABLE_AUTO(p_port
);
2108 WRW_HARPOON((p_port
+ hp_intstat
),
2109 (PROG_HLT
| TIMEOUT
| SEL
| BUS_FREE
| PHASE
|
2112 pCurrCard
->currentSCCB
->HostStatus
= SCCB_SELECTION_TIMEOUT
;
2115 &FPT_sccbMgrTbl
[p_card
][pCurrCard
->currentSCCB
->TargID
];
2116 if ((pCurrCard
->globalFlags
& F_CONLUN_IO
)
2117 && ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) !=
2119 currTar_Info
->TarLUNBusy
[pCurrCard
->currentSCCB
->Lun
] =
2122 currTar_Info
->TarLUNBusy
[0] = 0;
2124 if (currTar_Info
->TarEEValue
& EE_SYNC_MASK
) {
2125 currTar_Info
->TarSyncCtrl
= 0;
2126 currTar_Info
->TarStatus
&= ~TAR_SYNC_MASK
;
2129 if (currTar_Info
->TarEEValue
& EE_WIDE_SCSI
) {
2130 currTar_Info
->TarStatus
&= ~TAR_WIDE_MASK
;
2133 FPT_sssyncv(p_port
, pCurrCard
->currentSCCB
->TargID
, NARROW_SCSI
,
2136 FPT_queueCmdComplete(pCurrCard
, pCurrCard
->currentSCCB
, p_card
);
2140 else if (p_int
& SCAM_SEL
) {
2142 FPT_scarb(p_port
, LEVEL2_TAR
);
2144 FPT_scasid(p_card
, p_port
);
2148 WRW_HARPOON((p_port
+ hp_intstat
), SCAM_SEL
);
2154 /*---------------------------------------------------------------------
2156 * Function: SccbMgrTableInit
2158 * Description: Initialize all Sccb manager data structures.
2160 *---------------------------------------------------------------------*/
2162 static void FPT_SccbMgrTableInitAll()
2164 unsigned char thisCard
;
2166 for (thisCard
= 0; thisCard
< MAX_CARDS
; thisCard
++) {
2167 FPT_SccbMgrTableInitCard(&FPT_BL_Card
[thisCard
], thisCard
);
2169 FPT_BL_Card
[thisCard
].ioPort
= 0x00;
2170 FPT_BL_Card
[thisCard
].cardInfo
= NULL
;
2171 FPT_BL_Card
[thisCard
].cardIndex
= 0xFF;
2172 FPT_BL_Card
[thisCard
].ourId
= 0x00;
2173 FPT_BL_Card
[thisCard
].pNvRamInfo
= NULL
;
2177 /*---------------------------------------------------------------------
2179 * Function: SccbMgrTableInit
2181 * Description: Initialize all Sccb manager data structures.
2183 *---------------------------------------------------------------------*/
2185 static void FPT_SccbMgrTableInitCard(struct sccb_card
*pCurrCard
,
2186 unsigned char p_card
)
2188 unsigned char scsiID
, qtag
;
2190 for (qtag
= 0; qtag
< QUEUE_DEPTH
; qtag
++) {
2191 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] = NULL
;
2194 for (scsiID
= 0; scsiID
< MAX_SCSI_TAR
; scsiID
++) {
2195 FPT_sccbMgrTbl
[p_card
][scsiID
].TarStatus
= 0;
2196 FPT_sccbMgrTbl
[p_card
][scsiID
].TarEEValue
= 0;
2197 FPT_SccbMgrTableInitTarget(p_card
, scsiID
);
2200 pCurrCard
->scanIndex
= 0x00;
2201 pCurrCard
->currentSCCB
= NULL
;
2202 pCurrCard
->globalFlags
= 0x00;
2203 pCurrCard
->cmdCounter
= 0x00;
2204 pCurrCard
->tagQ_Lst
= 0x01;
2205 pCurrCard
->discQCount
= 0;
2209 /*---------------------------------------------------------------------
2211 * Function: SccbMgrTableInit
2213 * Description: Initialize all Sccb manager data structures.
2215 *---------------------------------------------------------------------*/
2217 static void FPT_SccbMgrTableInitTarget(unsigned char p_card
,
2218 unsigned char target
)
2221 unsigned char lun
, qtag
;
2222 struct sccb_mgr_tar_info
*currTar_Info
;
2224 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][target
];
2226 currTar_Info
->TarSelQ_Cnt
= 0;
2227 currTar_Info
->TarSyncCtrl
= 0;
2229 currTar_Info
->TarSelQ_Head
= NULL
;
2230 currTar_Info
->TarSelQ_Tail
= NULL
;
2231 currTar_Info
->TarTagQ_Cnt
= 0;
2232 currTar_Info
->TarLUN_CA
= 0;
2234 for (lun
= 0; lun
< MAX_LUN
; lun
++) {
2235 currTar_Info
->TarLUNBusy
[lun
] = 0;
2236 currTar_Info
->LunDiscQ_Idx
[lun
] = 0;
2239 for (qtag
= 0; qtag
< QUEUE_DEPTH
; qtag
++) {
2240 if (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] != NULL
) {
2241 if (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->TargID
==
2243 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] = NULL
;
2244 FPT_BL_Card
[p_card
].discQCount
--;
2250 /*---------------------------------------------------------------------
2254 * Description: Read in a message byte from the SCSI bus, and check
2255 * for a parity error.
2257 *---------------------------------------------------------------------*/
2259 static unsigned char FPT_sfm(unsigned long port
, struct sccb
*pCurrSCCB
)
2261 unsigned char message
;
2262 unsigned short TimeOutLoop
;
2265 while ((!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)) &&
2266 (TimeOutLoop
++ < 20000)) {
2269 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
2271 message
= RD_HARPOON(port
+ hp_scsidata_0
);
2273 WR_HARPOON(port
+ hp_scsisig
, SCSI_ACK
+ S_MSGI_PH
);
2275 if (TimeOutLoop
> 20000)
2276 message
= 0x00; /* force message byte = 0 if Time Out on Req */
2278 if ((RDW_HARPOON((port
+ hp_intstat
)) & PARITY
) &&
2279 (RD_HARPOON(port
+ hp_addstat
) & SCSI_PAR_ERR
)) {
2280 WR_HARPOON(port
+ hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
2281 WR_HARPOON(port
+ hp_xferstat
, 0);
2282 WR_HARPOON(port
+ hp_fiforead
, 0);
2283 WR_HARPOON(port
+ hp_fifowrite
, 0);
2284 if (pCurrSCCB
!= NULL
) {
2285 pCurrSCCB
->Sccb_scsimsg
= SMPARITY
;
2289 ACCEPT_MSG_ATN(port
);
2291 while ((!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)) &&
2292 (TimeOutLoop
++ < 20000)) {
2294 if (TimeOutLoop
> 20000) {
2295 WRW_HARPOON((port
+ hp_intstat
), PARITY
);
2298 if ((RD_HARPOON(port
+ hp_scsisig
) & S_SCSI_PHZ
) !=
2300 WRW_HARPOON((port
+ hp_intstat
), PARITY
);
2303 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
2305 RD_HARPOON(port
+ hp_scsidata_0
);
2307 WR_HARPOON(port
+ hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
2312 WR_HARPOON(port
+ hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
2313 WR_HARPOON(port
+ hp_xferstat
, 0);
2314 WR_HARPOON(port
+ hp_fiforead
, 0);
2315 WR_HARPOON(port
+ hp_fifowrite
, 0);
2319 /*---------------------------------------------------------------------
2321 * Function: FPT_ssel
2323 * Description: Load up automation and select target device.
2325 *---------------------------------------------------------------------*/
2327 static void FPT_ssel(unsigned long port
, unsigned char p_card
)
2330 unsigned char auto_loaded
, i
, target
, *theCCB
;
2332 unsigned long cdb_reg
;
2333 struct sccb_card
*CurrCard
;
2334 struct sccb
*currSCCB
;
2335 struct sccb_mgr_tar_info
*currTar_Info
;
2336 unsigned char lastTag
, lun
;
2338 CurrCard
= &FPT_BL_Card
[p_card
];
2339 currSCCB
= CurrCard
->currentSCCB
;
2340 target
= currSCCB
->TargID
;
2341 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][target
];
2342 lastTag
= CurrCard
->tagQ_Lst
;
2346 if ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) == TAG_Q_REJECT
)
2347 currSCCB
->ControlByte
&= ~F_USE_CMD_Q
;
2349 if (((CurrCard
->globalFlags
& F_CONLUN_IO
) &&
2350 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
)))
2352 lun
= currSCCB
->Lun
;
2356 if (CurrCard
->globalFlags
& F_TAG_STARTED
) {
2357 if (!(currSCCB
->ControlByte
& F_USE_CMD_Q
)) {
2358 if ((currTar_Info
->TarLUN_CA
== 0)
2359 && ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
)
2362 if (currTar_Info
->TarTagQ_Cnt
!= 0) {
2363 currTar_Info
->TarLUNBusy
[lun
] = 1;
2364 FPT_queueSelectFail(CurrCard
, p_card
);
2370 currTar_Info
->TarLUNBusy
[lun
] = 1;
2376 currTar_Info
->TarLUNBusy
[lun
] = 1;
2380 /*!Use cmd Q Tagged */
2382 if (currTar_Info
->TarLUN_CA
== 1) {
2383 FPT_queueSelectFail(CurrCard
, p_card
);
2388 currTar_Info
->TarLUNBusy
[lun
] = 1;
2390 } /*else use cmd Q tagged */
2393 /*if glob tagged started */
2395 currTar_Info
->TarLUNBusy
[lun
] = 1;
2398 if ((((CurrCard
->globalFlags
& F_CONLUN_IO
) &&
2399 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
2400 || (!(currSCCB
->ControlByte
& F_USE_CMD_Q
)))) {
2401 if (CurrCard
->discQCount
>= QUEUE_DEPTH
) {
2402 currTar_Info
->TarLUNBusy
[lun
] = 1;
2403 FPT_queueSelectFail(CurrCard
, p_card
);
2407 for (i
= 1; i
< QUEUE_DEPTH
; i
++) {
2408 if (++lastTag
>= QUEUE_DEPTH
)
2410 if (CurrCard
->discQ_Tbl
[lastTag
] == NULL
) {
2411 CurrCard
->tagQ_Lst
= lastTag
;
2412 currTar_Info
->LunDiscQ_Idx
[lun
] = lastTag
;
2413 CurrCard
->discQ_Tbl
[lastTag
] = currSCCB
;
2414 CurrCard
->discQCount
++;
2418 if (i
== QUEUE_DEPTH
) {
2419 currTar_Info
->TarLUNBusy
[lun
] = 1;
2420 FPT_queueSelectFail(CurrCard
, p_card
);
2428 WR_HARPOON(port
+ hp_select_id
, target
);
2429 WR_HARPOON(port
+ hp_gp_reg_3
, target
); /* Use by new automation logic */
2431 if (currSCCB
->OperationCode
== RESET_COMMAND
) {
2432 WRW_HARPOON((port
+ ID_MSG_STRT
), (MPM_OP
+ AMSG_OUT
+
2434 Sccb_idmsg
& ~DISC_PRIV
)));
2436 WRW_HARPOON((port
+ ID_MSG_STRT
+ 2), BRH_OP
+ ALWAYS
+ NP
);
2438 currSCCB
->Sccb_scsimsg
= SMDEV_RESET
;
2440 WR_HARPOON(port
+ hp_autostart_3
, (SELECT
+ SELCHK_STRT
));
2442 currSCCB
->Sccb_scsistat
= SELECT_BDR_ST
;
2444 if (currTar_Info
->TarEEValue
& EE_SYNC_MASK
) {
2445 currTar_Info
->TarSyncCtrl
= 0;
2446 currTar_Info
->TarStatus
&= ~TAR_SYNC_MASK
;
2449 if (currTar_Info
->TarEEValue
& EE_WIDE_SCSI
) {
2450 currTar_Info
->TarStatus
&= ~TAR_WIDE_MASK
;
2453 FPT_sssyncv(port
, target
, NARROW_SCSI
, currTar_Info
);
2454 FPT_SccbMgrTableInitTarget(p_card
, target
);
2458 else if (currSCCB
->Sccb_scsistat
== ABORT_ST
) {
2459 WRW_HARPOON((port
+ ID_MSG_STRT
), (MPM_OP
+ AMSG_OUT
+
2461 Sccb_idmsg
& ~DISC_PRIV
)));
2463 WRW_HARPOON((port
+ ID_MSG_STRT
+ 2), BRH_OP
+ ALWAYS
+ CMDPZ
);
2465 WRW_HARPOON((port
+ SYNC_MSGS
+ 0), (MPM_OP
+ AMSG_OUT
+
2470 >> 6) | (unsigned char)
2472 WRW_HARPOON((port
+ SYNC_MSGS
+ 2),
2473 (MPM_OP
+ AMSG_OUT
+ currSCCB
->Sccb_tag
));
2474 WRW_HARPOON((port
+ SYNC_MSGS
+ 4), (BRH_OP
+ ALWAYS
+ NP
));
2476 WR_HARPOON(port
+ hp_autostart_3
, (SELECT
+ SELCHK_STRT
));
2481 else if (!(currTar_Info
->TarStatus
& WIDE_NEGOCIATED
)) {
2482 auto_loaded
= FPT_siwidn(port
, p_card
);
2483 currSCCB
->Sccb_scsistat
= SELECT_WN_ST
;
2486 else if (!((currTar_Info
->TarStatus
& TAR_SYNC_MASK
)
2487 == SYNC_SUPPORTED
)) {
2488 auto_loaded
= FPT_sisyncn(port
, p_card
, 0);
2489 currSCCB
->Sccb_scsistat
= SELECT_SN_ST
;
2494 if (currSCCB
->ControlByte
& F_USE_CMD_Q
) {
2496 CurrCard
->globalFlags
|= F_TAG_STARTED
;
2498 if ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
)
2500 currSCCB
->ControlByte
&= ~F_USE_CMD_Q
;
2502 /* Fix up the start instruction with a jump to
2503 Non-Tag-CMD handling */
2504 WRW_HARPOON((port
+ ID_MSG_STRT
),
2505 BRH_OP
+ ALWAYS
+ NTCMD
);
2507 WRW_HARPOON((port
+ NON_TAG_ID_MSG
),
2508 (MPM_OP
+ AMSG_OUT
+
2509 currSCCB
->Sccb_idmsg
));
2511 WR_HARPOON(port
+ hp_autostart_3
,
2512 (SELECT
+ SELCHK_STRT
));
2514 /* Setup our STATE so we know what happend when
2515 the wheels fall off. */
2516 currSCCB
->Sccb_scsistat
= SELECT_ST
;
2518 currTar_Info
->TarLUNBusy
[lun
] = 1;
2522 WRW_HARPOON((port
+ ID_MSG_STRT
),
2523 (MPM_OP
+ AMSG_OUT
+
2524 currSCCB
->Sccb_idmsg
));
2526 WRW_HARPOON((port
+ ID_MSG_STRT
+ 2),
2527 (MPM_OP
+ AMSG_OUT
+
2528 (((unsigned char)(currSCCB
->
2531 >> 6) | (unsigned char)0x20)));
2533 for (i
= 1; i
< QUEUE_DEPTH
; i
++) {
2534 if (++lastTag
>= QUEUE_DEPTH
)
2536 if (CurrCard
->discQ_Tbl
[lastTag
] ==
2540 (MPM_OP
+ AMSG_OUT
+
2542 CurrCard
->tagQ_Lst
= lastTag
;
2543 currSCCB
->Sccb_tag
= lastTag
;
2544 CurrCard
->discQ_Tbl
[lastTag
] =
2546 CurrCard
->discQCount
++;
2551 if (i
== QUEUE_DEPTH
) {
2552 currTar_Info
->TarLUNBusy
[lun
] = 1;
2553 FPT_queueSelectFail(CurrCard
, p_card
);
2558 currSCCB
->Sccb_scsistat
= SELECT_Q_ST
;
2560 WR_HARPOON(port
+ hp_autostart_3
,
2561 (SELECT
+ SELCHK_STRT
));
2567 WRW_HARPOON((port
+ ID_MSG_STRT
),
2568 BRH_OP
+ ALWAYS
+ NTCMD
);
2570 WRW_HARPOON((port
+ NON_TAG_ID_MSG
),
2571 (MPM_OP
+ AMSG_OUT
+ currSCCB
->Sccb_idmsg
));
2573 currSCCB
->Sccb_scsistat
= SELECT_ST
;
2575 WR_HARPOON(port
+ hp_autostart_3
,
2576 (SELECT
+ SELCHK_STRT
));
2579 theCCB
= (unsigned char *)&currSCCB
->Cdb
[0];
2581 cdb_reg
= port
+ CMD_STRT
;
2583 for (i
= 0; i
< currSCCB
->CdbLength
; i
++) {
2584 WRW_HARPOON(cdb_reg
, (MPM_OP
+ ACOMMAND
+ *theCCB
));
2589 if (currSCCB
->CdbLength
!= TWELVE_BYTE_CMD
)
2590 WRW_HARPOON(cdb_reg
, (BRH_OP
+ ALWAYS
+ NP
));
2594 WRW_HARPOON((port
+ hp_fiforead
), (unsigned short)0x00);
2595 WR_HARPOON(port
+ hp_xferstat
, 0x00);
2597 WRW_HARPOON((port
+ hp_intstat
), (PROG_HLT
| TIMEOUT
| SEL
| BUS_FREE
));
2599 WR_HARPOON(port
+ hp_portctrl_0
, (SCSI_PORT
));
2601 if (!(currSCCB
->Sccb_MGRFlags
& F_DEV_SELECTED
)) {
2602 WR_HARPOON(port
+ hp_scsictrl_0
,
2603 (SEL_TAR
| ENA_ATN
| ENA_RESEL
| ENA_SCAM_SEL
));
2606 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2607 auto_loaded |= AUTO_IMMED; */
2608 auto_loaded
= AUTO_IMMED
;
2612 WR_HARPOON(port
+ hp_autostart_3
, auto_loaded
);
2618 /*---------------------------------------------------------------------
2620 * Function: FPT_sres
2622 * Description: Hookup the correct CCB and handle the incoming messages.
2624 *---------------------------------------------------------------------*/
2626 static void FPT_sres(unsigned long port
, unsigned char p_card
,
2627 struct sccb_card
*pCurrCard
)
2630 unsigned char our_target
, message
, lun
= 0, tag
, msgRetryCount
;
2632 struct sccb_mgr_tar_info
*currTar_Info
;
2633 struct sccb
*currSCCB
;
2635 if (pCurrCard
->currentSCCB
!= NULL
) {
2637 &FPT_sccbMgrTbl
[p_card
][pCurrCard
->currentSCCB
->TargID
];
2640 WR_HARPOON((port
+ hp_scsictrl_0
), (ENA_RESEL
| ENA_SCAM_SEL
));
2642 currSCCB
= pCurrCard
->currentSCCB
;
2643 if (currSCCB
->Sccb_scsistat
== SELECT_WN_ST
) {
2644 currTar_Info
->TarStatus
&= ~TAR_WIDE_MASK
;
2645 currSCCB
->Sccb_scsistat
= BUS_FREE_ST
;
2647 if (currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) {
2648 currTar_Info
->TarStatus
&= ~TAR_SYNC_MASK
;
2649 currSCCB
->Sccb_scsistat
= BUS_FREE_ST
;
2651 if (((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
2652 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) !=
2654 currTar_Info
->TarLUNBusy
[currSCCB
->Lun
] = 0;
2655 if (currSCCB
->Sccb_scsistat
!= ABORT_ST
) {
2656 pCurrCard
->discQCount
--;
2657 pCurrCard
->discQ_Tbl
[currTar_Info
->
2658 LunDiscQ_Idx
[currSCCB
->
2663 currTar_Info
->TarLUNBusy
[0] = 0;
2664 if (currSCCB
->Sccb_tag
) {
2665 if (currSCCB
->Sccb_scsistat
!= ABORT_ST
) {
2666 pCurrCard
->discQCount
--;
2667 pCurrCard
->discQ_Tbl
[currSCCB
->
2671 if (currSCCB
->Sccb_scsistat
!= ABORT_ST
) {
2672 pCurrCard
->discQCount
--;
2673 pCurrCard
->discQ_Tbl
[currTar_Info
->
2680 FPT_queueSelectFail(&FPT_BL_Card
[p_card
], p_card
);
2683 WRW_HARPOON((port
+ hp_fiforead
), (unsigned short)0x00);
2685 our_target
= (unsigned char)(RD_HARPOON(port
+ hp_select_id
) >> 4);
2686 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][our_target
];
2691 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][our_target
];
2694 while (!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)) {
2695 if (!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_BSY
)) {
2697 WRW_HARPOON((port
+ hp_intstat
), PHASE
);
2702 WRW_HARPOON((port
+ hp_intstat
), PHASE
);
2703 if ((RD_HARPOON(port
+ hp_scsisig
) & S_SCSI_PHZ
) == S_MSGI_PH
) {
2705 message
= FPT_sfm(port
, pCurrCard
->currentSCCB
);
2708 if (message
<= (0x80 | LUN_MASK
)) {
2709 lun
= message
& (unsigned char)LUN_MASK
;
2712 TarStatus
& TAR_TAG_Q_MASK
) ==
2714 if (currTar_Info
->TarTagQ_Cnt
!=
2720 ACCEPT_MSG(port
); /*Release the ACK for ID msg. */
2756 /*End Tag cmds supported! */
2758 /*End valid ID message. */
2761 ACCEPT_MSG_ATN(port
);
2765 /* End good id message. */
2771 ACCEPT_MSG_ATN(port
);
2774 (RDW_HARPOON((port
+ hp_intstat
)) &
2776 && !(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)
2777 && (RD_HARPOON(port
+ hp_scsisig
) & SCSI_BSY
)) ;
2784 if (msgRetryCount
== 1) {
2785 FPT_SendMsg(port
, SMPARITY
);
2787 FPT_SendMsg(port
, SMDEV_RESET
);
2789 FPT_sssyncv(port
, our_target
, NARROW_SCSI
,
2792 if (FPT_sccbMgrTbl
[p_card
][our_target
].
2793 TarEEValue
& EE_SYNC_MASK
) {
2795 FPT_sccbMgrTbl
[p_card
][our_target
].
2796 TarStatus
&= ~TAR_SYNC_MASK
;
2800 if (FPT_sccbMgrTbl
[p_card
][our_target
].
2801 TarEEValue
& EE_WIDE_SCSI
) {
2803 FPT_sccbMgrTbl
[p_card
][our_target
].
2804 TarStatus
&= ~TAR_WIDE_MASK
;
2807 FPT_queueFlushTargSccb(p_card
, our_target
,
2809 FPT_SccbMgrTableInitTarget(p_card
, our_target
);
2813 } while (message
== 0);
2815 if (((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
2816 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))) {
2817 currTar_Info
->TarLUNBusy
[lun
] = 1;
2818 pCurrCard
->currentSCCB
=
2819 pCurrCard
->discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[lun
]];
2820 if (pCurrCard
->currentSCCB
!= NULL
) {
2823 ACCEPT_MSG_ATN(port
);
2826 currTar_Info
->TarLUNBusy
[0] = 1;
2829 if (pCurrCard
->discQ_Tbl
[tag
] != NULL
) {
2830 pCurrCard
->currentSCCB
=
2831 pCurrCard
->discQ_Tbl
[tag
];
2832 currTar_Info
->TarTagQ_Cnt
--;
2835 ACCEPT_MSG_ATN(port
);
2838 pCurrCard
->currentSCCB
=
2839 pCurrCard
->discQ_Tbl
[currTar_Info
->LunDiscQ_Idx
[0]];
2840 if (pCurrCard
->currentSCCB
!= NULL
) {
2843 ACCEPT_MSG_ATN(port
);
2848 if (pCurrCard
->currentSCCB
!= NULL
) {
2849 if (pCurrCard
->currentSCCB
->Sccb_scsistat
== ABORT_ST
) {
2850 /* During Abort Tag command, the target could have got re-selected
2851 and completed the command. Check the select Q and remove the CCB
2852 if it is in the Select Q */
2853 FPT_queueFindSccb(pCurrCard
->currentSCCB
, p_card
);
2857 while (!(RDW_HARPOON((port
+ hp_intstat
)) & (PHASE
| RESET
)) &&
2858 !(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
) &&
2859 (RD_HARPOON(port
+ hp_scsisig
) & SCSI_BSY
)) ;
2862 static void FPT_SendMsg(unsigned long port
, unsigned char message
)
2864 while (!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)) {
2865 if (!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_BSY
)) {
2867 WRW_HARPOON((port
+ hp_intstat
), PHASE
);
2872 WRW_HARPOON((port
+ hp_intstat
), PHASE
);
2873 if ((RD_HARPOON(port
+ hp_scsisig
) & S_SCSI_PHZ
) == S_MSGO_PH
) {
2874 WRW_HARPOON((port
+ hp_intstat
),
2875 (BUS_FREE
| PHASE
| XFER_CNT_0
));
2877 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_BUS_EN
);
2879 WR_HARPOON(port
+ hp_scsidata_0
, message
);
2881 WR_HARPOON(port
+ hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
2885 WR_HARPOON(port
+ hp_portctrl_0
, 0x00);
2887 if ((message
== SMABORT
) || (message
== SMDEV_RESET
) ||
2888 (message
== SMABORT_TAG
)) {
2890 (RDW_HARPOON((port
+ hp_intstat
)) &
2891 (BUS_FREE
| PHASE
))) {
2894 if (RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
) {
2895 WRW_HARPOON((port
+ hp_intstat
), BUS_FREE
);
2901 /*---------------------------------------------------------------------
2903 * Function: FPT_sdecm
2905 * Description: Determine the proper responce to the message from the
2908 *---------------------------------------------------------------------*/
2909 static void FPT_sdecm(unsigned char message
, unsigned long port
,
2910 unsigned char p_card
)
2912 struct sccb
*currSCCB
;
2913 struct sccb_card
*CurrCard
;
2914 struct sccb_mgr_tar_info
*currTar_Info
;
2916 CurrCard
= &FPT_BL_Card
[p_card
];
2917 currSCCB
= CurrCard
->currentSCCB
;
2919 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
2921 if (message
== SMREST_DATA_PTR
) {
2922 if (!(currSCCB
->Sccb_XferState
& F_NO_DATA_YET
)) {
2923 currSCCB
->Sccb_ATC
= currSCCB
->Sccb_savedATC
;
2925 FPT_hostDataXferRestart(currSCCB
);
2929 WR_HARPOON(port
+ hp_autostart_1
,
2930 (AUTO_IMMED
+ DISCONNECT_START
));
2933 else if (message
== SMCMD_COMP
) {
2935 if (currSCCB
->Sccb_scsistat
== SELECT_Q_ST
) {
2936 currTar_Info
->TarStatus
&=
2937 ~(unsigned char)TAR_TAG_Q_MASK
;
2938 currTar_Info
->TarStatus
|= (unsigned char)TAG_Q_REJECT
;
2945 else if ((message
== SMNO_OP
) || (message
>= SMIDENT
)
2946 || (message
== SMINIT_RECOVERY
) || (message
== SMREL_RECOVERY
)) {
2949 WR_HARPOON(port
+ hp_autostart_1
,
2950 (AUTO_IMMED
+ DISCONNECT_START
));
2953 else if (message
== SMREJECT
) {
2955 if ((currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) ||
2956 (currSCCB
->Sccb_scsistat
== SELECT_WN_ST
) ||
2957 ((currTar_Info
->TarStatus
& TAR_SYNC_MASK
) == SYNC_TRYING
)
2958 || ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) ==
2961 WRW_HARPOON((port
+ hp_intstat
), BUS_FREE
);
2965 while ((!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)) &&
2966 (!(RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
)))
2970 if (currSCCB
->Lun
== 0x00) {
2971 if ((currSCCB
->Sccb_scsistat
== SELECT_SN_ST
)) {
2973 currTar_Info
->TarStatus
|=
2974 (unsigned char)SYNC_SUPPORTED
;
2976 currTar_Info
->TarEEValue
&=
2980 else if ((currSCCB
->Sccb_scsistat
==
2983 currTar_Info
->TarStatus
=
2985 TarStatus
& ~WIDE_ENABLED
) |
2988 currTar_Info
->TarEEValue
&=
2993 else if ((currTar_Info
->
2994 TarStatus
& TAR_TAG_Q_MASK
) ==
2996 currTar_Info
->TarStatus
=
2998 TarStatus
& ~(unsigned char)
2999 TAR_TAG_Q_MASK
) | TAG_Q_REJECT
;
3001 currSCCB
->ControlByte
&= ~F_USE_CMD_Q
;
3002 CurrCard
->discQCount
--;
3003 CurrCard
->discQ_Tbl
[currSCCB
->
3005 currSCCB
->Sccb_tag
= 0x00;
3010 if (RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
) {
3012 if (currSCCB
->Lun
== 0x00) {
3013 WRW_HARPOON((port
+ hp_intstat
),
3015 CurrCard
->globalFlags
|= F_NEW_SCCB_CMD
;
3021 if ((CurrCard
->globalFlags
& F_CONLUN_IO
) &&
3023 TarStatus
& TAR_TAG_Q_MASK
) !=
3025 currTar_Info
->TarLUNBusy
[currSCCB
->
3028 currTar_Info
->TarLUNBusy
[0] = 1;
3030 currSCCB
->ControlByte
&=
3031 ~(unsigned char)F_USE_CMD_Q
;
3033 WR_HARPOON(port
+ hp_autostart_1
,
3034 (AUTO_IMMED
+ DISCONNECT_START
));
3042 while ((!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)) &&
3043 (!(RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
)))
3047 if (!(RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
)) {
3048 WR_HARPOON(port
+ hp_autostart_1
,
3049 (AUTO_IMMED
+ DISCONNECT_START
));
3054 else if (message
== SMEXT
) {
3057 FPT_shandem(port
, p_card
, currSCCB
);
3060 else if (message
== SMIGNORWR
) {
3062 ACCEPT_MSG(port
); /* ACK the RESIDUE MSG */
3064 message
= FPT_sfm(port
, currSCCB
);
3066 if (currSCCB
->Sccb_scsimsg
!= SMPARITY
)
3068 WR_HARPOON(port
+ hp_autostart_1
,
3069 (AUTO_IMMED
+ DISCONNECT_START
));
3074 currSCCB
->HostStatus
= SCCB_PHASE_SEQUENCE_FAIL
;
3075 currSCCB
->Sccb_scsimsg
= SMREJECT
;
3077 ACCEPT_MSG_ATN(port
);
3078 WR_HARPOON(port
+ hp_autostart_1
,
3079 (AUTO_IMMED
+ DISCONNECT_START
));
3083 /*---------------------------------------------------------------------
3085 * Function: FPT_shandem
3087 * Description: Decide what to do with the extended message.
3089 *---------------------------------------------------------------------*/
3090 static void FPT_shandem(unsigned long port
, unsigned char p_card
,
3091 struct sccb
*pCurrSCCB
)
3093 unsigned char length
, message
;
3095 length
= FPT_sfm(port
, pCurrSCCB
);
3099 message
= FPT_sfm(port
, pCurrSCCB
);
3102 if (message
== SMSYNC
) {
3104 if (length
== 0x03) {
3107 FPT_stsyncn(port
, p_card
);
3110 pCurrSCCB
->Sccb_scsimsg
= SMREJECT
;
3111 ACCEPT_MSG_ATN(port
);
3113 } else if (message
== SMWDTR
) {
3115 if (length
== 0x02) {
3118 FPT_stwidn(port
, p_card
);
3121 pCurrSCCB
->Sccb_scsimsg
= SMREJECT
;
3122 ACCEPT_MSG_ATN(port
);
3124 WR_HARPOON(port
+ hp_autostart_1
,
3130 pCurrSCCB
->Sccb_scsimsg
= SMREJECT
;
3131 ACCEPT_MSG_ATN(port
);
3133 WR_HARPOON(port
+ hp_autostart_1
,
3134 (AUTO_IMMED
+ DISCONNECT_START
));
3137 if (pCurrSCCB
->Sccb_scsimsg
!= SMPARITY
)
3139 WR_HARPOON(port
+ hp_autostart_1
,
3140 (AUTO_IMMED
+ DISCONNECT_START
));
3143 if (pCurrSCCB
->Sccb_scsimsg
== SMPARITY
)
3144 WR_HARPOON(port
+ hp_autostart_1
,
3145 (AUTO_IMMED
+ DISCONNECT_START
));
3149 /*---------------------------------------------------------------------
3151 * Function: FPT_sisyncn
3153 * Description: Read in a message byte from the SCSI bus, and check
3154 * for a parity error.
3156 *---------------------------------------------------------------------*/
3158 static unsigned char FPT_sisyncn(unsigned long port
, unsigned char p_card
,
3159 unsigned char syncFlag
)
3161 struct sccb
*currSCCB
;
3162 struct sccb_mgr_tar_info
*currTar_Info
;
3164 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3165 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3167 if (!((currTar_Info
->TarStatus
& TAR_SYNC_MASK
) == SYNC_TRYING
)) {
3169 WRW_HARPOON((port
+ ID_MSG_STRT
),
3170 (MPM_OP
+ AMSG_OUT
+
3172 Sccb_idmsg
& ~(unsigned char)DISC_PRIV
)));
3174 WRW_HARPOON((port
+ ID_MSG_STRT
+ 2), BRH_OP
+ ALWAYS
+ CMDPZ
);
3176 WRW_HARPOON((port
+ SYNC_MSGS
+ 0),
3177 (MPM_OP
+ AMSG_OUT
+ SMEXT
));
3178 WRW_HARPOON((port
+ SYNC_MSGS
+ 2), (MPM_OP
+ AMSG_OUT
+ 0x03));
3179 WRW_HARPOON((port
+ SYNC_MSGS
+ 4),
3180 (MPM_OP
+ AMSG_OUT
+ SMSYNC
));
3182 if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_20MB
)
3184 WRW_HARPOON((port
+ SYNC_MSGS
+ 6),
3185 (MPM_OP
+ AMSG_OUT
+ 12));
3187 else if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) ==
3190 WRW_HARPOON((port
+ SYNC_MSGS
+ 6),
3191 (MPM_OP
+ AMSG_OUT
+ 25));
3193 else if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) ==
3196 WRW_HARPOON((port
+ SYNC_MSGS
+ 6),
3197 (MPM_OP
+ AMSG_OUT
+ 50));
3200 WRW_HARPOON((port
+ SYNC_MSGS
+ 6),
3201 (MPM_OP
+ AMSG_OUT
+ 00));
3203 WRW_HARPOON((port
+ SYNC_MSGS
+ 8), (RAT_OP
));
3204 WRW_HARPOON((port
+ SYNC_MSGS
+ 10),
3205 (MPM_OP
+ AMSG_OUT
+ DEFAULT_OFFSET
));
3206 WRW_HARPOON((port
+ SYNC_MSGS
+ 12), (BRH_OP
+ ALWAYS
+ NP
));
3208 if (syncFlag
== 0) {
3209 WR_HARPOON(port
+ hp_autostart_3
,
3210 (SELECT
+ SELCHK_STRT
));
3211 currTar_Info
->TarStatus
=
3213 TarStatus
& ~(unsigned char)TAR_SYNC_MASK
) |
3214 (unsigned char)SYNC_TRYING
);
3216 WR_HARPOON(port
+ hp_autostart_3
,
3217 (AUTO_IMMED
+ CMD_ONLY_STRT
));
3225 currTar_Info
->TarStatus
|= (unsigned char)SYNC_SUPPORTED
;
3226 currTar_Info
->TarEEValue
&= ~EE_SYNC_MASK
;
3231 /*---------------------------------------------------------------------
3233 * Function: FPT_stsyncn
3235 * Description: The has sent us a Sync Nego message so handle it as
3238 *---------------------------------------------------------------------*/
3239 static void FPT_stsyncn(unsigned long port
, unsigned char p_card
)
3241 unsigned char sync_msg
, offset
, sync_reg
, our_sync_msg
;
3242 struct sccb
*currSCCB
;
3243 struct sccb_mgr_tar_info
*currTar_Info
;
3245 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3246 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3248 sync_msg
= FPT_sfm(port
, currSCCB
);
3250 if ((sync_msg
== 0x00) && (currSCCB
->Sccb_scsimsg
== SMPARITY
)) {
3251 WR_HARPOON(port
+ hp_autostart_1
,
3252 (AUTO_IMMED
+ DISCONNECT_START
));
3258 offset
= FPT_sfm(port
, currSCCB
);
3260 if ((offset
== 0x00) && (currSCCB
->Sccb_scsimsg
== SMPARITY
)) {
3261 WR_HARPOON(port
+ hp_autostart_1
,
3262 (AUTO_IMMED
+ DISCONNECT_START
));
3266 if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_20MB
)
3268 our_sync_msg
= 12; /* Setup our Message to 20mb/s */
3270 else if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_10MB
)
3272 our_sync_msg
= 25; /* Setup our Message to 10mb/s */
3274 else if ((currTar_Info
->TarEEValue
& EE_SYNC_MASK
) == EE_SYNC_5MB
)
3276 our_sync_msg
= 50; /* Setup our Message to 5mb/s */
3279 our_sync_msg
= 0; /* Message = Async */
3281 if (sync_msg
< our_sync_msg
) {
3282 sync_msg
= our_sync_msg
; /*if faster, then set to max. */
3285 if (offset
== ASYNC
)
3288 if (offset
> MAX_OFFSET
)
3289 offset
= MAX_OFFSET
;
3295 sync_reg
= 0x20; /* Use 10MB/s */
3299 sync_reg
= 0x40; /* Use 6.6MB/s */
3303 sync_reg
= 0x60; /* Use 5MB/s */
3307 sync_reg
= 0x80; /* Use 4MB/s */
3311 sync_reg
= 0xA0; /* Use 3.33MB/s */
3315 sync_reg
= 0xC0; /* Use 2.85MB/s */
3319 sync_reg
= 0xE0; /* Use 2.5MB/s */
3321 if (sync_msg
> 100) {
3323 sync_reg
= 0x00; /* Use ASYNC */
3327 if (currTar_Info
->TarStatus
& WIDE_ENABLED
)
3333 sync_reg
|= (offset
| NARROW_SCSI
);
3335 FPT_sssyncv(port
, currSCCB
->TargID
, sync_reg
, currTar_Info
);
3337 if (currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) {
3341 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3342 ~(unsigned char)TAR_SYNC_MASK
) |
3343 (unsigned char)SYNC_SUPPORTED
);
3345 WR_HARPOON(port
+ hp_autostart_1
,
3346 (AUTO_IMMED
+ DISCONNECT_START
));
3351 ACCEPT_MSG_ATN(port
);
3353 FPT_sisyncr(port
, sync_msg
, offset
);
3355 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3356 ~(unsigned char)TAR_SYNC_MASK
) |
3357 (unsigned char)SYNC_SUPPORTED
);
3361 /*---------------------------------------------------------------------
3363 * Function: FPT_sisyncr
3365 * Description: Answer the targets sync message.
3367 *---------------------------------------------------------------------*/
3368 static void FPT_sisyncr(unsigned long port
, unsigned char sync_pulse
,
3369 unsigned char offset
)
3372 WRW_HARPOON((port
+ SYNC_MSGS
+ 0), (MPM_OP
+ AMSG_OUT
+ SMEXT
));
3373 WRW_HARPOON((port
+ SYNC_MSGS
+ 2), (MPM_OP
+ AMSG_OUT
+ 0x03));
3374 WRW_HARPOON((port
+ SYNC_MSGS
+ 4), (MPM_OP
+ AMSG_OUT
+ SMSYNC
));
3375 WRW_HARPOON((port
+ SYNC_MSGS
+ 6), (MPM_OP
+ AMSG_OUT
+ sync_pulse
));
3376 WRW_HARPOON((port
+ SYNC_MSGS
+ 8), (RAT_OP
));
3377 WRW_HARPOON((port
+ SYNC_MSGS
+ 10), (MPM_OP
+ AMSG_OUT
+ offset
));
3378 WRW_HARPOON((port
+ SYNC_MSGS
+ 12), (BRH_OP
+ ALWAYS
+ NP
));
3381 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
3382 WRW_HARPOON((port
+ hp_intstat
), CLR_ALL_INT_1
);
3384 WR_HARPOON(port
+ hp_autostart_3
, (AUTO_IMMED
+ CMD_ONLY_STRT
));
3386 while (!(RDW_HARPOON((port
+ hp_intstat
)) & (BUS_FREE
| AUTO_INT
))) {
3390 /*---------------------------------------------------------------------
3392 * Function: FPT_siwidn
3394 * Description: Read in a message byte from the SCSI bus, and check
3395 * for a parity error.
3397 *---------------------------------------------------------------------*/
3399 static unsigned char FPT_siwidn(unsigned long port
, unsigned char p_card
)
3401 struct sccb
*currSCCB
;
3402 struct sccb_mgr_tar_info
*currTar_Info
;
3404 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3405 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3407 if (!((currTar_Info
->TarStatus
& TAR_WIDE_MASK
) == WIDE_NEGOCIATED
)) {
3409 WRW_HARPOON((port
+ ID_MSG_STRT
),
3410 (MPM_OP
+ AMSG_OUT
+
3412 Sccb_idmsg
& ~(unsigned char)DISC_PRIV
)));
3414 WRW_HARPOON((port
+ ID_MSG_STRT
+ 2), BRH_OP
+ ALWAYS
+ CMDPZ
);
3416 WRW_HARPOON((port
+ SYNC_MSGS
+ 0),
3417 (MPM_OP
+ AMSG_OUT
+ SMEXT
));
3418 WRW_HARPOON((port
+ SYNC_MSGS
+ 2), (MPM_OP
+ AMSG_OUT
+ 0x02));
3419 WRW_HARPOON((port
+ SYNC_MSGS
+ 4),
3420 (MPM_OP
+ AMSG_OUT
+ SMWDTR
));
3421 WRW_HARPOON((port
+ SYNC_MSGS
+ 6), (RAT_OP
));
3422 WRW_HARPOON((port
+ SYNC_MSGS
+ 8),
3423 (MPM_OP
+ AMSG_OUT
+ SM16BIT
));
3424 WRW_HARPOON((port
+ SYNC_MSGS
+ 10), (BRH_OP
+ ALWAYS
+ NP
));
3426 WR_HARPOON(port
+ hp_autostart_3
, (SELECT
+ SELCHK_STRT
));
3428 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3429 ~(unsigned char)TAR_WIDE_MASK
) |
3430 (unsigned char)WIDE_ENABLED
);
3437 currTar_Info
->TarStatus
= ((currTar_Info
->TarStatus
&
3438 ~(unsigned char)TAR_WIDE_MASK
) |
3441 currTar_Info
->TarEEValue
&= ~EE_WIDE_SCSI
;
3446 /*---------------------------------------------------------------------
3448 * Function: FPT_stwidn
3450 * Description: The has sent us a Wide Nego message so handle it as
3453 *---------------------------------------------------------------------*/
3454 static void FPT_stwidn(unsigned long port
, unsigned char p_card
)
3456 unsigned char width
;
3457 struct sccb
*currSCCB
;
3458 struct sccb_mgr_tar_info
*currTar_Info
;
3460 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3461 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
];
3463 width
= FPT_sfm(port
, currSCCB
);
3465 if ((width
== 0x00) && (currSCCB
->Sccb_scsimsg
== SMPARITY
)) {
3466 WR_HARPOON(port
+ hp_autostart_1
,
3467 (AUTO_IMMED
+ DISCONNECT_START
));
3471 if (!(currTar_Info
->TarEEValue
& EE_WIDE_SCSI
))
3475 currTar_Info
->TarStatus
|= WIDE_ENABLED
;
3478 width
= NARROW_SCSI
;
3479 currTar_Info
->TarStatus
&= ~WIDE_ENABLED
;
3482 FPT_sssyncv(port
, currSCCB
->TargID
, width
, currTar_Info
);
3484 if (currSCCB
->Sccb_scsistat
== SELECT_WN_ST
) {
3486 currTar_Info
->TarStatus
|= WIDE_NEGOCIATED
;
3489 ((currTar_Info
->TarStatus
& TAR_SYNC_MASK
) ==
3491 ACCEPT_MSG_ATN(port
);
3493 FPT_sisyncn(port
, p_card
, 1);
3494 currSCCB
->Sccb_scsistat
= SELECT_SN_ST
;
3498 WR_HARPOON(port
+ hp_autostart_1
,
3499 (AUTO_IMMED
+ DISCONNECT_START
));
3505 ACCEPT_MSG_ATN(port
);
3507 if (currTar_Info
->TarEEValue
& EE_WIDE_SCSI
)
3512 FPT_siwidr(port
, width
);
3514 currTar_Info
->TarStatus
|= (WIDE_NEGOCIATED
| WIDE_ENABLED
);
3518 /*---------------------------------------------------------------------
3520 * Function: FPT_siwidr
3522 * Description: Answer the targets Wide nego message.
3524 *---------------------------------------------------------------------*/
3525 static void FPT_siwidr(unsigned long port
, unsigned char width
)
3528 WRW_HARPOON((port
+ SYNC_MSGS
+ 0), (MPM_OP
+ AMSG_OUT
+ SMEXT
));
3529 WRW_HARPOON((port
+ SYNC_MSGS
+ 2), (MPM_OP
+ AMSG_OUT
+ 0x02));
3530 WRW_HARPOON((port
+ SYNC_MSGS
+ 4), (MPM_OP
+ AMSG_OUT
+ SMWDTR
));
3531 WRW_HARPOON((port
+ SYNC_MSGS
+ 6), (RAT_OP
));
3532 WRW_HARPOON((port
+ SYNC_MSGS
+ 8), (MPM_OP
+ AMSG_OUT
+ width
));
3533 WRW_HARPOON((port
+ SYNC_MSGS
+ 10), (BRH_OP
+ ALWAYS
+ NP
));
3536 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
3537 WRW_HARPOON((port
+ hp_intstat
), CLR_ALL_INT_1
);
3539 WR_HARPOON(port
+ hp_autostart_3
, (AUTO_IMMED
+ CMD_ONLY_STRT
));
3541 while (!(RDW_HARPOON((port
+ hp_intstat
)) & (BUS_FREE
| AUTO_INT
))) {
3545 /*---------------------------------------------------------------------
3547 * Function: FPT_sssyncv
3549 * Description: Write the desired value to the Sync Register for the
3552 *---------------------------------------------------------------------*/
3553 static void FPT_sssyncv(unsigned long p_port
, unsigned char p_id
,
3554 unsigned char p_sync_value
,
3555 struct sccb_mgr_tar_info
*currTar_Info
)
3557 unsigned char index
;
3564 index
= 12; /* hp_synctarg_0 */
3567 index
= 13; /* hp_synctarg_1 */
3570 index
= 14; /* hp_synctarg_2 */
3573 index
= 15; /* hp_synctarg_3 */
3576 index
= 8; /* hp_synctarg_4 */
3579 index
= 9; /* hp_synctarg_5 */
3582 index
= 10; /* hp_synctarg_6 */
3585 index
= 11; /* hp_synctarg_7 */
3588 index
= 4; /* hp_synctarg_8 */
3591 index
= 5; /* hp_synctarg_9 */
3594 index
= 6; /* hp_synctarg_10 */
3597 index
= 7; /* hp_synctarg_11 */
3600 index
= 0; /* hp_synctarg_12 */
3603 index
= 1; /* hp_synctarg_13 */
3606 index
= 2; /* hp_synctarg_14 */
3609 index
= 3; /* hp_synctarg_15 */
3613 WR_HARPOON(p_port
+ hp_synctarg_base
+ index
, p_sync_value
);
3615 currTar_Info
->TarSyncCtrl
= p_sync_value
;
3618 /*---------------------------------------------------------------------
3620 * Function: FPT_sresb
3622 * Description: Reset the desired card's SCSI bus.
3624 *---------------------------------------------------------------------*/
3625 static void FPT_sresb(unsigned long port
, unsigned char p_card
)
3627 unsigned char scsiID
, i
;
3629 struct sccb_mgr_tar_info
*currTar_Info
;
3631 WR_HARPOON(port
+ hp_page_ctrl
,
3632 (RD_HARPOON(port
+ hp_page_ctrl
) | G_INT_DISABLE
));
3633 WRW_HARPOON((port
+ hp_intstat
), CLR_ALL_INT
);
3635 WR_HARPOON(port
+ hp_scsictrl_0
, SCSI_RST
);
3637 scsiID
= RD_HARPOON(port
+ hp_seltimeout
);
3638 WR_HARPOON(port
+ hp_seltimeout
, TO_5ms
);
3639 WRW_HARPOON((port
+ hp_intstat
), TIMEOUT
);
3641 WR_HARPOON(port
+ hp_portctrl_0
, (SCSI_PORT
| START_TO
));
3643 while (!(RDW_HARPOON((port
+ hp_intstat
)) & TIMEOUT
)) {
3646 WR_HARPOON(port
+ hp_seltimeout
, scsiID
);
3648 WR_HARPOON(port
+ hp_scsictrl_0
, ENA_SCAM_SEL
);
3650 FPT_Wait(port
, TO_5ms
);
3652 WRW_HARPOON((port
+ hp_intstat
), CLR_ALL_INT
);
3654 WR_HARPOON(port
+ hp_int_mask
, (RD_HARPOON(port
+ hp_int_mask
) | 0x00));
3656 for (scsiID
= 0; scsiID
< MAX_SCSI_TAR
; scsiID
++) {
3657 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][scsiID
];
3659 if (currTar_Info
->TarEEValue
& EE_SYNC_MASK
) {
3660 currTar_Info
->TarSyncCtrl
= 0;
3661 currTar_Info
->TarStatus
&= ~TAR_SYNC_MASK
;
3664 if (currTar_Info
->TarEEValue
& EE_WIDE_SCSI
) {
3665 currTar_Info
->TarStatus
&= ~TAR_WIDE_MASK
;
3668 FPT_sssyncv(port
, scsiID
, NARROW_SCSI
, currTar_Info
);
3670 FPT_SccbMgrTableInitTarget(p_card
, scsiID
);
3673 FPT_BL_Card
[p_card
].scanIndex
= 0x00;
3674 FPT_BL_Card
[p_card
].currentSCCB
= NULL
;
3675 FPT_BL_Card
[p_card
].globalFlags
&= ~(F_TAG_STARTED
| F_HOST_XFER_ACT
3677 FPT_BL_Card
[p_card
].cmdCounter
= 0x00;
3678 FPT_BL_Card
[p_card
].discQCount
= 0x00;
3679 FPT_BL_Card
[p_card
].tagQ_Lst
= 0x01;
3681 for (i
= 0; i
< QUEUE_DEPTH
; i
++)
3682 FPT_BL_Card
[p_card
].discQ_Tbl
[i
] = NULL
;
3684 WR_HARPOON(port
+ hp_page_ctrl
,
3685 (RD_HARPOON(port
+ hp_page_ctrl
) & ~G_INT_DISABLE
));
3689 /*---------------------------------------------------------------------
3691 * Function: FPT_ssenss
3693 * Description: Setup for the Auto Sense command.
3695 *---------------------------------------------------------------------*/
3696 static void FPT_ssenss(struct sccb_card
*pCurrCard
)
3699 struct sccb
*currSCCB
;
3701 currSCCB
= pCurrCard
->currentSCCB
;
3703 currSCCB
->Save_CdbLen
= currSCCB
->CdbLength
;
3705 for (i
= 0; i
< 6; i
++) {
3707 currSCCB
->Save_Cdb
[i
] = currSCCB
->Cdb
[i
];
3710 currSCCB
->CdbLength
= SIX_BYTE_CMD
;
3711 currSCCB
->Cdb
[0] = SCSI_REQUEST_SENSE
;
3712 currSCCB
->Cdb
[1] = currSCCB
->Cdb
[1] & (unsigned char)0xE0; /*Keep LUN. */
3713 currSCCB
->Cdb
[2] = 0x00;
3714 currSCCB
->Cdb
[3] = 0x00;
3715 currSCCB
->Cdb
[4] = currSCCB
->RequestSenseLength
;
3716 currSCCB
->Cdb
[5] = 0x00;
3718 currSCCB
->Sccb_XferCnt
= (unsigned long)currSCCB
->RequestSenseLength
;
3720 currSCCB
->Sccb_ATC
= 0x00;
3722 currSCCB
->Sccb_XferState
|= F_AUTO_SENSE
;
3724 currSCCB
->Sccb_XferState
&= ~F_SG_XFER
;
3726 currSCCB
->Sccb_idmsg
= currSCCB
->Sccb_idmsg
& ~(unsigned char)DISC_PRIV
;
3728 currSCCB
->ControlByte
= 0x00;
3730 currSCCB
->Sccb_MGRFlags
&= F_STATUSLOADED
;
3733 /*---------------------------------------------------------------------
3735 * Function: FPT_sxfrp
3737 * Description: Transfer data into the bit bucket until the device
3738 * decides to switch phase.
3740 *---------------------------------------------------------------------*/
3742 static void FPT_sxfrp(unsigned long p_port
, unsigned char p_card
)
3744 unsigned char curr_phz
;
3746 DISABLE_AUTO(p_port
);
3748 if (FPT_BL_Card
[p_card
].globalFlags
& F_HOST_XFER_ACT
) {
3750 FPT_hostDataXferAbort(p_port
, p_card
,
3751 FPT_BL_Card
[p_card
].currentSCCB
);
3755 /* If the Automation handled the end of the transfer then do not
3756 match the phase or we will get out of sync with the ISR. */
3758 if (RDW_HARPOON((p_port
+ hp_intstat
)) &
3759 (BUS_FREE
| XFER_CNT_0
| AUTO_INT
))
3762 WR_HARPOON(p_port
+ hp_xfercnt_0
, 0x00);
3764 curr_phz
= RD_HARPOON(p_port
+ hp_scsisig
) & (unsigned char)S_SCSI_PHZ
;
3766 WRW_HARPOON((p_port
+ hp_intstat
), XFER_CNT_0
);
3768 WR_HARPOON(p_port
+ hp_scsisig
, curr_phz
);
3770 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) & (BUS_FREE
| RESET
)) &&
3772 (RD_HARPOON(p_port
+ hp_scsisig
) & (unsigned char)S_SCSI_PHZ
)))
3774 if (curr_phz
& (unsigned char)SCSI_IOBIT
) {
3775 WR_HARPOON(p_port
+ hp_portctrl_0
,
3776 (SCSI_PORT
| HOST_PORT
| SCSI_INBIT
));
3778 if (!(RD_HARPOON(p_port
+ hp_xferstat
) & FIFO_EMPTY
)) {
3779 RD_HARPOON(p_port
+ hp_fifodata_0
);
3782 WR_HARPOON(p_port
+ hp_portctrl_0
,
3783 (SCSI_PORT
| HOST_PORT
| HOST_WRT
));
3784 if (RD_HARPOON(p_port
+ hp_xferstat
) & FIFO_EMPTY
) {
3785 WR_HARPOON(p_port
+ hp_fifodata_0
, 0xFA);
3788 } /* End of While loop for padding data I/O phase */
3790 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) & (BUS_FREE
| RESET
))) {
3791 if (RD_HARPOON(p_port
+ hp_scsisig
) & SCSI_REQ
)
3795 WR_HARPOON(p_port
+ hp_portctrl_0
,
3796 (SCSI_PORT
| HOST_PORT
| SCSI_INBIT
));
3797 while (!(RD_HARPOON(p_port
+ hp_xferstat
) & FIFO_EMPTY
)) {
3798 RD_HARPOON(p_port
+ hp_fifodata_0
);
3801 if (!(RDW_HARPOON((p_port
+ hp_intstat
)) & (BUS_FREE
| RESET
))) {
3802 WR_HARPOON(p_port
+ hp_autostart_0
,
3803 (AUTO_IMMED
+ DISCONNECT_START
));
3804 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) & AUTO_INT
)) {
3807 if (RDW_HARPOON((p_port
+ hp_intstat
)) &
3808 (ICMD_COMP
| ITAR_DISC
))
3810 (RDW_HARPOON((p_port
+ hp_intstat
)) &
3811 (BUS_FREE
| RSEL
))) ;
3815 /*---------------------------------------------------------------------
3817 * Function: FPT_schkdd
3819 * Description: Make sure data has been flushed from both FIFOs and abort
3820 * the operations if necessary.
3822 *---------------------------------------------------------------------*/
3824 static void FPT_schkdd(unsigned long port
, unsigned char p_card
)
3826 unsigned short TimeOutLoop
;
3827 unsigned char sPhase
;
3829 struct sccb
*currSCCB
;
3831 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
3833 if ((currSCCB
->Sccb_scsistat
!= DATA_OUT_ST
) &&
3834 (currSCCB
->Sccb_scsistat
!= DATA_IN_ST
)) {
3838 if (currSCCB
->Sccb_XferState
& F_ODD_BALL_CNT
) {
3840 currSCCB
->Sccb_ATC
+= (currSCCB
->Sccb_XferCnt
- 1);
3842 currSCCB
->Sccb_XferCnt
= 1;
3844 currSCCB
->Sccb_XferState
&= ~F_ODD_BALL_CNT
;
3845 WRW_HARPOON((port
+ hp_fiforead
), (unsigned short)0x00);
3846 WR_HARPOON(port
+ hp_xferstat
, 0x00);
3851 currSCCB
->Sccb_ATC
+= currSCCB
->Sccb_XferCnt
;
3853 currSCCB
->Sccb_XferCnt
= 0;
3856 if ((RDW_HARPOON((port
+ hp_intstat
)) & PARITY
) &&
3857 (currSCCB
->HostStatus
== SCCB_COMPLETE
)) {
3859 currSCCB
->HostStatus
= SCCB_PARITY_ERR
;
3860 WRW_HARPOON((port
+ hp_intstat
), PARITY
);
3863 FPT_hostDataXferAbort(port
, p_card
, currSCCB
);
3865 while (RD_HARPOON(port
+ hp_scsisig
) & SCSI_ACK
) {
3870 while (RD_HARPOON(port
+ hp_xferstat
) & FIFO_EMPTY
) {
3871 if (RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
) {
3874 if (RD_HARPOON(port
+ hp_offsetctr
) & (unsigned char)0x1F) {
3877 if (RDW_HARPOON((port
+ hp_intstat
)) & RESET
) {
3880 if ((RD_HARPOON(port
+ hp_scsisig
) & SCSI_REQ
)
3881 || (TimeOutLoop
++ > 0x3000))
3885 sPhase
= RD_HARPOON(port
+ hp_scsisig
) & (SCSI_BSY
| S_SCSI_PHZ
);
3886 if ((!(RD_HARPOON(port
+ hp_xferstat
) & FIFO_EMPTY
)) ||
3887 (RD_HARPOON(port
+ hp_offsetctr
) & (unsigned char)0x1F) ||
3888 (sPhase
== (SCSI_BSY
| S_DATAO_PH
)) ||
3889 (sPhase
== (SCSI_BSY
| S_DATAI_PH
))) {
3891 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
3893 if (!(currSCCB
->Sccb_XferState
& F_ALL_XFERRED
)) {
3894 if (currSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
) {
3895 FPT_phaseDataIn(port
, p_card
);
3899 FPT_phaseDataOut(port
, p_card
);
3902 FPT_sxfrp(port
, p_card
);
3903 if (!(RDW_HARPOON((port
+ hp_intstat
)) &
3904 (BUS_FREE
| ICMD_COMP
| ITAR_DISC
| RESET
))) {
3905 WRW_HARPOON((port
+ hp_intstat
), AUTO_INT
);
3906 FPT_phaseDecode(port
, p_card
);
3913 WR_HARPOON(port
+ hp_portctrl_0
, 0x00);
3917 /*---------------------------------------------------------------------
3919 * Function: FPT_sinits
3921 * Description: Setup SCCB manager fields in this SCCB.
3923 *---------------------------------------------------------------------*/
3925 static void FPT_sinits(struct sccb
*p_sccb
, unsigned char p_card
)
3927 struct sccb_mgr_tar_info
*currTar_Info
;
3929 if ((p_sccb
->TargID
> MAX_SCSI_TAR
) || (p_sccb
->Lun
> MAX_LUN
)) {
3932 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
];
3934 p_sccb
->Sccb_XferState
= 0x00;
3935 p_sccb
->Sccb_XferCnt
= p_sccb
->DataLength
;
3937 if ((p_sccb
->OperationCode
== SCATTER_GATHER_COMMAND
) ||
3938 (p_sccb
->OperationCode
== RESIDUAL_SG_COMMAND
)) {
3940 p_sccb
->Sccb_SGoffset
= 0;
3941 p_sccb
->Sccb_XferState
= F_SG_XFER
;
3942 p_sccb
->Sccb_XferCnt
= 0x00;
3945 if (p_sccb
->DataLength
== 0x00)
3947 p_sccb
->Sccb_XferState
|= F_ALL_XFERRED
;
3949 if (p_sccb
->ControlByte
& F_USE_CMD_Q
) {
3950 if ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) == TAG_Q_REJECT
)
3951 p_sccb
->ControlByte
&= ~F_USE_CMD_Q
;
3954 currTar_Info
->TarStatus
|= TAG_Q_TRYING
;
3957 /* For !single SCSI device in system & device allow Disconnect
3958 or command is tag_q type then send Cmd with Disconnect Enable
3959 else send Cmd with Disconnect Disable */
3962 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
3963 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
3964 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3966 if ((currTar_Info
->TarStatus
& TAR_ALLOW_DISC
) ||
3967 (currTar_Info
->TarStatus
& TAG_Q_TRYING
)) {
3968 p_sccb
->Sccb_idmsg
=
3969 (unsigned char)(SMIDENT
| DISC_PRIV
) | p_sccb
->Lun
;
3974 p_sccb
->Sccb_idmsg
= (unsigned char)SMIDENT
| p_sccb
->Lun
;
3977 p_sccb
->HostStatus
= 0x00;
3978 p_sccb
->TargetStatus
= 0x00;
3979 p_sccb
->Sccb_tag
= 0x00;
3980 p_sccb
->Sccb_MGRFlags
= 0x00;
3981 p_sccb
->Sccb_sgseg
= 0x00;
3982 p_sccb
->Sccb_ATC
= 0x00;
3983 p_sccb
->Sccb_savedATC
= 0x00;
3985 p_sccb->SccbVirtDataPtr = 0x00;
3986 p_sccb->Sccb_forwardlink = NULL;
3987 p_sccb->Sccb_backlink = NULL;
3989 p_sccb
->Sccb_scsistat
= BUS_FREE_ST
;
3990 p_sccb
->SccbStatus
= SCCB_IN_PROCESS
;
3991 p_sccb
->Sccb_scsimsg
= SMNO_OP
;
3995 /*---------------------------------------------------------------------
3997 * Function: Phase Decode
3999 * Description: Determine the phase and call the appropriate function.
4001 *---------------------------------------------------------------------*/
4003 static void FPT_phaseDecode(unsigned long p_port
, unsigned char p_card
)
4005 unsigned char phase_ref
;
4006 void (*phase
) (unsigned long, unsigned char);
4008 DISABLE_AUTO(p_port
);
4011 (unsigned char)(RD_HARPOON(p_port
+ hp_scsisig
) & S_SCSI_PHZ
);
4013 phase
= FPT_s_PhaseTbl
[phase_ref
];
4015 (*phase
) (p_port
, p_card
); /* Call the correct phase func */
4018 /*---------------------------------------------------------------------
4020 * Function: Data Out Phase
4022 * Description: Start up both the BusMaster and Xbow.
4024 *---------------------------------------------------------------------*/
4026 static void FPT_phaseDataOut(unsigned long port
, unsigned char p_card
)
4029 struct sccb
*currSCCB
;
4031 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4032 if (currSCCB
== NULL
) {
4033 return; /* Exit if No SCCB record */
4036 currSCCB
->Sccb_scsistat
= DATA_OUT_ST
;
4037 currSCCB
->Sccb_XferState
&= ~(F_HOST_XFER_DIR
| F_NO_DATA_YET
);
4039 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
4041 WRW_HARPOON((port
+ hp_intstat
), XFER_CNT_0
);
4043 WR_HARPOON(port
+ hp_autostart_0
, (END_DATA
+ END_DATA_START
));
4045 FPT_dataXferProcessor(port
, &FPT_BL_Card
[p_card
]);
4047 if (currSCCB
->Sccb_XferCnt
== 0) {
4049 if ((currSCCB
->ControlByte
& SCCB_DATA_XFER_OUT
) &&
4050 (currSCCB
->HostStatus
== SCCB_COMPLETE
))
4051 currSCCB
->HostStatus
= SCCB_DATA_OVER_RUN
;
4053 FPT_sxfrp(port
, p_card
);
4054 if (!(RDW_HARPOON((port
+ hp_intstat
)) & (BUS_FREE
| RESET
)))
4055 FPT_phaseDecode(port
, p_card
);
4059 /*---------------------------------------------------------------------
4061 * Function: Data In Phase
4063 * Description: Startup the BusMaster and the XBOW.
4065 *---------------------------------------------------------------------*/
4067 static void FPT_phaseDataIn(unsigned long port
, unsigned char p_card
)
4070 struct sccb
*currSCCB
;
4072 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4074 if (currSCCB
== NULL
) {
4075 return; /* Exit if No SCCB record */
4078 currSCCB
->Sccb_scsistat
= DATA_IN_ST
;
4079 currSCCB
->Sccb_XferState
|= F_HOST_XFER_DIR
;
4080 currSCCB
->Sccb_XferState
&= ~F_NO_DATA_YET
;
4082 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_PORT
);
4084 WRW_HARPOON((port
+ hp_intstat
), XFER_CNT_0
);
4086 WR_HARPOON(port
+ hp_autostart_0
, (END_DATA
+ END_DATA_START
));
4088 FPT_dataXferProcessor(port
, &FPT_BL_Card
[p_card
]);
4090 if (currSCCB
->Sccb_XferCnt
== 0) {
4092 if ((currSCCB
->ControlByte
& SCCB_DATA_XFER_IN
) &&
4093 (currSCCB
->HostStatus
== SCCB_COMPLETE
))
4094 currSCCB
->HostStatus
= SCCB_DATA_OVER_RUN
;
4096 FPT_sxfrp(port
, p_card
);
4097 if (!(RDW_HARPOON((port
+ hp_intstat
)) & (BUS_FREE
| RESET
)))
4098 FPT_phaseDecode(port
, p_card
);
4103 /*---------------------------------------------------------------------
4105 * Function: Command Phase
4107 * Description: Load the CDB into the automation and start it up.
4109 *---------------------------------------------------------------------*/
4111 static void FPT_phaseCommand(unsigned long p_port
, unsigned char p_card
)
4113 struct sccb
*currSCCB
;
4114 unsigned long cdb_reg
;
4117 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4119 if (currSCCB
->OperationCode
== RESET_COMMAND
) {
4121 currSCCB
->HostStatus
= SCCB_PHASE_SEQUENCE_FAIL
;
4122 currSCCB
->CdbLength
= SIX_BYTE_CMD
;
4125 WR_HARPOON(p_port
+ hp_scsisig
, 0x00);
4127 ARAM_ACCESS(p_port
);
4129 cdb_reg
= p_port
+ CMD_STRT
;
4131 for (i
= 0; i
< currSCCB
->CdbLength
; i
++) {
4133 if (currSCCB
->OperationCode
== RESET_COMMAND
)
4135 WRW_HARPOON(cdb_reg
, (MPM_OP
+ ACOMMAND
+ 0x00));
4138 WRW_HARPOON(cdb_reg
,
4139 (MPM_OP
+ ACOMMAND
+ currSCCB
->Cdb
[i
]));
4143 if (currSCCB
->CdbLength
!= TWELVE_BYTE_CMD
)
4144 WRW_HARPOON(cdb_reg
, (BRH_OP
+ ALWAYS
+ NP
));
4146 WR_HARPOON(p_port
+ hp_portctrl_0
, (SCSI_PORT
));
4148 currSCCB
->Sccb_scsistat
= COMMAND_ST
;
4150 WR_HARPOON(p_port
+ hp_autostart_3
, (AUTO_IMMED
| CMD_ONLY_STRT
));
4151 SGRAM_ACCESS(p_port
);
4154 /*---------------------------------------------------------------------
4156 * Function: Status phase
4158 * Description: Bring in the status and command complete message bytes
4160 *---------------------------------------------------------------------*/
4162 static void FPT_phaseStatus(unsigned long port
, unsigned char p_card
)
4164 /* Start-up the automation to finish off this command and let the
4165 isr handle the interrupt for command complete when it comes in.
4166 We could wait here for the interrupt to be generated?
4169 WR_HARPOON(port
+ hp_scsisig
, 0x00);
4171 WR_HARPOON(port
+ hp_autostart_0
, (AUTO_IMMED
+ END_DATA_START
));
4174 /*---------------------------------------------------------------------
4176 * Function: Phase Message Out
4178 * Description: Send out our message (if we have one) and handle whatever
4181 *---------------------------------------------------------------------*/
4183 static void FPT_phaseMsgOut(unsigned long port
, unsigned char p_card
)
4185 unsigned char message
, scsiID
;
4186 struct sccb
*currSCCB
;
4187 struct sccb_mgr_tar_info
*currTar_Info
;
4189 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4191 if (currSCCB
!= NULL
) {
4193 message
= currSCCB
->Sccb_scsimsg
;
4194 scsiID
= currSCCB
->TargID
;
4196 if (message
== SMDEV_RESET
) {
4198 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][scsiID
];
4199 currTar_Info
->TarSyncCtrl
= 0;
4200 FPT_sssyncv(port
, scsiID
, NARROW_SCSI
, currTar_Info
);
4202 if (FPT_sccbMgrTbl
[p_card
][scsiID
].
4203 TarEEValue
& EE_SYNC_MASK
) {
4205 FPT_sccbMgrTbl
[p_card
][scsiID
].TarStatus
&=
4210 if (FPT_sccbMgrTbl
[p_card
][scsiID
].
4211 TarEEValue
& EE_WIDE_SCSI
) {
4213 FPT_sccbMgrTbl
[p_card
][scsiID
].TarStatus
&=
4217 FPT_queueFlushSccb(p_card
, SCCB_COMPLETE
);
4218 FPT_SccbMgrTableInitTarget(p_card
, scsiID
);
4219 } else if (currSCCB
->Sccb_scsistat
== ABORT_ST
) {
4220 currSCCB
->HostStatus
= SCCB_COMPLETE
;
4221 if (FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->Sccb_tag
] !=
4223 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->
4225 FPT_sccbMgrTbl
[p_card
][scsiID
].TarTagQ_Cnt
--;
4230 else if (currSCCB
->Sccb_scsistat
< COMMAND_ST
) {
4232 if (message
== SMNO_OP
) {
4233 currSCCB
->Sccb_MGRFlags
|= F_DEV_SELECTED
;
4235 FPT_ssel(port
, p_card
);
4240 if (message
== SMABORT
)
4242 FPT_queueFlushSccb(p_card
, SCCB_COMPLETE
);
4249 WRW_HARPOON((port
+ hp_intstat
), (BUS_FREE
| PHASE
| XFER_CNT_0
));
4251 WR_HARPOON(port
+ hp_portctrl_0
, SCSI_BUS_EN
);
4253 WR_HARPOON(port
+ hp_scsidata_0
, message
);
4255 WR_HARPOON(port
+ hp_scsisig
, (SCSI_ACK
+ S_ILL_PH
));
4259 WR_HARPOON(port
+ hp_portctrl_0
, 0x00);
4261 if ((message
== SMABORT
) || (message
== SMDEV_RESET
) ||
4262 (message
== SMABORT_TAG
)) {
4264 while (!(RDW_HARPOON((port
+ hp_intstat
)) & (BUS_FREE
| PHASE
))) {
4267 if (RDW_HARPOON((port
+ hp_intstat
)) & BUS_FREE
) {
4268 WRW_HARPOON((port
+ hp_intstat
), BUS_FREE
);
4270 if (currSCCB
!= NULL
) {
4272 if ((FPT_BL_Card
[p_card
].
4273 globalFlags
& F_CONLUN_IO
)
4275 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4276 TarStatus
& TAR_TAG_Q_MASK
) !=
4278 FPT_sccbMgrTbl
[p_card
][currSCCB
->
4280 TarLUNBusy
[currSCCB
->Lun
] = 0;
4282 FPT_sccbMgrTbl
[p_card
][currSCCB
->
4286 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
],
4291 FPT_BL_Card
[p_card
].globalFlags
|=
4298 FPT_sxfrp(port
, p_card
);
4304 if (message
== SMPARITY
) {
4305 currSCCB
->Sccb_scsimsg
= SMNO_OP
;
4306 WR_HARPOON(port
+ hp_autostart_1
,
4307 (AUTO_IMMED
+ DISCONNECT_START
));
4309 FPT_sxfrp(port
, p_card
);
4314 /*---------------------------------------------------------------------
4316 * Function: Message In phase
4318 * Description: Bring in the message and determine what to do with it.
4320 *---------------------------------------------------------------------*/
4322 static void FPT_phaseMsgIn(unsigned long port
, unsigned char p_card
)
4324 unsigned char message
;
4325 struct sccb
*currSCCB
;
4327 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4329 if (FPT_BL_Card
[p_card
].globalFlags
& F_HOST_XFER_ACT
) {
4331 FPT_phaseChkFifo(port
, p_card
);
4334 message
= RD_HARPOON(port
+ hp_scsidata_0
);
4335 if ((message
== SMDISC
) || (message
== SMSAVE_DATA_PTR
)) {
4337 WR_HARPOON(port
+ hp_autostart_1
,
4338 (AUTO_IMMED
+ END_DATA_START
));
4344 message
= FPT_sfm(port
, currSCCB
);
4347 FPT_sdecm(message
, port
, p_card
);
4350 if (currSCCB
->Sccb_scsimsg
!= SMPARITY
)
4352 WR_HARPOON(port
+ hp_autostart_1
,
4353 (AUTO_IMMED
+ DISCONNECT_START
));
4359 /*---------------------------------------------------------------------
4361 * Function: Illegal phase
4363 * Description: Target switched to some illegal phase, so all we can do
4364 * is report an error back to the host (if that is possible)
4365 * and send an ABORT message to the misbehaving target.
4367 *---------------------------------------------------------------------*/
4369 static void FPT_phaseIllegal(unsigned long port
, unsigned char p_card
)
4371 struct sccb
*currSCCB
;
4373 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4375 WR_HARPOON(port
+ hp_scsisig
, RD_HARPOON(port
+ hp_scsisig
));
4376 if (currSCCB
!= NULL
) {
4378 currSCCB
->HostStatus
= SCCB_PHASE_SEQUENCE_FAIL
;
4379 currSCCB
->Sccb_scsistat
= ABORT_ST
;
4380 currSCCB
->Sccb_scsimsg
= SMABORT
;
4383 ACCEPT_MSG_ATN(port
);
4386 /*---------------------------------------------------------------------
4388 * Function: Phase Check FIFO
4390 * Description: Make sure data has been flushed from both FIFOs and abort
4391 * the operations if necessary.
4393 *---------------------------------------------------------------------*/
4395 static void FPT_phaseChkFifo(unsigned long port
, unsigned char p_card
)
4397 unsigned long xfercnt
;
4398 struct sccb
*currSCCB
;
4400 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4402 if (currSCCB
->Sccb_scsistat
== DATA_IN_ST
) {
4404 while ((!(RD_HARPOON(port
+ hp_xferstat
) & FIFO_EMPTY
)) &&
4405 (RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
)) {
4408 if (!(RD_HARPOON(port
+ hp_xferstat
) & FIFO_EMPTY
)) {
4409 currSCCB
->Sccb_ATC
+= currSCCB
->Sccb_XferCnt
;
4411 currSCCB
->Sccb_XferCnt
= 0;
4413 if ((RDW_HARPOON((port
+ hp_intstat
)) & PARITY
) &&
4414 (currSCCB
->HostStatus
== SCCB_COMPLETE
)) {
4415 currSCCB
->HostStatus
= SCCB_PARITY_ERR
;
4416 WRW_HARPOON((port
+ hp_intstat
), PARITY
);
4419 FPT_hostDataXferAbort(port
, p_card
, currSCCB
);
4421 FPT_dataXferProcessor(port
, &FPT_BL_Card
[p_card
]);
4423 while ((!(RD_HARPOON(port
+ hp_xferstat
) & FIFO_EMPTY
))
4424 && (RD_HARPOON(port
+ hp_ext_status
) &
4431 /*End Data In specific code. */
4432 GET_XFER_CNT(port
, xfercnt
);
4434 WR_HARPOON(port
+ hp_xfercnt_0
, 0x00);
4436 WR_HARPOON(port
+ hp_portctrl_0
, 0x00);
4438 currSCCB
->Sccb_ATC
+= (currSCCB
->Sccb_XferCnt
- xfercnt
);
4440 currSCCB
->Sccb_XferCnt
= xfercnt
;
4442 if ((RDW_HARPOON((port
+ hp_intstat
)) & PARITY
) &&
4443 (currSCCB
->HostStatus
== SCCB_COMPLETE
)) {
4445 currSCCB
->HostStatus
= SCCB_PARITY_ERR
;
4446 WRW_HARPOON((port
+ hp_intstat
), PARITY
);
4449 FPT_hostDataXferAbort(port
, p_card
, currSCCB
);
4451 WR_HARPOON(port
+ hp_fifowrite
, 0x00);
4452 WR_HARPOON(port
+ hp_fiforead
, 0x00);
4453 WR_HARPOON(port
+ hp_xferstat
, 0x00);
4455 WRW_HARPOON((port
+ hp_intstat
), XFER_CNT_0
);
4458 /*---------------------------------------------------------------------
4460 * Function: Phase Bus Free
4462 * Description: We just went bus free so figure out if it was
4463 * because of command complete or from a disconnect.
4465 *---------------------------------------------------------------------*/
4466 static void FPT_phaseBusFree(unsigned long port
, unsigned char p_card
)
4468 struct sccb
*currSCCB
;
4470 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4472 if (currSCCB
!= NULL
) {
4476 if (currSCCB
->OperationCode
== RESET_COMMAND
) {
4478 if ((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4479 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4480 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
4481 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4482 TarLUNBusy
[currSCCB
->Lun
] = 0;
4484 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4487 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
], currSCCB
,
4490 FPT_queueSearchSelect(&FPT_BL_Card
[p_card
], p_card
);
4494 else if (currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) {
4495 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
|=
4496 (unsigned char)SYNC_SUPPORTED
;
4497 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
&=
4501 else if (currSCCB
->Sccb_scsistat
== SELECT_WN_ST
) {
4502 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
=
4503 (FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4504 TarStatus
& ~WIDE_ENABLED
) | WIDE_NEGOCIATED
;
4506 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
&=
4510 else if (currSCCB
->Sccb_scsistat
== SELECT_Q_ST
) {
4511 /* Make sure this is not a phony BUS_FREE. If we were
4512 reselected or if BUSY is NOT on then this is a
4513 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4515 if ((!(RD_HARPOON(port
+ hp_scsisig
) & SCSI_BSY
)) ||
4516 (RDW_HARPOON((port
+ hp_intstat
)) & RSEL
)) {
4517 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4518 TarStatus
&= ~TAR_TAG_Q_MASK
;
4519 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4520 TarStatus
|= TAG_Q_REJECT
;
4530 currSCCB
->Sccb_scsistat
= BUS_FREE_ST
;
4532 if (!currSCCB
->HostStatus
) {
4533 currSCCB
->HostStatus
= SCCB_PHASE_SEQUENCE_FAIL
;
4536 if ((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4537 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4538 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
4539 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4540 TarLUNBusy
[currSCCB
->Lun
] = 0;
4542 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4545 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
], currSCCB
,
4550 FPT_BL_Card
[p_card
].globalFlags
|= F_NEW_SCCB_CMD
;
4552 } /*end if !=null */
4555 /*---------------------------------------------------------------------
4557 * Function: Auto Load Default Map
4559 * Description: Load the Automation RAM with the defualt map values.
4561 *---------------------------------------------------------------------*/
4562 static void FPT_autoLoadDefaultMap(unsigned long p_port
)
4564 unsigned long map_addr
;
4566 ARAM_ACCESS(p_port
);
4567 map_addr
= p_port
+ hp_aramBase
;
4569 WRW_HARPOON(map_addr
, (MPM_OP
+ AMSG_OUT
+ 0xC0)); /*ID MESSAGE */
4571 WRW_HARPOON(map_addr
, (MPM_OP
+ AMSG_OUT
+ 0x20)); /*SIMPLE TAG QUEUEING MSG */
4573 WRW_HARPOON(map_addr
, RAT_OP
); /*RESET ATTENTION */
4575 WRW_HARPOON(map_addr
, (MPM_OP
+ AMSG_OUT
+ 0x00)); /*TAG ID MSG */
4577 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 0 */
4579 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 1 */
4581 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 2 */
4583 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 3 */
4585 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 4 */
4587 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 5 */
4589 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 6 */
4591 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 7 */
4593 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 8 */
4595 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 9 */
4597 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 10 */
4599 WRW_HARPOON(map_addr
, (MPM_OP
+ ACOMMAND
+ 0x00)); /*CDB BYTE 11 */
4601 WRW_HARPOON(map_addr
, (CPE_OP
+ ADATA_OUT
+ DINT
)); /*JUMP IF DATA OUT */
4603 WRW_HARPOON(map_addr
, (TCB_OP
+ FIFO_0
+ DI
)); /*JUMP IF NO DATA IN FIFO */
4604 map_addr
+= 2; /*This means AYNC DATA IN */
4605 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_IDO_STRT
)); /*STOP AND INTERRUPT */
4607 WRW_HARPOON(map_addr
, (CPE_OP
+ ADATA_IN
+ DINT
)); /*JUMP IF NOT DATA IN PHZ */
4609 WRW_HARPOON(map_addr
, (CPN_OP
+ AMSG_IN
+ ST
)); /*IF NOT MSG IN CHECK 4 DATA IN */
4611 WRW_HARPOON(map_addr
, (CRD_OP
+ SDATA
+ 0x02)); /*SAVE DATA PTR MSG? */
4613 WRW_HARPOON(map_addr
, (BRH_OP
+ NOT_EQ
+ DC
)); /*GO CHECK FOR DISCONNECT MSG */
4615 WRW_HARPOON(map_addr
, (MRR_OP
+ SDATA
+ D_AR1
)); /*SAVE DATA PTRS MSG */
4617 WRW_HARPOON(map_addr
, (CPN_OP
+ AMSG_IN
+ ST
)); /*IF NOT MSG IN CHECK DATA IN */
4619 WRW_HARPOON(map_addr
, (CRD_OP
+ SDATA
+ 0x04)); /*DISCONNECT MSG? */
4621 WRW_HARPOON(map_addr
, (BRH_OP
+ NOT_EQ
+ UNKNWN
)); /*UKNKNOWN MSG */
4623 WRW_HARPOON(map_addr
, (MRR_OP
+ SDATA
+ D_BUCKET
)); /*XFER DISCONNECT MSG */
4625 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_ITAR_DISC
)); /*STOP AND INTERRUPT */
4627 WRW_HARPOON(map_addr
, (CPN_OP
+ ASTATUS
+ UNKNWN
)); /*JUMP IF NOT STATUS PHZ. */
4629 WRW_HARPOON(map_addr
, (MRR_OP
+ SDATA
+ D_AR0
)); /*GET STATUS BYTE */
4631 WRW_HARPOON(map_addr
, (CPN_OP
+ AMSG_IN
+ CC
)); /*ERROR IF NOT MSG IN PHZ */
4633 WRW_HARPOON(map_addr
, (CRD_OP
+ SDATA
+ 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4635 WRW_HARPOON(map_addr
, (BRH_OP
+ NOT_EQ
+ CC
)); /*ERROR IF NOT CMD COMPLETE MSG. */
4637 WRW_HARPOON(map_addr
, (MRR_OP
+ SDATA
+ D_BUCKET
)); /*GET CMD COMPLETE MSG */
4639 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_ICMD_COMP
)); /*END OF COMMAND */
4642 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_IUNKWN
)); /*RECEIVED UNKNOWN MSG BYTE */
4644 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_INO_CC
)); /*NO COMMAND COMPLETE AFTER STATUS */
4646 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_ITICKLE
)); /*BIOS Tickled the Mgr */
4648 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_IRFAIL
)); /*EXPECTED ID/TAG MESSAGES AND */
4649 map_addr
+= 2; /* DIDN'T GET ONE */
4650 WRW_HARPOON(map_addr
, (CRR_OP
+ AR3
+ S_IDREG
)); /* comp SCSI SEL ID & AR3 */
4652 WRW_HARPOON(map_addr
, (BRH_OP
+ EQUAL
+ 0x00)); /*SEL ID OK then Conti. */
4654 WRW_HARPOON(map_addr
, (SSI_OP
+ SSI_INO_CC
)); /*NO COMMAND COMPLETE AFTER STATUS */
4656 SGRAM_ACCESS(p_port
);
4659 /*---------------------------------------------------------------------
4661 * Function: Auto Command Complete
4663 * Description: Post command back to host and find another command
4666 *---------------------------------------------------------------------*/
4668 static void FPT_autoCmdCmplt(unsigned long p_port
, unsigned char p_card
)
4670 struct sccb
*currSCCB
;
4671 unsigned char status_byte
;
4673 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
4675 status_byte
= RD_HARPOON(p_port
+ hp_gp_reg_0
);
4677 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUN_CA
= 0;
4679 if (status_byte
!= SSGOOD
) {
4681 if (status_byte
== SSQ_FULL
) {
4683 if (((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4684 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4685 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))) {
4686 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4687 TarLUNBusy
[currSCCB
->Lun
] = 1;
4688 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4689 FPT_BL_Card
[p_card
].discQCount
--;
4690 FPT_BL_Card
[p_card
].
4691 discQ_Tbl
[FPT_sccbMgrTbl
[p_card
]
4693 LunDiscQ_Idx
[currSCCB
->Lun
]] =
4696 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4698 if (currSCCB
->Sccb_tag
) {
4699 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4700 FPT_BL_Card
[p_card
].
4702 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->
4706 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4707 FPT_BL_Card
[p_card
].
4709 FPT_BL_Card
[p_card
].
4710 discQ_Tbl
[FPT_sccbMgrTbl
[p_card
]
4712 LunDiscQ_Idx
[0]] = NULL
;
4716 currSCCB
->Sccb_MGRFlags
|= F_STATUSLOADED
;
4718 FPT_queueSelectFail(&FPT_BL_Card
[p_card
], p_card
);
4723 if (currSCCB
->Sccb_scsistat
== SELECT_SN_ST
) {
4724 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
|=
4725 (unsigned char)SYNC_SUPPORTED
;
4727 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
&=
4729 FPT_BL_Card
[p_card
].globalFlags
|= F_NEW_SCCB_CMD
;
4731 if (((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4732 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4733 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))) {
4734 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4735 TarLUNBusy
[currSCCB
->Lun
] = 1;
4736 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4737 FPT_BL_Card
[p_card
].discQCount
--;
4738 FPT_BL_Card
[p_card
].
4739 discQ_Tbl
[FPT_sccbMgrTbl
[p_card
]
4741 LunDiscQ_Idx
[currSCCB
->Lun
]] =
4744 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4746 if (currSCCB
->Sccb_tag
) {
4747 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4748 FPT_BL_Card
[p_card
].
4750 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->
4754 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4755 FPT_BL_Card
[p_card
].
4757 FPT_BL_Card
[p_card
].
4758 discQ_Tbl
[FPT_sccbMgrTbl
[p_card
]
4760 LunDiscQ_Idx
[0]] = NULL
;
4767 if (currSCCB
->Sccb_scsistat
== SELECT_WN_ST
) {
4769 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarStatus
=
4770 (FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4771 TarStatus
& ~WIDE_ENABLED
) | WIDE_NEGOCIATED
;
4773 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarEEValue
&=
4775 FPT_BL_Card
[p_card
].globalFlags
|= F_NEW_SCCB_CMD
;
4777 if (((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4778 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4779 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))) {
4780 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4781 TarLUNBusy
[currSCCB
->Lun
] = 1;
4782 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4783 FPT_BL_Card
[p_card
].discQCount
--;
4784 FPT_BL_Card
[p_card
].
4785 discQ_Tbl
[FPT_sccbMgrTbl
[p_card
]
4787 LunDiscQ_Idx
[currSCCB
->Lun
]] =
4790 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4792 if (currSCCB
->Sccb_tag
) {
4793 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4794 FPT_BL_Card
[p_card
].
4796 FPT_BL_Card
[p_card
].discQ_Tbl
[currSCCB
->
4800 if (FPT_BL_Card
[p_card
].discQCount
!= 0)
4801 FPT_BL_Card
[p_card
].
4803 FPT_BL_Card
[p_card
].
4804 discQ_Tbl
[FPT_sccbMgrTbl
[p_card
]
4806 LunDiscQ_Idx
[0]] = NULL
;
4813 if (status_byte
== SSCHECK
) {
4814 if (FPT_BL_Card
[p_card
].globalFlags
& F_DO_RENEGO
) {
4815 if (FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4816 TarEEValue
& EE_SYNC_MASK
) {
4817 FPT_sccbMgrTbl
[p_card
][currSCCB
->
4819 TarStatus
&= ~TAR_SYNC_MASK
;
4821 if (FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4822 TarEEValue
& EE_WIDE_SCSI
) {
4823 FPT_sccbMgrTbl
[p_card
][currSCCB
->
4825 TarStatus
&= ~TAR_WIDE_MASK
;
4830 if (!(currSCCB
->Sccb_XferState
& F_AUTO_SENSE
)) {
4832 currSCCB
->SccbStatus
= SCCB_ERROR
;
4833 currSCCB
->TargetStatus
= status_byte
;
4835 if (status_byte
== SSCHECK
) {
4837 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4840 if (currSCCB
->RequestSenseLength
!=
4841 NO_AUTO_REQUEST_SENSE
) {
4843 if (currSCCB
->RequestSenseLength
== 0)
4844 currSCCB
->RequestSenseLength
=
4847 FPT_ssenss(&FPT_BL_Card
[p_card
]);
4848 FPT_BL_Card
[p_card
].globalFlags
|=
4851 if (((FPT_BL_Card
[p_card
].
4852 globalFlags
& F_CONLUN_IO
)
4854 ((FPT_sccbMgrTbl
[p_card
]
4856 TarStatus
& TAR_TAG_Q_MASK
) !=
4858 FPT_sccbMgrTbl
[p_card
]
4860 TarLUNBusy
[currSCCB
->Lun
] =
4862 if (FPT_BL_Card
[p_card
].
4864 FPT_BL_Card
[p_card
].
4866 FPT_BL_Card
[p_card
].
4867 discQ_Tbl
[FPT_sccbMgrTbl
4875 FPT_sccbMgrTbl
[p_card
]
4878 if (currSCCB
->Sccb_tag
) {
4879 if (FPT_BL_Card
[p_card
].
4884 FPT_BL_Card
[p_card
].
4885 discQ_Tbl
[currSCCB
->
4889 if (FPT_BL_Card
[p_card
].
4894 FPT_BL_Card
[p_card
].
4909 if ((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
4910 ((FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].
4911 TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))
4912 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[currSCCB
->
4915 FPT_sccbMgrTbl
[p_card
][currSCCB
->TargID
].TarLUNBusy
[0] = 0;
4917 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
], currSCCB
, p_card
);
4920 #define SHORT_WAIT 0x0000000F
4921 #define LONG_WAIT 0x0000FFFFL
4923 /*---------------------------------------------------------------------
4925 * Function: Data Transfer Processor
4927 * Description: This routine performs two tasks.
4928 * (1) Start data transfer by calling HOST_DATA_XFER_START
4929 * function. Once data transfer is started, (2) Depends
4930 * on the type of data transfer mode Scatter/Gather mode
4931 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
4932 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
4933 * data transfer done. In Scatter/Gather mode, this routine
4934 * checks bus master command complete and dual rank busy
4935 * bit to keep chaining SC transfer command. Similarly,
4936 * in Scatter/Gather mode, it checks Sccb_MGRFlag
4937 * (F_HOST_XFER_ACT bit) for data transfer done.
4939 *---------------------------------------------------------------------*/
4941 static void FPT_dataXferProcessor(unsigned long port
,
4942 struct sccb_card
*pCurrCard
)
4944 struct sccb
*currSCCB
;
4946 currSCCB
= pCurrCard
->currentSCCB
;
4948 if (currSCCB
->Sccb_XferState
& F_SG_XFER
) {
4949 if (pCurrCard
->globalFlags
& F_HOST_XFER_ACT
)
4951 currSCCB
->Sccb_sgseg
+= (unsigned char)SG_BUF_CNT
;
4952 currSCCB
->Sccb_SGoffset
= 0x00;
4954 pCurrCard
->globalFlags
|= F_HOST_XFER_ACT
;
4956 FPT_busMstrSGDataXferStart(port
, currSCCB
);
4960 if (!(pCurrCard
->globalFlags
& F_HOST_XFER_ACT
)) {
4961 pCurrCard
->globalFlags
|= F_HOST_XFER_ACT
;
4963 FPT_busMstrDataXferStart(port
, currSCCB
);
4968 /*---------------------------------------------------------------------
4970 * Function: BusMaster Scatter Gather Data Transfer Start
4974 *---------------------------------------------------------------------*/
4975 static void FPT_busMstrSGDataXferStart(unsigned long p_port
,
4976 struct sccb
*pcurrSCCB
)
4978 unsigned long count
, addr
, tmpSGCnt
;
4979 unsigned int sg_index
;
4980 unsigned char sg_count
, i
;
4981 unsigned long reg_offset
;
4983 if (pcurrSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
) {
4985 count
= ((unsigned long)HOST_RD_CMD
) << 24;
4989 count
= ((unsigned long)HOST_WRT_CMD
) << 24;
4994 sg_index
= pcurrSCCB
->Sccb_sgseg
;
4995 reg_offset
= hp_aramBase
;
4997 i
= (unsigned char)(RD_HARPOON(p_port
+ hp_page_ctrl
) &
4998 ~(SGRAM_ARAM
| SCATTER_EN
));
5000 WR_HARPOON(p_port
+ hp_page_ctrl
, i
);
5002 while ((sg_count
< (unsigned char)SG_BUF_CNT
) &&
5003 ((unsigned long)(sg_index
* (unsigned int)SG_ELEMENT_SIZE
) <
5004 pcurrSCCB
->DataLength
)) {
5006 tmpSGCnt
+= *(((unsigned long *)pcurrSCCB
->DataPointer
) +
5009 count
|= *(((unsigned long *)pcurrSCCB
->DataPointer
) +
5012 addr
= *(((unsigned long *)pcurrSCCB
->DataPointer
) +
5013 ((sg_index
* 2) + 1));
5015 if ((!sg_count
) && (pcurrSCCB
->Sccb_SGoffset
)) {
5018 ((count
& 0x00FFFFFFL
) - pcurrSCCB
->Sccb_SGoffset
);
5020 (count
& 0xFF000000L
) | pcurrSCCB
->Sccb_SGoffset
;
5022 tmpSGCnt
= count
& 0x00FFFFFFL
;
5025 WR_HARP32(p_port
, reg_offset
, addr
);
5028 WR_HARP32(p_port
, reg_offset
, count
);
5031 count
&= 0xFF000000L
;
5037 pcurrSCCB
->Sccb_XferCnt
= tmpSGCnt
;
5039 WR_HARPOON(p_port
+ hp_sg_addr
, (sg_count
<< 4));
5041 if (pcurrSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
) {
5043 WR_HARP32(p_port
, hp_xfercnt_0
, tmpSGCnt
);
5045 WR_HARPOON(p_port
+ hp_portctrl_0
,
5046 (DMA_PORT
| SCSI_PORT
| SCSI_INBIT
));
5047 WR_HARPOON(p_port
+ hp_scsisig
, S_DATAI_PH
);
5052 if ((!(RD_HARPOON(p_port
+ hp_synctarg_0
) & NARROW_SCSI
)) &&
5053 (tmpSGCnt
& 0x000000001)) {
5055 pcurrSCCB
->Sccb_XferState
|= F_ODD_BALL_CNT
;
5059 WR_HARP32(p_port
, hp_xfercnt_0
, tmpSGCnt
);
5061 WR_HARPOON(p_port
+ hp_portctrl_0
,
5062 (SCSI_PORT
| DMA_PORT
| DMA_RD
));
5063 WR_HARPOON(p_port
+ hp_scsisig
, S_DATAO_PH
);
5066 WR_HARPOON(p_port
+ hp_page_ctrl
, (unsigned char)(i
| SCATTER_EN
));
5070 /*---------------------------------------------------------------------
5072 * Function: BusMaster Data Transfer Start
5076 *---------------------------------------------------------------------*/
5077 static void FPT_busMstrDataXferStart(unsigned long p_port
,
5078 struct sccb
*pcurrSCCB
)
5080 unsigned long addr
, count
;
5082 if (!(pcurrSCCB
->Sccb_XferState
& F_AUTO_SENSE
)) {
5084 count
= pcurrSCCB
->Sccb_XferCnt
;
5087 (unsigned long)pcurrSCCB
->DataPointer
+ pcurrSCCB
->Sccb_ATC
;
5091 addr
= pcurrSCCB
->SensePointer
;
5092 count
= pcurrSCCB
->RequestSenseLength
;
5096 HP_SETUP_ADDR_CNT(p_port
, addr
, count
);
5098 if (pcurrSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
) {
5100 WR_HARPOON(p_port
+ hp_portctrl_0
,
5101 (DMA_PORT
| SCSI_PORT
| SCSI_INBIT
));
5102 WR_HARPOON(p_port
+ hp_scsisig
, S_DATAI_PH
);
5104 WR_HARPOON(p_port
+ hp_xfer_cmd
,
5105 (XFER_DMA_HOST
| XFER_HOST_AUTO
| XFER_DMA_8BIT
));
5110 WR_HARPOON(p_port
+ hp_portctrl_0
,
5111 (SCSI_PORT
| DMA_PORT
| DMA_RD
));
5112 WR_HARPOON(p_port
+ hp_scsisig
, S_DATAO_PH
);
5114 WR_HARPOON(p_port
+ hp_xfer_cmd
,
5115 (XFER_HOST_DMA
| XFER_HOST_AUTO
| XFER_DMA_8BIT
));
5120 /*---------------------------------------------------------------------
5122 * Function: BusMaster Timeout Handler
5124 * Description: This function is called after a bus master command busy time
5125 * out is detected. This routines issue halt state machine
5126 * with a software time out for command busy. If command busy
5127 * is still asserted at the end of the time out, it issues
5128 * hard abort with another software time out. It hard abort
5129 * command busy is also time out, it'll just give up.
5131 *---------------------------------------------------------------------*/
5132 static unsigned char FPT_busMstrTimeOut(unsigned long p_port
)
5134 unsigned long timeout
;
5136 timeout
= LONG_WAIT
;
5138 WR_HARPOON(p_port
+ hp_sys_ctrl
, HALT_MACH
);
5140 while ((!(RD_HARPOON(p_port
+ hp_ext_status
) & CMD_ABORTED
))
5144 if (RD_HARPOON(p_port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5145 WR_HARPOON(p_port
+ hp_sys_ctrl
, HARD_ABORT
);
5147 timeout
= LONG_WAIT
;
5148 while ((RD_HARPOON(p_port
+ hp_ext_status
) & BM_CMD_BUSY
)
5153 RD_HARPOON(p_port
+ hp_int_status
); /*Clear command complete */
5155 if (RD_HARPOON(p_port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5164 /*---------------------------------------------------------------------
5166 * Function: Host Data Transfer Abort
5168 * Description: Abort any in progress transfer.
5170 *---------------------------------------------------------------------*/
5171 static void FPT_hostDataXferAbort(unsigned long port
, unsigned char p_card
,
5172 struct sccb
*pCurrSCCB
)
5175 unsigned long timeout
;
5176 unsigned long remain_cnt
;
5177 unsigned int sg_ptr
;
5179 FPT_BL_Card
[p_card
].globalFlags
&= ~F_HOST_XFER_ACT
;
5181 if (pCurrSCCB
->Sccb_XferState
& F_AUTO_SENSE
) {
5183 if (!(RD_HARPOON(port
+ hp_int_status
) & INT_CMD_COMPL
)) {
5185 WR_HARPOON(port
+ hp_bm_ctrl
,
5186 (RD_HARPOON(port
+ hp_bm_ctrl
) |
5188 timeout
= LONG_WAIT
;
5190 while ((RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
)
5194 WR_HARPOON(port
+ hp_bm_ctrl
,
5195 (RD_HARPOON(port
+ hp_bm_ctrl
) &
5198 if (RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5200 if (FPT_busMstrTimeOut(port
)) {
5202 if (pCurrSCCB
->HostStatus
== 0x00)
5204 pCurrSCCB
->HostStatus
=
5209 if (RD_HARPOON(port
+ hp_int_status
) &
5212 if (RD_HARPOON(port
+ hp_ext_status
) &
5215 if (pCurrSCCB
->HostStatus
==
5218 pCurrSCCB
->HostStatus
=
5225 else if (pCurrSCCB
->Sccb_XferCnt
) {
5227 if (pCurrSCCB
->Sccb_XferState
& F_SG_XFER
) {
5229 WR_HARPOON(port
+ hp_page_ctrl
,
5230 (RD_HARPOON(port
+ hp_page_ctrl
) &
5233 WR_HARPOON(port
+ hp_sg_addr
, 0x00);
5235 sg_ptr
= pCurrSCCB
->Sccb_sgseg
+ SG_BUF_CNT
;
5238 (unsigned int)(pCurrSCCB
->DataLength
/
5242 (unsigned int)(pCurrSCCB
->DataLength
/
5246 remain_cnt
= pCurrSCCB
->Sccb_XferCnt
;
5248 while (remain_cnt
< 0x01000000L
) {
5254 long)(*(((unsigned long *)pCurrSCCB
->
5255 DataPointer
) + (sg_ptr
* 2)))) {
5259 long)(*(((unsigned long *)
5260 pCurrSCCB
->DataPointer
) +
5270 if (remain_cnt
< 0x01000000L
) {
5272 pCurrSCCB
->Sccb_SGoffset
= remain_cnt
;
5274 pCurrSCCB
->Sccb_sgseg
= (unsigned short)sg_ptr
;
5276 if ((unsigned long)(sg_ptr
* SG_ELEMENT_SIZE
) ==
5277 pCurrSCCB
->DataLength
&& (remain_cnt
== 0))
5279 pCurrSCCB
->Sccb_XferState
|=
5285 if (pCurrSCCB
->HostStatus
== 0x00) {
5287 pCurrSCCB
->HostStatus
=
5293 if (!(pCurrSCCB
->Sccb_XferState
& F_HOST_XFER_DIR
)) {
5295 if (RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5297 FPT_busMstrTimeOut(port
);
5302 if (RD_HARPOON(port
+ hp_int_status
) &
5305 if (RD_HARPOON(port
+ hp_ext_status
) &
5308 if (pCurrSCCB
->HostStatus
==
5311 pCurrSCCB
->HostStatus
=
5322 if ((RD_HARPOON(port
+ hp_fifo_cnt
)) >= BM_THRESHOLD
) {
5324 timeout
= SHORT_WAIT
;
5326 while ((RD_HARPOON(port
+ hp_ext_status
) &
5328 && ((RD_HARPOON(port
+ hp_fifo_cnt
)) >=
5329 BM_THRESHOLD
) && timeout
--) {
5333 if (RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5335 WR_HARPOON(port
+ hp_bm_ctrl
,
5336 (RD_HARPOON(port
+ hp_bm_ctrl
) |
5339 timeout
= LONG_WAIT
;
5341 while ((RD_HARPOON(port
+ hp_ext_status
) &
5342 BM_CMD_BUSY
) && timeout
--) {
5345 WR_HARPOON(port
+ hp_bm_ctrl
,
5346 (RD_HARPOON(port
+ hp_bm_ctrl
) &
5349 if (RD_HARPOON(port
+ hp_ext_status
) &
5352 if (pCurrSCCB
->HostStatus
== 0x00) {
5354 pCurrSCCB
->HostStatus
=
5358 FPT_busMstrTimeOut(port
);
5362 if (RD_HARPOON(port
+ hp_int_status
) & INT_EXT_STATUS
) {
5364 if (RD_HARPOON(port
+ hp_ext_status
) &
5367 if (pCurrSCCB
->HostStatus
== 0x00) {
5369 pCurrSCCB
->HostStatus
=
5380 if (RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5382 timeout
= LONG_WAIT
;
5384 while ((RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
)
5388 if (RD_HARPOON(port
+ hp_ext_status
) & BM_CMD_BUSY
) {
5390 if (pCurrSCCB
->HostStatus
== 0x00) {
5392 pCurrSCCB
->HostStatus
= SCCB_BM_ERR
;
5395 FPT_busMstrTimeOut(port
);
5399 if (RD_HARPOON(port
+ hp_int_status
) & INT_EXT_STATUS
) {
5401 if (RD_HARPOON(port
+ hp_ext_status
) & BAD_EXT_STATUS
) {
5403 if (pCurrSCCB
->HostStatus
== 0x00) {
5405 pCurrSCCB
->HostStatus
= SCCB_BM_ERR
;
5411 if (pCurrSCCB
->Sccb_XferState
& F_SG_XFER
) {
5413 WR_HARPOON(port
+ hp_page_ctrl
,
5414 (RD_HARPOON(port
+ hp_page_ctrl
) &
5417 WR_HARPOON(port
+ hp_sg_addr
, 0x00);
5419 pCurrSCCB
->Sccb_sgseg
+= SG_BUF_CNT
;
5421 pCurrSCCB
->Sccb_SGoffset
= 0x00;
5423 if ((unsigned long)(pCurrSCCB
->Sccb_sgseg
*
5425 pCurrSCCB
->DataLength
) {
5427 pCurrSCCB
->Sccb_XferState
|= F_ALL_XFERRED
;
5429 pCurrSCCB
->Sccb_sgseg
=
5430 (unsigned short)(pCurrSCCB
->DataLength
/
5438 if (!(pCurrSCCB
->Sccb_XferState
& F_AUTO_SENSE
))
5440 pCurrSCCB
->Sccb_XferState
|= F_ALL_XFERRED
;
5444 WR_HARPOON(port
+ hp_int_mask
, (INT_CMD_COMPL
| SCSI_INTERRUPT
));
5447 /*---------------------------------------------------------------------
5449 * Function: Host Data Transfer Restart
5451 * Description: Reset the available count due to a restore data
5454 *---------------------------------------------------------------------*/
5455 static void FPT_hostDataXferRestart(struct sccb
*currSCCB
)
5457 unsigned long data_count
;
5458 unsigned int sg_index
;
5459 unsigned long *sg_ptr
;
5461 if (currSCCB
->Sccb_XferState
& F_SG_XFER
) {
5463 currSCCB
->Sccb_XferCnt
= 0;
5465 sg_index
= 0xffff; /*Index by long words into sg list. */
5466 data_count
= 0; /*Running count of SG xfer counts. */
5468 sg_ptr
= (unsigned long *)currSCCB
->DataPointer
;
5470 while (data_count
< currSCCB
->Sccb_ATC
) {
5473 data_count
+= *(sg_ptr
+ (sg_index
* 2));
5476 if (data_count
== currSCCB
->Sccb_ATC
) {
5478 currSCCB
->Sccb_SGoffset
= 0;
5483 currSCCB
->Sccb_SGoffset
=
5484 data_count
- currSCCB
->Sccb_ATC
;
5487 currSCCB
->Sccb_sgseg
= (unsigned short)sg_index
;
5491 currSCCB
->Sccb_XferCnt
=
5492 currSCCB
->DataLength
- currSCCB
->Sccb_ATC
;
5496 /*---------------------------------------------------------------------
5498 * Function: FPT_scini
5500 * Description: Setup all data structures necessary for SCAM selection.
5502 *---------------------------------------------------------------------*/
5504 static void FPT_scini(unsigned char p_card
, unsigned char p_our_id
,
5505 unsigned char p_power_up
)
5508 unsigned char loser
, assigned_id
;
5509 unsigned long p_port
;
5511 unsigned char i
, k
, ScamFlg
;
5512 struct sccb_card
*currCard
;
5513 struct nvram_info
*pCurrNvRam
;
5515 currCard
= &FPT_BL_Card
[p_card
];
5516 p_port
= currCard
->ioPort
;
5517 pCurrNvRam
= currCard
->pNvRamInfo
;
5520 ScamFlg
= pCurrNvRam
->niScamConf
;
5521 i
= pCurrNvRam
->niSysConf
;
5524 (unsigned char)FPT_utilEERead(p_port
, SCAM_CONFIG
/ 2);
5526 char)(FPT_utilEERead(p_port
, (SYSTEM_CONFIG
/ 2)));
5528 if (!(i
& 0x02)) /* check if reset bus in AutoSCSI parameter set */
5531 FPT_inisci(p_card
, p_port
, p_our_id
);
5533 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5534 too slow to return to SCAM selection */
5537 FPT_Wait1Second(p_port);
5539 FPT_Wait(p_port, TO_250ms); */
5541 FPT_Wait1Second(p_port
);
5543 if ((ScamFlg
& SCAM_ENABLED
) && (ScamFlg
& SCAM_LEVEL2
)) {
5544 while (!(FPT_scarb(p_port
, INIT_SELTD
))) {
5550 FPT_scxferc(p_port
, SYNC_PTRN
);
5551 FPT_scxferc(p_port
, DOM_MSTR
);
5554 &FPT_scamInfo
[p_our_id
].id_string
[0]);
5555 } while (loser
== 0xFF);
5559 if ((p_power_up
) && (!loser
)) {
5560 FPT_sresb(p_port
, p_card
);
5561 FPT_Wait(p_port
, TO_250ms
);
5563 while (!(FPT_scarb(p_port
, INIT_SELTD
))) {
5569 FPT_scxferc(p_port
, SYNC_PTRN
);
5570 FPT_scxferc(p_port
, DOM_MSTR
);
5573 &FPT_scamInfo
[p_our_id
].
5575 } while (loser
== 0xFF);
5587 FPT_scamInfo
[p_our_id
].state
= ID_ASSIGNED
;
5589 if (ScamFlg
& SCAM_ENABLED
) {
5591 for (i
= 0; i
< MAX_SCSI_TAR
; i
++) {
5592 if ((FPT_scamInfo
[i
].state
== ID_UNASSIGNED
) ||
5593 (FPT_scamInfo
[i
].state
== ID_UNUSED
)) {
5594 if (FPT_scsell(p_port
, i
)) {
5595 FPT_scamInfo
[i
].state
= LEGACY
;
5596 if ((FPT_scamInfo
[i
].
5597 id_string
[0] != 0xFF)
5598 || (FPT_scamInfo
[i
].
5599 id_string
[1] != 0xFA)) {
5602 id_string
[0] = 0xFF;
5604 id_string
[1] = 0xFA;
5605 if (pCurrNvRam
== NULL
)
5615 FPT_sresb(p_port
, p_card
);
5616 FPT_Wait1Second(p_port
);
5617 while (!(FPT_scarb(p_port
, INIT_SELTD
))) {
5620 FPT_scasid(p_card
, p_port
);
5625 else if ((loser
) && (ScamFlg
& SCAM_ENABLED
)) {
5626 FPT_scamInfo
[p_our_id
].id_string
[0] = SLV_TYPE_CODE0
;
5628 FPT_scwtsel(p_port
);
5631 while (FPT_scxferc(p_port
, 0x00) != SYNC_PTRN
) {
5634 i
= FPT_scxferc(p_port
, 0x00);
5635 if (i
== ASSIGN_ID
) {
5639 &FPT_scamInfo
[p_our_id
].id_string
[0]))) {
5640 i
= FPT_scxferc(p_port
, 0x00);
5641 if (FPT_scvalq(i
)) {
5642 k
= FPT_scxferc(p_port
, 0x00);
5644 if (FPT_scvalq(k
)) {
5657 FPT_scamInfo
[currCard
->
5659 state
= ID_ASSIGNED
;
5660 FPT_scamInfo
[currCard
->
5670 else if (i
== SET_P_FLAG
) {
5671 if (!(FPT_scsendi(p_port
,
5672 &FPT_scamInfo
[p_our_id
].
5674 FPT_scamInfo
[p_our_id
].id_string
[0] |=
5677 } while (!assigned_id
);
5679 while (FPT_scxferc(p_port
, 0x00) != CFG_CMPLT
) {
5683 if (ScamFlg
& SCAM_ENABLED
) {
5685 if (currCard
->globalFlags
& F_UPDATE_EEPROM
) {
5686 FPT_scsavdi(p_card
, p_port
);
5687 currCard
->globalFlags
&= ~F_UPDATE_EEPROM
;
5692 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5694 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5695 (FPT_scamInfo[i].state == LEGACY))
5700 currCard->globalFlags |= F_SINGLE_DEVICE;
5702 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5706 /*---------------------------------------------------------------------
5708 * Function: FPT_scarb
5710 * Description: Gain control of the bus and wait SCAM select time (250ms)
5712 *---------------------------------------------------------------------*/
5714 static int FPT_scarb(unsigned long p_port
, unsigned char p_sel_type
)
5716 if (p_sel_type
== INIT_SELTD
) {
5718 while (RD_HARPOON(p_port
+ hp_scsisig
) & (SCSI_SEL
| SCSI_BSY
)) {
5721 if (RD_HARPOON(p_port
+ hp_scsisig
) & SCSI_SEL
)
5724 if (RD_HARPOON(p_port
+ hp_scsidata_0
) != 00)
5727 WR_HARPOON(p_port
+ hp_scsisig
,
5728 (RD_HARPOON(p_port
+ hp_scsisig
) | SCSI_BSY
));
5730 if (RD_HARPOON(p_port
+ hp_scsisig
) & SCSI_SEL
) {
5732 WR_HARPOON(p_port
+ hp_scsisig
,
5733 (RD_HARPOON(p_port
+ hp_scsisig
) &
5738 WR_HARPOON(p_port
+ hp_scsisig
,
5739 (RD_HARPOON(p_port
+ hp_scsisig
) | SCSI_SEL
));
5741 if (RD_HARPOON(p_port
+ hp_scsidata_0
) != 00) {
5743 WR_HARPOON(p_port
+ hp_scsisig
,
5744 (RD_HARPOON(p_port
+ hp_scsisig
) &
5745 ~(SCSI_BSY
| SCSI_SEL
)));
5750 WR_HARPOON(p_port
+ hp_clkctrl_0
, (RD_HARPOON(p_port
+ hp_clkctrl_0
)
5752 WR_HARPOON(p_port
+ hp_scsireset
, SCAM_EN
);
5753 WR_HARPOON(p_port
+ hp_scsidata_0
, 0x00);
5754 WR_HARPOON(p_port
+ hp_scsidata_1
, 0x00);
5755 WR_HARPOON(p_port
+ hp_portctrl_0
, SCSI_BUS_EN
);
5757 WR_HARPOON(p_port
+ hp_scsisig
,
5758 (RD_HARPOON(p_port
+ hp_scsisig
) | SCSI_MSG
));
5760 WR_HARPOON(p_port
+ hp_scsisig
, (RD_HARPOON(p_port
+ hp_scsisig
)
5763 FPT_Wait(p_port
, TO_250ms
);
5768 /*---------------------------------------------------------------------
5770 * Function: FPT_scbusf
5772 * Description: Release the SCSI bus and disable SCAM selection.
5774 *---------------------------------------------------------------------*/
5776 static void FPT_scbusf(unsigned long p_port
)
5778 WR_HARPOON(p_port
+ hp_page_ctrl
,
5779 (RD_HARPOON(p_port
+ hp_page_ctrl
) | G_INT_DISABLE
));
5781 WR_HARPOON(p_port
+ hp_scsidata_0
, 0x00);
5783 WR_HARPOON(p_port
+ hp_portctrl_0
, (RD_HARPOON(p_port
+ hp_portctrl_0
)
5786 WR_HARPOON(p_port
+ hp_scsisig
, 0x00);
5788 WR_HARPOON(p_port
+ hp_scsireset
, (RD_HARPOON(p_port
+ hp_scsireset
)
5791 WR_HARPOON(p_port
+ hp_clkctrl_0
, (RD_HARPOON(p_port
+ hp_clkctrl_0
)
5794 WRW_HARPOON((p_port
+ hp_intstat
), (BUS_FREE
| AUTO_INT
| SCAM_SEL
));
5796 WR_HARPOON(p_port
+ hp_page_ctrl
,
5797 (RD_HARPOON(p_port
+ hp_page_ctrl
) & ~G_INT_DISABLE
));
5800 /*---------------------------------------------------------------------
5802 * Function: FPT_scasid
5804 * Description: Assign an ID to all the SCAM devices.
5806 *---------------------------------------------------------------------*/
5808 static void FPT_scasid(unsigned char p_card
, unsigned long p_port
)
5810 unsigned char temp_id_string
[ID_STRING_LENGTH
];
5812 unsigned char i
, k
, scam_id
;
5813 unsigned char crcBytes
[3];
5814 struct nvram_info
*pCurrNvRam
;
5815 unsigned short *pCrcBytes
;
5817 pCurrNvRam
= FPT_BL_Card
[p_card
].pNvRamInfo
;
5823 for (k
= 0; k
< ID_STRING_LENGTH
; k
++) {
5824 temp_id_string
[k
] = (unsigned char)0x00;
5827 FPT_scxferc(p_port
, SYNC_PTRN
);
5828 FPT_scxferc(p_port
, ASSIGN_ID
);
5830 if (!(FPT_sciso(p_port
, &temp_id_string
[0]))) {
5832 pCrcBytes
= (unsigned short *)&crcBytes
[0];
5833 *pCrcBytes
= FPT_CalcCrc16(&temp_id_string
[0]);
5834 crcBytes
[2] = FPT_CalcLrc(&temp_id_string
[0]);
5835 temp_id_string
[1] = crcBytes
[2];
5836 temp_id_string
[2] = crcBytes
[0];
5837 temp_id_string
[3] = crcBytes
[1];
5838 for (k
= 4; k
< ID_STRING_LENGTH
; k
++)
5839 temp_id_string
[k
] = (unsigned char)0x00;
5841 i
= FPT_scmachid(p_card
, temp_id_string
);
5843 if (i
== CLR_PRIORITY
) {
5844 FPT_scxferc(p_port
, MISC_CODE
);
5845 FPT_scxferc(p_port
, CLR_P_FLAG
);
5846 i
= 0; /*Not the last ID yet. */
5849 else if (i
!= NO_ID_AVAIL
) {
5851 FPT_scxferc(p_port
, ID_0_7
);
5853 FPT_scxferc(p_port
, ID_8_F
);
5855 scam_id
= (i
& (unsigned char)0x07);
5857 for (k
= 1; k
< 0x08; k
<<= 1)
5859 scam_id
+= 0x08; /*Count number of zeros in DB0-3. */
5861 FPT_scxferc(p_port
, scam_id
);
5863 i
= 0; /*Not the last ID yet. */
5873 FPT_scxferc(p_port
, SYNC_PTRN
);
5874 FPT_scxferc(p_port
, CFG_CMPLT
);
5877 /*---------------------------------------------------------------------
5879 * Function: FPT_scsel
5881 * Description: Select all the SCAM devices.
5883 *---------------------------------------------------------------------*/
5885 static void FPT_scsel(unsigned long p_port
)
5888 WR_HARPOON(p_port
+ hp_scsisig
, SCSI_SEL
);
5889 FPT_scwiros(p_port
, SCSI_MSG
);
5891 WR_HARPOON(p_port
+ hp_scsisig
, (SCSI_SEL
| SCSI_BSY
));
5893 WR_HARPOON(p_port
+ hp_scsisig
,
5894 (SCSI_SEL
| SCSI_BSY
| SCSI_IOBIT
| SCSI_CD
));
5895 WR_HARPOON(p_port
+ hp_scsidata_0
,
5896 (unsigned char)(RD_HARPOON(p_port
+ hp_scsidata_0
) |
5897 (unsigned char)(BIT(7) + BIT(6))));
5899 WR_HARPOON(p_port
+ hp_scsisig
, (SCSI_BSY
| SCSI_IOBIT
| SCSI_CD
));
5900 FPT_scwiros(p_port
, SCSI_SEL
);
5902 WR_HARPOON(p_port
+ hp_scsidata_0
,
5903 (unsigned char)(RD_HARPOON(p_port
+ hp_scsidata_0
) &
5904 ~(unsigned char)BIT(6)));
5905 FPT_scwirod(p_port
, BIT(6));
5907 WR_HARPOON(p_port
+ hp_scsisig
,
5908 (SCSI_SEL
| SCSI_BSY
| SCSI_IOBIT
| SCSI_CD
));
5911 /*---------------------------------------------------------------------
5913 * Function: FPT_scxferc
5915 * Description: Handshake the p_data (DB4-0) across the bus.
5917 *---------------------------------------------------------------------*/
5919 static unsigned char FPT_scxferc(unsigned long p_port
, unsigned char p_data
)
5921 unsigned char curr_data
, ret_data
;
5923 curr_data
= p_data
| BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
5925 WR_HARPOON(p_port
+ hp_scsidata_0
, curr_data
);
5927 curr_data
&= ~BIT(7);
5929 WR_HARPOON(p_port
+ hp_scsidata_0
, curr_data
);
5931 FPT_scwirod(p_port
, BIT(7)); /*Wait for DB7 to be released. */
5932 while (!(RD_HARPOON(p_port
+ hp_scsidata_0
) & BIT(5))) ;
5934 ret_data
= (RD_HARPOON(p_port
+ hp_scsidata_0
) & (unsigned char)0x1F);
5936 curr_data
|= BIT(6);
5938 WR_HARPOON(p_port
+ hp_scsidata_0
, curr_data
);
5940 curr_data
&= ~BIT(5);
5942 WR_HARPOON(p_port
+ hp_scsidata_0
, curr_data
);
5944 FPT_scwirod(p_port
, BIT(5)); /*Wait for DB5 to be released. */
5946 curr_data
&= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */
5947 curr_data
|= BIT(7);
5949 WR_HARPOON(p_port
+ hp_scsidata_0
, curr_data
);
5951 curr_data
&= ~BIT(6);
5953 WR_HARPOON(p_port
+ hp_scsidata_0
, curr_data
);
5955 FPT_scwirod(p_port
, BIT(6)); /*Wait for DB6 to be released. */
5960 /*---------------------------------------------------------------------
5962 * Function: FPT_scsendi
5964 * Description: Transfer our Identification string to determine if we
5965 * will be the dominant master.
5967 *---------------------------------------------------------------------*/
5969 static unsigned char FPT_scsendi(unsigned long p_port
,
5970 unsigned char p_id_string
[])
5972 unsigned char ret_data
, byte_cnt
, bit_cnt
, defer
;
5976 for (byte_cnt
= 0; byte_cnt
< ID_STRING_LENGTH
; byte_cnt
++) {
5978 for (bit_cnt
= 0x80; bit_cnt
!= 0; bit_cnt
>>= 1) {
5981 ret_data
= FPT_scxferc(p_port
, 00);
5983 else if (p_id_string
[byte_cnt
] & bit_cnt
)
5985 ret_data
= FPT_scxferc(p_port
, 02);
5989 ret_data
= FPT_scxferc(p_port
, 01);
5994 if ((ret_data
& 0x1C) == 0x10)
5995 return 0x00; /*End of isolation stage, we won! */
5997 if (ret_data
& 0x1C)
6000 if ((defer
) && (!(ret_data
& 0x1F)))
6001 return 0x01; /*End of isolation stage, we lost. */
6008 return 0x01; /*We lost */
6010 return 0; /*We WON! Yeeessss! */
6013 /*---------------------------------------------------------------------
6015 * Function: FPT_sciso
6017 * Description: Transfer the Identification string.
6019 *---------------------------------------------------------------------*/
6021 static unsigned char FPT_sciso(unsigned long p_port
,
6022 unsigned char p_id_string
[])
6024 unsigned char ret_data
, the_data
, byte_cnt
, bit_cnt
;
6028 for (byte_cnt
= 0; byte_cnt
< ID_STRING_LENGTH
; byte_cnt
++) {
6030 for (bit_cnt
= 0; bit_cnt
< 8; bit_cnt
++) {
6032 ret_data
= FPT_scxferc(p_port
, 0);
6034 if (ret_data
& 0xFC)
6040 if (ret_data
& BIT(1)) {
6045 if ((ret_data
& 0x1F) == 0) {
6047 if(bit_cnt != 0 || bit_cnt != 8)
6051 FPT_scxferc(p_port, SYNC_PTRN);
6052 FPT_scxferc(p_port, ASSIGN_ID);
6064 p_id_string
[byte_cnt
] = the_data
;
6071 /*---------------------------------------------------------------------
6073 * Function: FPT_scwirod
6075 * Description: Sample the SCSI data bus making sure the signal has been
6076 * deasserted for the correct number of consecutive samples.
6078 *---------------------------------------------------------------------*/
6080 static void FPT_scwirod(unsigned long p_port
, unsigned char p_data_bit
)
6085 while (i
< MAX_SCSI_TAR
) {
6087 if (RD_HARPOON(p_port
+ hp_scsidata_0
) & p_data_bit
)
6098 /*---------------------------------------------------------------------
6100 * Function: FPT_scwiros
6102 * Description: Sample the SCSI Signal lines making sure the signal has been
6103 * deasserted for the correct number of consecutive samples.
6105 *---------------------------------------------------------------------*/
6107 static void FPT_scwiros(unsigned long p_port
, unsigned char p_data_bit
)
6112 while (i
< MAX_SCSI_TAR
) {
6114 if (RD_HARPOON(p_port
+ hp_scsisig
) & p_data_bit
)
6125 /*---------------------------------------------------------------------
6127 * Function: FPT_scvalq
6129 * Description: Make sure we received a valid data byte.
6131 *---------------------------------------------------------------------*/
6133 static unsigned char FPT_scvalq(unsigned char p_quintet
)
6135 unsigned char count
;
6137 for (count
= 1; count
< 0x08; count
<<= 1) {
6138 if (!(p_quintet
& count
))
6142 if (p_quintet
& 0x18)
6149 /*---------------------------------------------------------------------
6151 * Function: FPT_scsell
6153 * Description: Select the specified device ID using a selection timeout
6154 * less than 4ms. If somebody responds then it is a legacy
6155 * drive and this ID must be marked as such.
6157 *---------------------------------------------------------------------*/
6159 static unsigned char FPT_scsell(unsigned long p_port
, unsigned char targ_id
)
6163 WR_HARPOON(p_port
+ hp_page_ctrl
,
6164 (RD_HARPOON(p_port
+ hp_page_ctrl
) | G_INT_DISABLE
));
6166 ARAM_ACCESS(p_port
);
6168 WR_HARPOON(p_port
+ hp_addstat
,
6169 (RD_HARPOON(p_port
+ hp_addstat
) | SCAM_TIMER
));
6170 WR_HARPOON(p_port
+ hp_seltimeout
, TO_4ms
);
6172 for (i
= p_port
+ CMD_STRT
; i
< p_port
+ CMD_STRT
+ 12; i
+= 2) {
6173 WRW_HARPOON(i
, (MPM_OP
+ ACOMMAND
));
6175 WRW_HARPOON(i
, (BRH_OP
+ ALWAYS
+ NP
));
6177 WRW_HARPOON((p_port
+ hp_intstat
),
6178 (RESET
| TIMEOUT
| SEL
| BUS_FREE
| AUTO_INT
));
6180 WR_HARPOON(p_port
+ hp_select_id
, targ_id
);
6182 WR_HARPOON(p_port
+ hp_portctrl_0
, SCSI_PORT
);
6183 WR_HARPOON(p_port
+ hp_autostart_3
, (SELECT
| CMD_ONLY_STRT
));
6184 WR_HARPOON(p_port
+ hp_scsictrl_0
, (SEL_TAR
| ENA_RESEL
));
6186 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) &
6187 (RESET
| PROG_HLT
| TIMEOUT
| AUTO_INT
))) {
6190 if (RDW_HARPOON((p_port
+ hp_intstat
)) & RESET
)
6191 FPT_Wait(p_port
, TO_250ms
);
6193 DISABLE_AUTO(p_port
);
6195 WR_HARPOON(p_port
+ hp_addstat
,
6196 (RD_HARPOON(p_port
+ hp_addstat
) & ~SCAM_TIMER
));
6197 WR_HARPOON(p_port
+ hp_seltimeout
, TO_290ms
);
6199 SGRAM_ACCESS(p_port
);
6201 if (RDW_HARPOON((p_port
+ hp_intstat
)) & (RESET
| TIMEOUT
)) {
6203 WRW_HARPOON((p_port
+ hp_intstat
),
6204 (RESET
| TIMEOUT
| SEL
| BUS_FREE
| PHASE
));
6206 WR_HARPOON(p_port
+ hp_page_ctrl
,
6207 (RD_HARPOON(p_port
+ hp_page_ctrl
) &
6210 return 0; /*No legacy device */
6215 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) & BUS_FREE
)) {
6216 if (RD_HARPOON(p_port
+ hp_scsisig
) & SCSI_REQ
) {
6217 WR_HARPOON(p_port
+ hp_scsisig
,
6218 (SCSI_ACK
+ S_ILL_PH
));
6223 WRW_HARPOON((p_port
+ hp_intstat
), CLR_ALL_INT_1
);
6225 WR_HARPOON(p_port
+ hp_page_ctrl
,
6226 (RD_HARPOON(p_port
+ hp_page_ctrl
) &
6229 return 1; /*Found one of them oldies! */
6233 /*---------------------------------------------------------------------
6235 * Function: FPT_scwtsel
6237 * Description: Wait to be selected by another SCAM initiator.
6239 *---------------------------------------------------------------------*/
6241 static void FPT_scwtsel(unsigned long p_port
)
6243 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) & SCAM_SEL
)) {
6247 /*---------------------------------------------------------------------
6249 * Function: FPT_inisci
6251 * Description: Setup the data Structure with the info from the EEPROM.
6253 *---------------------------------------------------------------------*/
6255 static void FPT_inisci(unsigned char p_card
, unsigned long p_port
,
6256 unsigned char p_our_id
)
6258 unsigned char i
, k
, max_id
;
6259 unsigned short ee_data
;
6260 struct nvram_info
*pCurrNvRam
;
6262 pCurrNvRam
= FPT_BL_Card
[p_card
].pNvRamInfo
;
6264 if (RD_HARPOON(p_port
+ hp_page_ctrl
) & NARROW_SCSI_CARD
)
6271 for (i
= 0; i
< max_id
; i
++) {
6273 for (k
= 0; k
< 4; k
++)
6274 FPT_scamInfo
[i
].id_string
[k
] =
6275 pCurrNvRam
->niScamTbl
[i
][k
];
6276 for (k
= 4; k
< ID_STRING_LENGTH
; k
++)
6277 FPT_scamInfo
[i
].id_string
[k
] =
6278 (unsigned char)0x00;
6280 if (FPT_scamInfo
[i
].id_string
[0] == 0x00)
6281 FPT_scamInfo
[i
].state
= ID_UNUSED
; /*Default to unused ID. */
6283 FPT_scamInfo
[i
].state
= ID_UNASSIGNED
; /*Default to unassigned ID. */
6287 for (i
= 0; i
< max_id
; i
++) {
6288 for (k
= 0; k
< ID_STRING_LENGTH
; k
+= 2) {
6290 FPT_utilEERead(p_port
,
6292 short)((EE_SCAMBASE
/ 2) +
6293 (unsigned short)(i
*
6294 ((unsigned short)ID_STRING_LENGTH
/ 2)) + (unsigned short)(k
/ 2)));
6295 FPT_scamInfo
[i
].id_string
[k
] =
6296 (unsigned char)ee_data
;
6298 FPT_scamInfo
[i
].id_string
[k
+ 1] =
6299 (unsigned char)ee_data
;
6302 if ((FPT_scamInfo
[i
].id_string
[0] == 0x00) ||
6303 (FPT_scamInfo
[i
].id_string
[0] == 0xFF))
6305 FPT_scamInfo
[i
].state
= ID_UNUSED
; /*Default to unused ID. */
6308 FPT_scamInfo
[i
].state
= ID_UNASSIGNED
; /*Default to unassigned ID. */
6312 for (k
= 0; k
< ID_STRING_LENGTH
; k
++)
6313 FPT_scamInfo
[p_our_id
].id_string
[k
] = FPT_scamHAString
[k
];
6317 /*---------------------------------------------------------------------
6319 * Function: FPT_scmachid
6321 * Description: Match the Device ID string with our values stored in
6324 *---------------------------------------------------------------------*/
6326 static unsigned char FPT_scmachid(unsigned char p_card
,
6327 unsigned char p_id_string
[])
6330 unsigned char i
, k
, match
;
6332 for (i
= 0; i
< MAX_SCSI_TAR
; i
++) {
6336 for (k
= 0; k
< ID_STRING_LENGTH
; k
++) {
6337 if (p_id_string
[k
] != FPT_scamInfo
[i
].id_string
[k
])
6342 FPT_scamInfo
[i
].state
= ID_ASSIGNED
;
6348 if (p_id_string
[0] & BIT(5))
6353 if (((p_id_string
[0] & 0x06) == 0x02)
6354 || ((p_id_string
[0] & 0x06) == 0x04))
6355 match
= p_id_string
[1] & (unsigned char)0x1F;
6362 if (FPT_scamInfo
[match
].state
== ID_UNUSED
) {
6363 for (k
= 0; k
< ID_STRING_LENGTH
; k
++) {
6364 FPT_scamInfo
[match
].id_string
[k
] =
6368 FPT_scamInfo
[match
].state
= ID_ASSIGNED
;
6370 if (FPT_BL_Card
[p_card
].pNvRamInfo
== NULL
)
6371 FPT_BL_Card
[p_card
].globalFlags
|=
6379 if (match
== 0xFF) {
6380 if (p_id_string
[0] & BIT(5))
6383 match
= MAX_SCSI_TAR
- 1;
6387 if (p_id_string
[0] & BIT(7)) {
6388 return CLR_PRIORITY
;
6391 if (p_id_string
[0] & BIT(5))
6396 if (((p_id_string
[0] & 0x06) == 0x02)
6397 || ((p_id_string
[0] & 0x06) == 0x04))
6398 match
= p_id_string
[1] & (unsigned char)0x1F;
6406 if (FPT_scamInfo
[match
].state
== ID_UNASSIGNED
) {
6407 for (k
= 0; k
< ID_STRING_LENGTH
; k
++) {
6408 FPT_scamInfo
[match
].id_string
[k
] =
6412 FPT_scamInfo
[match
].id_string
[0] |= BIT(7);
6413 FPT_scamInfo
[match
].state
= ID_ASSIGNED
;
6414 if (FPT_BL_Card
[p_card
].pNvRamInfo
== NULL
)
6415 FPT_BL_Card
[p_card
].globalFlags
|=
6423 if (match
== 0xFF) {
6424 if (p_id_string
[0] & BIT(5))
6427 match
= MAX_SCSI_TAR
- 1;
6434 /*---------------------------------------------------------------------
6436 * Function: FPT_scsavdi
6438 * Description: Save off the device SCAM ID strings.
6440 *---------------------------------------------------------------------*/
6442 static void FPT_scsavdi(unsigned char p_card
, unsigned long p_port
)
6444 unsigned char i
, k
, max_id
;
6445 unsigned short ee_data
, sum_data
;
6449 for (i
= 1; i
< EE_SCAMBASE
/ 2; i
++) {
6450 sum_data
+= FPT_utilEERead(p_port
, i
);
6453 FPT_utilEEWriteOnOff(p_port
, 1); /* Enable write access to the EEPROM */
6455 if (RD_HARPOON(p_port
+ hp_page_ctrl
) & NARROW_SCSI_CARD
)
6461 for (i
= 0; i
< max_id
; i
++) {
6463 for (k
= 0; k
< ID_STRING_LENGTH
; k
+= 2) {
6464 ee_data
= FPT_scamInfo
[i
].id_string
[k
+ 1];
6466 ee_data
|= FPT_scamInfo
[i
].id_string
[k
];
6467 sum_data
+= ee_data
;
6468 FPT_utilEEWrite(p_port
, ee_data
,
6469 (unsigned short)((EE_SCAMBASE
/ 2) +
6470 (unsigned short)(i
*
6471 ((unsigned short)ID_STRING_LENGTH
/ 2)) + (unsigned short)(k
/ 2)));
6475 FPT_utilEEWrite(p_port
, sum_data
, EEPROM_CHECK_SUM
/ 2);
6476 FPT_utilEEWriteOnOff(p_port
, 0); /* Turn off write access */
6479 /*---------------------------------------------------------------------
6481 * Function: FPT_XbowInit
6483 * Description: Setup the Xbow for normal operation.
6485 *---------------------------------------------------------------------*/
6487 static void FPT_XbowInit(unsigned long port
, unsigned char ScamFlg
)
6491 i
= RD_HARPOON(port
+ hp_page_ctrl
);
6492 WR_HARPOON(port
+ hp_page_ctrl
, (unsigned char)(i
| G_INT_DISABLE
));
6494 WR_HARPOON(port
+ hp_scsireset
, 0x00);
6495 WR_HARPOON(port
+ hp_portctrl_1
, HOST_MODE8
);
6497 WR_HARPOON(port
+ hp_scsireset
, (DMA_RESET
| HPSCSI_RESET
| PROG_RESET
|
6500 WR_HARPOON(port
+ hp_scsireset
, SCSI_INI
);
6502 WR_HARPOON(port
+ hp_clkctrl_0
, CLKCTRL_DEFAULT
);
6504 WR_HARPOON(port
+ hp_scsisig
, 0x00); /* Clear any signals we might */
6505 WR_HARPOON(port
+ hp_scsictrl_0
, ENA_SCAM_SEL
);
6507 WRW_HARPOON((port
+ hp_intstat
), CLR_ALL_INT
);
6509 FPT_default_intena
= RESET
| RSEL
| PROG_HLT
| TIMEOUT
|
6510 BUS_FREE
| XFER_CNT_0
| AUTO_INT
;
6512 if ((ScamFlg
& SCAM_ENABLED
) && (ScamFlg
& SCAM_LEVEL2
))
6513 FPT_default_intena
|= SCAM_SEL
;
6515 WRW_HARPOON((port
+ hp_intena
), FPT_default_intena
);
6517 WR_HARPOON(port
+ hp_seltimeout
, TO_290ms
);
6519 /* Turn on SCSI_MODE8 for narrow cards to fix the
6520 strapping issue with the DUAL CHANNEL card */
6521 if (RD_HARPOON(port
+ hp_page_ctrl
) & NARROW_SCSI_CARD
)
6522 WR_HARPOON(port
+ hp_addstat
, SCSI_MODE8
);
6524 WR_HARPOON(port
+ hp_page_ctrl
, i
);
6528 /*---------------------------------------------------------------------
6530 * Function: FPT_BusMasterInit
6532 * Description: Initialize the BusMaster for normal operations.
6534 *---------------------------------------------------------------------*/
6536 static void FPT_BusMasterInit(unsigned long p_port
)
6539 WR_HARPOON(p_port
+ hp_sys_ctrl
, DRVR_RST
);
6540 WR_HARPOON(p_port
+ hp_sys_ctrl
, 0x00);
6542 WR_HARPOON(p_port
+ hp_host_blk_cnt
, XFER_BLK64
);
6544 WR_HARPOON(p_port
+ hp_bm_ctrl
, (BMCTRL_DEFAULT
));
6546 WR_HARPOON(p_port
+ hp_ee_ctrl
, (SCSI_TERM_ENA_H
));
6548 RD_HARPOON(p_port
+ hp_int_status
); /*Clear interrupts. */
6549 WR_HARPOON(p_port
+ hp_int_mask
, (INT_CMD_COMPL
| SCSI_INTERRUPT
));
6550 WR_HARPOON(p_port
+ hp_page_ctrl
, (RD_HARPOON(p_port
+ hp_page_ctrl
) &
6554 /*---------------------------------------------------------------------
6556 * Function: FPT_DiagEEPROM
6558 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6561 *---------------------------------------------------------------------*/
6563 static void FPT_DiagEEPROM(unsigned long p_port
)
6565 unsigned short index
, temp
, max_wd_cnt
;
6567 if (RD_HARPOON(p_port
+ hp_page_ctrl
) & NARROW_SCSI_CARD
)
6568 max_wd_cnt
= EEPROM_WD_CNT
;
6570 max_wd_cnt
= EEPROM_WD_CNT
* 2;
6572 temp
= FPT_utilEERead(p_port
, FW_SIGNATURE
/ 2);
6574 if (temp
== 0x4641) {
6576 for (index
= 2; index
< max_wd_cnt
; index
++) {
6578 temp
+= FPT_utilEERead(p_port
, index
);
6582 if (temp
== FPT_utilEERead(p_port
, EEPROM_CHECK_SUM
/ 2)) {
6584 return; /*EEPROM is Okay so return now! */
6588 FPT_utilEEWriteOnOff(p_port
, (unsigned char)1);
6590 for (index
= 0; index
< max_wd_cnt
; index
++) {
6592 FPT_utilEEWrite(p_port
, 0x0000, index
);
6597 FPT_utilEEWrite(p_port
, 0x4641, FW_SIGNATURE
/ 2);
6599 FPT_utilEEWrite(p_port
, 0x3920, MODEL_NUMB_0
/ 2);
6601 FPT_utilEEWrite(p_port
, 0x3033, MODEL_NUMB_2
/ 2);
6603 FPT_utilEEWrite(p_port
, 0x2020, MODEL_NUMB_4
/ 2);
6605 FPT_utilEEWrite(p_port
, 0x70D3, SYSTEM_CONFIG
/ 2);
6607 FPT_utilEEWrite(p_port
, 0x0010, BIOS_CONFIG
/ 2);
6609 FPT_utilEEWrite(p_port
, 0x0003, SCAM_CONFIG
/ 2);
6611 FPT_utilEEWrite(p_port
, 0x0007, ADAPTER_SCSI_ID
/ 2);
6614 FPT_utilEEWrite(p_port
, 0x0000, IGNORE_B_SCAN
/ 2);
6616 FPT_utilEEWrite(p_port
, 0x0000, SEND_START_ENA
/ 2);
6618 FPT_utilEEWrite(p_port
, 0x0000, DEVICE_ENABLE
/ 2);
6621 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL01
/ 2);
6623 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL23
/ 2);
6625 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL45
/ 2);
6627 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL67
/ 2);
6629 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBL89
/ 2);
6631 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBLab
/ 2);
6633 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBLcd
/ 2);
6635 FPT_utilEEWrite(p_port
, 0x4242, SYNC_RATE_TBLef
/ 2);
6638 FPT_utilEEWrite(p_port
, 0x6C46, 64 / 2); /*PRODUCT ID */
6640 FPT_utilEEWrite(p_port
, 0x7361, 66 / 2); /* FlashPoint LT */
6642 FPT_utilEEWrite(p_port
, 0x5068, 68 / 2);
6644 FPT_utilEEWrite(p_port
, 0x696F, 70 / 2);
6646 FPT_utilEEWrite(p_port
, 0x746E, 72 / 2);
6648 FPT_utilEEWrite(p_port
, 0x4C20, 74 / 2);
6650 FPT_utilEEWrite(p_port
, 0x2054, 76 / 2);
6652 FPT_utilEEWrite(p_port
, 0x2020, 78 / 2);
6655 index
= ((EE_SCAMBASE
/ 2) + (7 * 16));
6656 FPT_utilEEWrite(p_port
, (0x0700 + TYPE_CODE0
), index
);
6657 temp
+= (0x0700 + TYPE_CODE0
);
6659 FPT_utilEEWrite(p_port
, 0x5542, index
); /*Vendor ID code */
6660 temp
+= 0x5542; /* BUSLOGIC */
6662 FPT_utilEEWrite(p_port
, 0x4C53, index
);
6665 FPT_utilEEWrite(p_port
, 0x474F, index
);
6668 FPT_utilEEWrite(p_port
, 0x4349, index
);
6671 FPT_utilEEWrite(p_port
, 0x5442, index
); /*Vendor unique code */
6672 temp
+= 0x5442; /* BT- 930 */
6674 FPT_utilEEWrite(p_port
, 0x202D, index
);
6677 FPT_utilEEWrite(p_port
, 0x3339, index
);
6679 index
++; /*Serial # */
6680 FPT_utilEEWrite(p_port
, 0x2030, index
); /* 01234567 */
6683 FPT_utilEEWrite(p_port
, 0x5453, index
);
6686 FPT_utilEEWrite(p_port
, 0x5645, index
);
6689 FPT_utilEEWrite(p_port
, 0x2045, index
);
6692 FPT_utilEEWrite(p_port
, 0x202F, index
);
6695 FPT_utilEEWrite(p_port
, 0x4F4A, index
);
6698 FPT_utilEEWrite(p_port
, 0x204E, index
);
6701 FPT_utilEEWrite(p_port
, 0x3539, index
);
6704 FPT_utilEEWrite(p_port
, temp
, EEPROM_CHECK_SUM
/ 2);
6706 FPT_utilEEWriteOnOff(p_port
, (unsigned char)0);
6710 /*---------------------------------------------------------------------
6712 * Function: Queue Search Select
6714 * Description: Try to find a new command to execute.
6716 *---------------------------------------------------------------------*/
6718 static void FPT_queueSearchSelect(struct sccb_card
*pCurrCard
,
6719 unsigned char p_card
)
6721 unsigned char scan_ptr
, lun
;
6722 struct sccb_mgr_tar_info
*currTar_Info
;
6723 struct sccb
*pOldSccb
;
6725 scan_ptr
= pCurrCard
->scanIndex
;
6727 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][scan_ptr
];
6728 if ((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
6729 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) !=
6731 if (currTar_Info
->TarSelQ_Cnt
!= 0) {
6734 if (scan_ptr
== MAX_SCSI_TAR
)
6737 for (lun
= 0; lun
< MAX_LUN
; lun
++) {
6738 if (currTar_Info
->TarLUNBusy
[lun
] == 0) {
6740 pCurrCard
->currentSCCB
=
6741 currTar_Info
->TarSelQ_Head
;
6745 currentSCCB
!= NULL
)
6748 currentSCCB
->Lun
)) {
6752 pCurrCard
->currentSCCB
=
6758 if (pCurrCard
->currentSCCB
==
6761 if (pOldSccb
!= NULL
) {
6804 pCurrCard
->scanIndex
= scan_ptr
;
6806 pCurrCard
->globalFlags
|=
6816 if (scan_ptr
== MAX_SCSI_TAR
) {
6822 if ((currTar_Info
->TarSelQ_Cnt
!= 0) &&
6823 (currTar_Info
->TarLUNBusy
[0] == 0)) {
6825 pCurrCard
->currentSCCB
=
6826 currTar_Info
->TarSelQ_Head
;
6828 currTar_Info
->TarSelQ_Head
=
6829 (struct sccb
*)(pCurrCard
->currentSCCB
)->
6832 if (currTar_Info
->TarSelQ_Head
== NULL
) {
6833 currTar_Info
->TarSelQ_Tail
= NULL
;
6834 currTar_Info
->TarSelQ_Cnt
= 0;
6836 currTar_Info
->TarSelQ_Cnt
--;
6837 currTar_Info
->TarSelQ_Head
->
6838 Sccb_backlink
= (struct sccb
*)NULL
;
6842 if (scan_ptr
== MAX_SCSI_TAR
)
6845 pCurrCard
->scanIndex
= scan_ptr
;
6847 pCurrCard
->globalFlags
|= F_NEW_SCCB_CMD
;
6854 if (scan_ptr
== MAX_SCSI_TAR
) {
6859 } while (scan_ptr
!= pCurrCard
->scanIndex
);
6862 /*---------------------------------------------------------------------
6864 * Function: Queue Select Fail
6866 * Description: Add the current SCCB to the head of the Queue.
6868 *---------------------------------------------------------------------*/
6870 static void FPT_queueSelectFail(struct sccb_card
*pCurrCard
,
6871 unsigned char p_card
)
6873 unsigned char thisTarg
;
6874 struct sccb_mgr_tar_info
*currTar_Info
;
6876 if (pCurrCard
->currentSCCB
!= NULL
) {
6878 (unsigned char)(((struct sccb
*)(pCurrCard
->currentSCCB
))->
6880 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][thisTarg
];
6882 pCurrCard
->currentSCCB
->Sccb_backlink
= (struct sccb
*)NULL
;
6884 pCurrCard
->currentSCCB
->Sccb_forwardlink
=
6885 currTar_Info
->TarSelQ_Head
;
6887 if (currTar_Info
->TarSelQ_Cnt
== 0) {
6888 currTar_Info
->TarSelQ_Tail
= pCurrCard
->currentSCCB
;
6892 currTar_Info
->TarSelQ_Head
->Sccb_backlink
=
6893 pCurrCard
->currentSCCB
;
6896 currTar_Info
->TarSelQ_Head
= pCurrCard
->currentSCCB
;
6898 pCurrCard
->currentSCCB
= NULL
;
6899 currTar_Info
->TarSelQ_Cnt
++;
6903 /*---------------------------------------------------------------------
6905 * Function: Queue Command Complete
6907 * Description: Call the callback function with the current SCCB.
6909 *---------------------------------------------------------------------*/
6911 static void FPT_queueCmdComplete(struct sccb_card
*pCurrCard
,
6912 struct sccb
*p_sccb
, unsigned char p_card
)
6915 unsigned char i
, SCSIcmd
;
6916 CALL_BK_FN callback
;
6917 struct sccb_mgr_tar_info
*currTar_Info
;
6919 SCSIcmd
= p_sccb
->Cdb
[0];
6921 if (!(p_sccb
->Sccb_XferState
& F_ALL_XFERRED
)) {
6924 ControlByte
& (SCCB_DATA_XFER_OUT
| SCCB_DATA_XFER_IN
))
6925 && (p_sccb
->HostStatus
== SCCB_COMPLETE
)
6926 && (p_sccb
->TargetStatus
!= SSCHECK
))
6928 if ((SCSIcmd
== SCSI_READ
) ||
6929 (SCSIcmd
== SCSI_WRITE
) ||
6930 (SCSIcmd
== SCSI_READ_EXTENDED
) ||
6931 (SCSIcmd
== SCSI_WRITE_EXTENDED
) ||
6932 (SCSIcmd
== SCSI_WRITE_AND_VERIFY
) ||
6933 (SCSIcmd
== SCSI_START_STOP_UNIT
) ||
6934 (pCurrCard
->globalFlags
& F_NO_FILTER
)
6936 p_sccb
->HostStatus
= SCCB_DATA_UNDER_RUN
;
6939 if (p_sccb
->SccbStatus
== SCCB_IN_PROCESS
) {
6940 if (p_sccb
->HostStatus
|| p_sccb
->TargetStatus
)
6941 p_sccb
->SccbStatus
= SCCB_ERROR
;
6943 p_sccb
->SccbStatus
= SCCB_SUCCESS
;
6946 if (p_sccb
->Sccb_XferState
& F_AUTO_SENSE
) {
6948 p_sccb
->CdbLength
= p_sccb
->Save_CdbLen
;
6949 for (i
= 0; i
< 6; i
++) {
6950 p_sccb
->Cdb
[i
] = p_sccb
->Save_Cdb
[i
];
6954 if ((p_sccb
->OperationCode
== RESIDUAL_SG_COMMAND
) ||
6955 (p_sccb
->OperationCode
== RESIDUAL_COMMAND
)) {
6957 FPT_utilUpdateResidual(p_sccb
);
6960 pCurrCard
->cmdCounter
--;
6961 if (!pCurrCard
->cmdCounter
) {
6963 if (pCurrCard
->globalFlags
& F_GREEN_PC
) {
6964 WR_HARPOON(pCurrCard
->ioPort
+ hp_clkctrl_0
,
6965 (PWR_DWN
| CLKCTRL_DEFAULT
));
6966 WR_HARPOON(pCurrCard
->ioPort
+ hp_sys_ctrl
, STOP_CLK
);
6969 WR_HARPOON(pCurrCard
->ioPort
+ hp_semaphore
,
6970 (RD_HARPOON(pCurrCard
->ioPort
+ hp_semaphore
) &
6975 if (pCurrCard
->discQCount
!= 0) {
6976 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
];
6977 if (((pCurrCard
->globalFlags
& F_CONLUN_IO
) &&
6978 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) !=
6980 pCurrCard
->discQCount
--;
6981 pCurrCard
->discQ_Tbl
[currTar_Info
->
6982 LunDiscQ_Idx
[p_sccb
->Lun
]] = NULL
;
6984 if (p_sccb
->Sccb_tag
) {
6985 pCurrCard
->discQCount
--;
6986 pCurrCard
->discQ_Tbl
[p_sccb
->Sccb_tag
] = NULL
;
6988 pCurrCard
->discQCount
--;
6989 pCurrCard
->discQ_Tbl
[currTar_Info
->
6990 LunDiscQ_Idx
[0]] = NULL
;
6996 callback
= (CALL_BK_FN
) p_sccb
->SccbCallback
;
6998 pCurrCard
->globalFlags
|= F_NEW_SCCB_CMD
;
6999 pCurrCard
->currentSCCB
= NULL
;
7002 /*---------------------------------------------------------------------
7004 * Function: Queue Disconnect
7006 * Description: Add SCCB to our disconnect array.
7008 *---------------------------------------------------------------------*/
7009 static void FPT_queueDisconnect(struct sccb
*p_sccb
, unsigned char p_card
)
7011 struct sccb_mgr_tar_info
*currTar_Info
;
7013 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
];
7015 if (((FPT_BL_Card
[p_card
].globalFlags
& F_CONLUN_IO
) &&
7016 ((currTar_Info
->TarStatus
& TAR_TAG_Q_MASK
) != TAG_Q_TRYING
))) {
7017 FPT_BL_Card
[p_card
].discQ_Tbl
[currTar_Info
->
7018 LunDiscQ_Idx
[p_sccb
->Lun
]] =
7021 if (p_sccb
->Sccb_tag
) {
7022 FPT_BL_Card
[p_card
].discQ_Tbl
[p_sccb
->Sccb_tag
] =
7024 FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
].TarLUNBusy
[0] =
7026 FPT_sccbMgrTbl
[p_card
][p_sccb
->TargID
].TarTagQ_Cnt
++;
7028 FPT_BL_Card
[p_card
].discQ_Tbl
[currTar_Info
->
7029 LunDiscQ_Idx
[0]] = p_sccb
;
7032 FPT_BL_Card
[p_card
].currentSCCB
= NULL
;
7035 /*---------------------------------------------------------------------
7037 * Function: Queue Flush SCCB
7039 * Description: Flush all SCCB's back to the host driver for this target.
7041 *---------------------------------------------------------------------*/
7043 static void FPT_queueFlushSccb(unsigned char p_card
, unsigned char error_code
)
7045 unsigned char qtag
, thisTarg
;
7046 struct sccb
*currSCCB
;
7047 struct sccb_mgr_tar_info
*currTar_Info
;
7049 currSCCB
= FPT_BL_Card
[p_card
].currentSCCB
;
7050 if (currSCCB
!= NULL
) {
7051 thisTarg
= (unsigned char)currSCCB
->TargID
;
7052 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][thisTarg
];
7054 for (qtag
= 0; qtag
< QUEUE_DEPTH
; qtag
++) {
7056 if (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] &&
7057 (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->TargID
==
7060 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->
7061 HostStatus
= (unsigned char)error_code
;
7063 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
],
7064 FPT_BL_Card
[p_card
].
7065 discQ_Tbl
[qtag
], p_card
);
7067 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] = NULL
;
7068 currTar_Info
->TarTagQ_Cnt
--;
7076 /*---------------------------------------------------------------------
7078 * Function: Queue Flush Target SCCB
7080 * Description: Flush all SCCB's back to the host driver for this target.
7082 *---------------------------------------------------------------------*/
7084 static void FPT_queueFlushTargSccb(unsigned char p_card
, unsigned char thisTarg
,
7085 unsigned char error_code
)
7088 struct sccb_mgr_tar_info
*currTar_Info
;
7090 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][thisTarg
];
7092 for (qtag
= 0; qtag
< QUEUE_DEPTH
; qtag
++) {
7094 if (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] &&
7095 (FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->TargID
== thisTarg
)) {
7097 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
]->HostStatus
=
7098 (unsigned char)error_code
;
7100 FPT_queueCmdComplete(&FPT_BL_Card
[p_card
],
7101 FPT_BL_Card
[p_card
].
7102 discQ_Tbl
[qtag
], p_card
);
7104 FPT_BL_Card
[p_card
].discQ_Tbl
[qtag
] = NULL
;
7105 currTar_Info
->TarTagQ_Cnt
--;
7112 static void FPT_queueAddSccb(struct sccb
*p_SCCB
, unsigned char p_card
)
7114 struct sccb_mgr_tar_info
*currTar_Info
;
7115 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_SCCB
->TargID
];
7117 p_SCCB
->Sccb_forwardlink
= NULL
;
7119 p_SCCB
->Sccb_backlink
= currTar_Info
->TarSelQ_Tail
;
7121 if (currTar_Info
->TarSelQ_Cnt
== 0) {
7123 currTar_Info
->TarSelQ_Head
= p_SCCB
;
7128 currTar_Info
->TarSelQ_Tail
->Sccb_forwardlink
= p_SCCB
;
7131 currTar_Info
->TarSelQ_Tail
= p_SCCB
;
7132 currTar_Info
->TarSelQ_Cnt
++;
7135 /*---------------------------------------------------------------------
7137 * Function: Queue Find SCCB
7139 * Description: Search the target select Queue for this SCCB, and
7140 * remove it if found.
7142 *---------------------------------------------------------------------*/
7144 static unsigned char FPT_queueFindSccb(struct sccb
*p_SCCB
,
7145 unsigned char p_card
)
7148 struct sccb_mgr_tar_info
*currTar_Info
;
7150 currTar_Info
= &FPT_sccbMgrTbl
[p_card
][p_SCCB
->TargID
];
7152 q_ptr
= currTar_Info
->TarSelQ_Head
;
7154 while (q_ptr
!= NULL
) {
7156 if (q_ptr
== p_SCCB
) {
7158 if (currTar_Info
->TarSelQ_Head
== q_ptr
) {
7160 currTar_Info
->TarSelQ_Head
=
7161 q_ptr
->Sccb_forwardlink
;
7164 if (currTar_Info
->TarSelQ_Tail
== q_ptr
) {
7166 currTar_Info
->TarSelQ_Tail
=
7167 q_ptr
->Sccb_backlink
;
7170 if (q_ptr
->Sccb_forwardlink
!= NULL
) {
7171 q_ptr
->Sccb_forwardlink
->Sccb_backlink
=
7172 q_ptr
->Sccb_backlink
;
7175 if (q_ptr
->Sccb_backlink
!= NULL
) {
7176 q_ptr
->Sccb_backlink
->Sccb_forwardlink
=
7177 q_ptr
->Sccb_forwardlink
;
7180 currTar_Info
->TarSelQ_Cnt
--;
7186 q_ptr
= q_ptr
->Sccb_forwardlink
;
7194 /*---------------------------------------------------------------------
7196 * Function: Utility Update Residual Count
7198 * Description: Update the XferCnt to the remaining byte count.
7199 * If we transferred all the data then just write zero.
7200 * If Non-SG transfer then report Total Cnt - Actual Transfer
7201 * Cnt. For SG transfers add the count fields of all
7202 * remaining SG elements, as well as any partial remaining
7205 *---------------------------------------------------------------------*/
7207 static void FPT_utilUpdateResidual(struct sccb
*p_SCCB
)
7209 unsigned long partial_cnt
;
7210 unsigned int sg_index
;
7211 unsigned long *sg_ptr
;
7213 if (p_SCCB
->Sccb_XferState
& F_ALL_XFERRED
) {
7215 p_SCCB
->DataLength
= 0x0000;
7218 else if (p_SCCB
->Sccb_XferState
& F_SG_XFER
) {
7220 partial_cnt
= 0x0000;
7222 sg_index
= p_SCCB
->Sccb_sgseg
;
7224 sg_ptr
= (unsigned long *)p_SCCB
->DataPointer
;
7226 if (p_SCCB
->Sccb_SGoffset
) {
7228 partial_cnt
= p_SCCB
->Sccb_SGoffset
;
7232 while (((unsigned long)sg_index
*
7233 (unsigned long)SG_ELEMENT_SIZE
) < p_SCCB
->DataLength
) {
7235 partial_cnt
+= *(sg_ptr
+ (sg_index
* 2));
7239 p_SCCB
->DataLength
= partial_cnt
;
7244 p_SCCB
->DataLength
-= p_SCCB
->Sccb_ATC
;
7248 /*---------------------------------------------------------------------
7250 * Function: Wait 1 Second
7252 * Description: Wait for 1 second.
7254 *---------------------------------------------------------------------*/
7256 static void FPT_Wait1Second(unsigned long p_port
)
7260 for (i
= 0; i
< 4; i
++) {
7262 FPT_Wait(p_port
, TO_250ms
);
7264 if ((RD_HARPOON(p_port
+ hp_scsictrl_0
) & SCSI_RST
))
7267 if ((RDW_HARPOON((p_port
+ hp_intstat
)) & SCAM_SEL
))
7272 /*---------------------------------------------------------------------
7274 * Function: FPT_Wait
7276 * Description: Wait the desired delay.
7278 *---------------------------------------------------------------------*/
7280 static void FPT_Wait(unsigned long p_port
, unsigned char p_delay
)
7282 unsigned char old_timer
;
7283 unsigned char green_flag
;
7285 old_timer
= RD_HARPOON(p_port
+ hp_seltimeout
);
7287 green_flag
= RD_HARPOON(p_port
+ hp_clkctrl_0
);
7288 WR_HARPOON(p_port
+ hp_clkctrl_0
, CLKCTRL_DEFAULT
);
7290 WR_HARPOON(p_port
+ hp_seltimeout
, p_delay
);
7291 WRW_HARPOON((p_port
+ hp_intstat
), TIMEOUT
);
7292 WRW_HARPOON((p_port
+ hp_intena
), (FPT_default_intena
& ~TIMEOUT
));
7294 WR_HARPOON(p_port
+ hp_portctrl_0
,
7295 (RD_HARPOON(p_port
+ hp_portctrl_0
) | START_TO
));
7297 while (!(RDW_HARPOON((p_port
+ hp_intstat
)) & TIMEOUT
)) {
7299 if ((RD_HARPOON(p_port
+ hp_scsictrl_0
) & SCSI_RST
))
7302 if ((RDW_HARPOON((p_port
+ hp_intstat
)) & SCAM_SEL
))
7306 WR_HARPOON(p_port
+ hp_portctrl_0
,
7307 (RD_HARPOON(p_port
+ hp_portctrl_0
) & ~START_TO
));
7309 WRW_HARPOON((p_port
+ hp_intstat
), TIMEOUT
);
7310 WRW_HARPOON((p_port
+ hp_intena
), FPT_default_intena
);
7312 WR_HARPOON(p_port
+ hp_clkctrl_0
, green_flag
);
7314 WR_HARPOON(p_port
+ hp_seltimeout
, old_timer
);
7317 /*---------------------------------------------------------------------
7319 * Function: Enable/Disable Write to EEPROM
7321 * Description: The EEPROM must first be enabled for writes
7322 * A total of 9 clocks are needed.
7324 *---------------------------------------------------------------------*/
7326 static void FPT_utilEEWriteOnOff(unsigned long p_port
, unsigned char p_mode
)
7328 unsigned char ee_value
;
7331 (unsigned char)(RD_HARPOON(p_port
+ hp_ee_ctrl
) &
7332 (EXT_ARB_ACK
| SCSI_TERM_ENA_H
));
7336 FPT_utilEESendCmdAddr(p_port
, EWEN
, EWEN_ADDR
);
7340 FPT_utilEESendCmdAddr(p_port
, EWDS
, EWDS_ADDR
);
7342 WR_HARPOON(p_port
+ hp_ee_ctrl
, (ee_value
| SEE_MS
)); /*Turn off CS */
7343 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
); /*Turn off Master Select */
7346 /*---------------------------------------------------------------------
7348 * Function: Write EEPROM
7350 * Description: Write a word to the EEPROM at the specified
7353 *---------------------------------------------------------------------*/
7355 static void FPT_utilEEWrite(unsigned long p_port
, unsigned short ee_data
,
7356 unsigned short ee_addr
)
7359 unsigned char ee_value
;
7364 char)((RD_HARPOON(p_port
+ hp_ee_ctrl
) &
7365 (EXT_ARB_ACK
| SCSI_TERM_ENA_H
)) | (SEE_MS
| SEE_CS
));
7367 FPT_utilEESendCmdAddr(p_port
, EE_WRITE
, ee_addr
);
7369 ee_value
|= (SEE_MS
+ SEE_CS
);
7371 for (i
= 0x8000; i
!= 0; i
>>= 1) {
7376 ee_value
&= ~SEE_DO
;
7378 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7379 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7380 ee_value
|= SEE_CLK
; /* Clock data! */
7381 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7382 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7383 ee_value
&= ~SEE_CLK
;
7384 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7385 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7387 ee_value
&= (EXT_ARB_ACK
| SCSI_TERM_ENA_H
);
7388 WR_HARPOON(p_port
+ hp_ee_ctrl
, (ee_value
| SEE_MS
));
7390 FPT_Wait(p_port
, TO_10ms
);
7392 WR_HARPOON(p_port
+ hp_ee_ctrl
, (ee_value
| SEE_MS
| SEE_CS
)); /* Set CS to EEPROM */
7393 WR_HARPOON(p_port
+ hp_ee_ctrl
, (ee_value
| SEE_MS
)); /* Turn off CS */
7394 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
); /* Turn off Master Select */
7397 /*---------------------------------------------------------------------
7399 * Function: Read EEPROM
7401 * Description: Read a word from the EEPROM at the desired
7404 *---------------------------------------------------------------------*/
7406 static unsigned short FPT_utilEERead(unsigned long p_port
,
7407 unsigned short ee_addr
)
7409 unsigned short i
, ee_data1
, ee_data2
;
7412 ee_data1
= FPT_utilEEReadOrg(p_port
, ee_addr
);
7414 ee_data2
= FPT_utilEEReadOrg(p_port
, ee_addr
);
7416 if (ee_data1
== ee_data2
)
7419 ee_data1
= ee_data2
;
7427 /*---------------------------------------------------------------------
7429 * Function: Read EEPROM Original
7431 * Description: Read a word from the EEPROM at the desired
7434 *---------------------------------------------------------------------*/
7436 static unsigned short FPT_utilEEReadOrg(unsigned long p_port
,
7437 unsigned short ee_addr
)
7440 unsigned char ee_value
;
7441 unsigned short i
, ee_data
;
7445 char)((RD_HARPOON(p_port
+ hp_ee_ctrl
) &
7446 (EXT_ARB_ACK
| SCSI_TERM_ENA_H
)) | (SEE_MS
| SEE_CS
));
7448 FPT_utilEESendCmdAddr(p_port
, EE_READ
, ee_addr
);
7450 ee_value
|= (SEE_MS
+ SEE_CS
);
7453 for (i
= 1; i
<= 16; i
++) {
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
);
7464 if (RD_HARPOON(p_port
+ hp_ee_ctrl
) & SEE_DI
)
7468 ee_value
&= ~(SEE_MS
+ SEE_CS
);
7469 WR_HARPOON(p_port
+ hp_ee_ctrl
, (ee_value
| SEE_MS
)); /*Turn off CS */
7470 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
); /*Turn off Master Select */
7475 /*---------------------------------------------------------------------
7477 * Function: Send EE command and Address to the EEPROM
7479 * Description: Transfers the correct command and sends the address
7482 *---------------------------------------------------------------------*/
7484 static void FPT_utilEESendCmdAddr(unsigned long p_port
, unsigned char ee_cmd
,
7485 unsigned short ee_addr
)
7487 unsigned char ee_value
;
7488 unsigned char narrow_flg
;
7493 (unsigned char)(RD_HARPOON(p_port
+ hp_page_ctrl
) &
7497 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7499 ee_value
|= SEE_CS
; /* Set CS to EEPROM */
7500 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7502 for (i
= 0x04; i
!= 0; i
>>= 1) {
7507 ee_value
&= ~SEE_DO
;
7509 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7510 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7511 ee_value
|= SEE_CLK
; /* Clock data! */
7512 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7513 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7514 ee_value
&= ~SEE_CLK
;
7515 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7516 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7530 ee_value
&= ~SEE_DO
;
7532 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7533 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7534 ee_value
|= SEE_CLK
; /* Clock data! */
7535 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7536 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7537 ee_value
&= ~SEE_CLK
;
7538 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7539 WR_HARPOON(p_port
+ hp_ee_ctrl
, ee_value
);
7545 static unsigned short FPT_CalcCrc16(unsigned char buffer
[])
7547 unsigned short crc
= 0;
7550 for (i
= 0; i
< ID_STRING_LENGTH
; i
++) {
7551 ch
= (unsigned short)buffer
[i
];
7552 for (j
= 0; j
< 8; j
++) {
7554 crc
= (crc
>> 1) ^ CRCMASK
;
7563 static unsigned char FPT_CalcLrc(unsigned char buffer
[])
7568 for (i
= 0; i
< ID_STRING_LENGTH
; i
++)
7574 The following inline definitions avoid type conflicts.
7577 static inline unsigned char
7578 FlashPoint__ProbeHostAdapter(struct FlashPoint_Info
*FlashPointInfo
)
7580 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info
*)
7584 static inline FlashPoint_CardHandle_T
7585 FlashPoint__HardwareResetHostAdapter(struct FlashPoint_Info
*FlashPointInfo
)
7587 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info
*)
7592 FlashPoint__ReleaseHostAdapter(FlashPoint_CardHandle_T CardHandle
)
7594 FlashPoint_ReleaseHostAdapter(CardHandle
);
7598 FlashPoint__StartCCB(FlashPoint_CardHandle_T CardHandle
,
7599 struct BusLogic_CCB
*CCB
)
7601 FlashPoint_StartCCB(CardHandle
, (struct sccb
*)CCB
);
7605 FlashPoint__AbortCCB(FlashPoint_CardHandle_T CardHandle
,
7606 struct BusLogic_CCB
*CCB
)
7608 FlashPoint_AbortCCB(CardHandle
, (struct sccb
*)CCB
);
7612 FlashPoint__InterruptPending(FlashPoint_CardHandle_T CardHandle
)
7614 return FlashPoint_InterruptPending(CardHandle
);
7618 FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle
)
7620 return FlashPoint_HandleInterrupt(CardHandle
);
7623 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7624 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7625 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7626 #define FlashPoint_StartCCB FlashPoint__StartCCB
7627 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7628 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7629 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7631 #else /* CONFIG_SCSI_OMIT_FLASHPOINT */
7634 Define prototypes for the FlashPoint SCCB Manager Functions.
7637 extern unsigned char FlashPoint_ProbeHostAdapter(struct FlashPoint_Info
*);
7638 extern FlashPoint_CardHandle_T
7639 FlashPoint_HardwareResetHostAdapter(struct FlashPoint_Info
*);
7640 extern void FlashPoint_StartCCB(FlashPoint_CardHandle_T
, struct BusLogic_CCB
*);
7641 extern int FlashPoint_AbortCCB(FlashPoint_CardHandle_T
, struct BusLogic_CCB
*);
7642 extern bool FlashPoint_InterruptPending(FlashPoint_CardHandle_T
);
7643 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T
);
7644 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T
);
7646 #endif /* CONFIG_SCSI_OMIT_FLASHPOINT */