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 #ifdef CONFIG_SCSI_FLASHPOINT
24 #define CRCMASK 0xA001
26 #define FAILURE 0xFFFFFFFFL
29 typedef void (*CALL_BK_FN) (struct sccb *);
31 struct sccb_mgr_info {
33 unsigned char si_present;
34 unsigned char si_intvect;
38 u16 si_per_targ_init_sync;
39 u16 si_per_targ_fast_nego;
40 u16 si_per_targ_ultra_nego;
41 u16 si_per_targ_no_disc;
42 u16 si_per_targ_wide_nego;
44 unsigned char si_card_family;
45 unsigned char si_bustype;
46 unsigned char si_card_model[3];
47 unsigned char si_relative_cardnum;
48 unsigned char si_reserved[4];
50 unsigned char si_XlatInfo[4];
52 u32 si_secondary_range;
55 #define SCSI_PARITY_ENA 0x0001
56 #define LOW_BYTE_TERM 0x0010
57 #define HIGH_BYTE_TERM 0x0020
58 #define BUSTYPE_PCI 0x3
60 #define SUPPORT_16TAR_32LUN 0x0002
61 #define SOFT_RESET 0x0004
62 #define EXTENDED_TRANSLATION 0x0008
63 #define POST_ALL_UNDERRRUNS 0x0040
64 #define FLAG_SCAM_ENABLED 0x0080
65 #define FLAG_SCAM_LEVEL2 0x0100
67 #define HARPOON_FAMILY 0x02
69 /* SCCB struct used for both SCCB and UCB manager compiles!
70 * The UCB Manager treats the SCCB as it's 'native hardware structure'
75 unsigned char OperationCode;
76 unsigned char ControlByte;
77 unsigned char CdbLength;
78 unsigned char RequestSenseLength;
81 unsigned char CcbRes[2];
82 unsigned char HostStatus;
83 unsigned char TargetStatus;
86 unsigned char Cdb[12];
87 unsigned char CcbRes1;
88 unsigned char Reserved1;
92 CALL_BK_FN SccbCallback; /* VOID (*SccbCallback)(); */
93 u32 SccbIOPort; /* Identifies board base port */
94 unsigned char SccbStatus;
95 unsigned char SCCBRes2;
98 u32 Sccb_XferCnt; /* actual transfer count */
100 u32 SccbVirtDataPtr; /* virtual addr for OS/2 */
104 unsigned char Sccb_scsimsg; /* identify msg for selection */
105 unsigned char Sccb_tag;
106 unsigned char Sccb_scsistat;
107 unsigned char Sccb_idmsg; /* image of last msg in */
108 struct sccb *Sccb_forwardlink;
109 struct sccb *Sccb_backlink;
111 unsigned char Save_Cdb[6];
112 unsigned char Save_CdbLen;
113 unsigned char Sccb_XferState;
119 #define SCATTER_GATHER_COMMAND 0x02
120 #define RESIDUAL_COMMAND 0x03
121 #define RESIDUAL_SG_COMMAND 0x04
122 #define RESET_COMMAND 0x81
124 #define F_USE_CMD_Q 0x20 /*Inidcates TAGGED command. */
125 #define TAG_TYPE_MASK 0xC0 /*Type of tag msg to send. */
126 #define SCCB_DATA_XFER_OUT 0x10 /* Write */
127 #define SCCB_DATA_XFER_IN 0x08 /* Read */
129 #define NO_AUTO_REQUEST_SENSE 0x01 /* No Request Sense Buffer */
131 #define BUS_FREE_ST 0
133 #define SELECT_BDR_ST 2 /* Select w\ Bus Device Reset */
134 #define SELECT_SN_ST 3 /* Select w\ Sync Nego */
135 #define SELECT_WN_ST 4 /* Select w\ Wide Data Nego */
136 #define SELECT_Q_ST 5 /* Select w\ Tagged Q'ing */
138 #define DATA_OUT_ST 7
140 #define DISCONNECT_ST 9
143 #define F_HOST_XFER_DIR 0x01
144 #define F_ALL_XFERRED 0x02
145 #define F_SG_XFER 0x04
146 #define F_AUTO_SENSE 0x08
147 #define F_ODD_BALL_CNT 0x10
148 #define F_NO_DATA_YET 0x80
150 #define F_STATUSLOADED 0x01
151 #define F_DEV_SELECTED 0x04
153 #define SCCB_COMPLETE 0x00 /* SCCB completed without error */
154 #define SCCB_DATA_UNDER_RUN 0x0C
155 #define SCCB_SELECTION_TIMEOUT 0x11 /* Set SCSI selection timed out */
156 #define SCCB_DATA_OVER_RUN 0x12
157 #define SCCB_PHASE_SEQUENCE_FAIL 0x14 /* Target bus phase sequence failure */
159 #define SCCB_GROSS_FW_ERR 0x27 /* Major problem! */
160 #define SCCB_BM_ERR 0x30 /* BusMaster error. */
161 #define SCCB_PARITY_ERR 0x34 /* SCSI parity error */
163 #define SCCB_IN_PROCESS 0x00
164 #define SCCB_SUCCESS 0x01
165 #define SCCB_ABORT 0x02
166 #define SCCB_ERROR 0x04
168 #define ORION_FW_REV 3110
170 #define QUEUE_DEPTH 254+1 /*1 for Normal disconnect 32 for Q'ing. */
172 #define MAX_MB_CARDS 4 /* Max. no of cards suppoerted on Mother Board */
174 #define MAX_SCSI_TAR 16
176 #define LUN_MASK 0x1f
178 #define SG_BUF_CNT 16 /*Number of prefetched elements. */
180 #define SG_ELEMENT_SIZE 8 /*Eight byte per element. */
182 #define RD_HARPOON(ioport) inb((u32)ioport)
183 #define RDW_HARPOON(ioport) inw((u32)ioport)
184 #define RD_HARP32(ioport,offset,data) (data = inl((u32)(ioport + offset)))
185 #define WR_HARPOON(ioport,val) outb((u8) val, (u32)ioport)
186 #define WRW_HARPOON(ioport,val) outw((u16)val, (u32)ioport)
187 #define WR_HARP32(ioport,offset,data) outl(data, (u32)(ioport + offset))
189 #define TAR_SYNC_MASK (BIT(7)+BIT(6))
190 #define SYNC_TRYING BIT(6)
191 #define SYNC_SUPPORTED (BIT(7)+BIT(6))
193 #define TAR_WIDE_MASK (BIT(5)+BIT(4))
194 #define WIDE_ENABLED BIT(4)
195 #define WIDE_NEGOCIATED BIT(5)
197 #define TAR_TAG_Q_MASK (BIT(3)+BIT(2))
198 #define TAG_Q_TRYING BIT(2)
199 #define TAG_Q_REJECT BIT(3)
201 #define TAR_ALLOW_DISC BIT(0)
203 #define EE_SYNC_MASK (BIT(0)+BIT(1))
204 #define EE_SYNC_5MB BIT(0)
205 #define EE_SYNC_10MB BIT(1)
206 #define EE_SYNC_20MB (BIT(0)+BIT(1))
208 #define EE_WIDE_SCSI BIT(7)
210 struct sccb_mgr_tar_info {
212 struct sccb *TarSelQ_Head;
213 struct sccb *TarSelQ_Tail;
214 unsigned char TarLUN_CA; /*Contingent Allgiance */
215 unsigned char TarTagQ_Cnt;
216 unsigned char TarSelQ_Cnt;
217 unsigned char TarStatus;
218 unsigned char TarEEValue;
219 unsigned char TarSyncCtrl;
220 unsigned char TarReserved[2]; /* for alignment */
221 unsigned char LunDiscQ_Idx[MAX_LUN];
222 unsigned char TarLUNBusy[MAX_LUN];
226 unsigned char niModel; /* Model No. of card */
227 unsigned char niCardNo; /* Card no. */
228 u32 niBaseAddr; /* Port Address of card */
229 unsigned char niSysConf; /* Adapter Configuration byte -
230 Byte 16 of eeprom map */
231 unsigned char niScsiConf; /* SCSI Configuration byte -
232 Byte 17 of eeprom map */
233 unsigned char niScamConf; /* SCAM Configuration byte -
234 Byte 20 of eeprom map */
235 unsigned char niAdapId; /* Host Adapter ID -
236 Byte 24 of eerpom map */
237 unsigned char niSyncTbl[MAX_SCSI_TAR / 2]; /* Sync/Wide byte
239 unsigned char niScamTbl[MAX_SCSI_TAR][4]; /* Compressed Scam name
249 struct sccb *currentSCCB;
250 struct sccb_mgr_info *cardInfo;
254 unsigned short cmdCounter;
255 unsigned char discQCount;
256 unsigned char tagQ_Lst;
257 unsigned char cardIndex;
258 unsigned char scanIndex;
259 unsigned char globalFlags;
261 struct nvram_info *pNvRamInfo;
262 struct sccb *discQ_Tbl[QUEUE_DEPTH];
266 #define F_TAG_STARTED 0x01
267 #define F_CONLUN_IO 0x02
268 #define F_DO_RENEGO 0x04
269 #define F_NO_FILTER 0x08
270 #define F_GREEN_PC 0x10
271 #define F_HOST_XFER_ACT 0x20
272 #define F_NEW_SCCB_CMD 0x40
273 #define F_UPDATE_EEPROM 0x80
275 #define ID_STRING_LENGTH 32
276 #define TYPE_CODE0 0x63 /*Level2 Mstr (bits 7-6), */
278 #define SLV_TYPE_CODE0 0xA3 /*Priority Bit set (bits 7-6), */
280 #define ASSIGN_ID 0x00
281 #define SET_P_FLAG 0x01
282 #define CFG_CMPLT 0x03
283 #define DOM_MSTR 0x0F
284 #define SYNC_PTRN 0x1F
288 #define MISC_CODE 0x14
289 #define CLR_P_FLAG 0x18
291 #define INIT_SELTD 0x01
292 #define LEVEL2_TAR 0x02
294 enum scam_id_st { ID0, ID1, ID2, ID3, ID4, ID5, ID6, ID7, ID8, ID9, ID10, ID11,
296 ID13, ID14, ID15, ID_UNUSED, ID_UNASSIGNED, ID_ASSIGNED, LEGACY,
297 CLR_PRIORITY, NO_ID_AVAIL
300 typedef struct SCCBscam_info {
302 unsigned char id_string[ID_STRING_LENGTH];
303 enum scam_id_st state;
307 #define SCSI_REQUEST_SENSE 0x03
308 #define SCSI_READ 0x08
309 #define SCSI_WRITE 0x0A
310 #define SCSI_START_STOP_UNIT 0x1B
311 #define SCSI_READ_EXTENDED 0x28
312 #define SCSI_WRITE_EXTENDED 0x2A
313 #define SCSI_WRITE_AND_VERIFY 0x2E
317 #define SSQ_FULL 0x28
319 #define SMCMD_COMP 0x00
321 #define SMSAVE_DATA_PTR 0x02
322 #define SMREST_DATA_PTR 0x03
325 #define SMREJECT 0x07
327 #define SMPARITY 0x09
328 #define SMDEV_RESET 0x0C
329 #define SMABORT_TAG 0x0D
330 #define SMINIT_RECOVERY 0x0F
331 #define SMREL_RECOVERY 0x10
334 #define DISC_PRIV 0x40
340 #define SMIGNORWR 0x23 /* Ignore Wide Residue */
342 #define SIX_BYTE_CMD 0x06
343 #define TWELVE_BYTE_CMD 0x0C
346 #define MAX_OFFSET 0x0F /* Maxbyteoffset for Sync Xfers */
348 #define EEPROM_WD_CNT 256
350 #define EEPROM_CHECK_SUM 0
351 #define FW_SIGNATURE 2
352 #define MODEL_NUMB_0 4
353 #define MODEL_NUMB_2 6
354 #define MODEL_NUMB_4 8
355 #define SYSTEM_CONFIG 16
356 #define SCSI_CONFIG 17
357 #define BIOS_CONFIG 18
358 #define SCAM_CONFIG 20
359 #define ADAPTER_SCSI_ID 24
361 #define IGNORE_B_SCAN 32
362 #define SEND_START_ENA 34
363 #define DEVICE_ENABLE 36
365 #define SYNC_RATE_TBL 38
366 #define SYNC_RATE_TBL01 38
367 #define SYNC_RATE_TBL23 40
368 #define SYNC_RATE_TBL45 42
369 #define SYNC_RATE_TBL67 44
370 #define SYNC_RATE_TBL89 46
371 #define SYNC_RATE_TBLab 48
372 #define SYNC_RATE_TBLcd 50
373 #define SYNC_RATE_TBLef 52
375 #define EE_SCAMBASE 256
377 #define SCAM_ENABLED BIT(2)
378 #define SCAM_LEVEL2 BIT(3)
380 #define RENEGO_ENA BIT(10)
381 #define CONNIO_ENA BIT(11)
382 #define GREEN_PC_ENA BIT(12)
384 #define AUTO_RATE_00 00
385 #define AUTO_RATE_05 01
386 #define AUTO_RATE_10 02
387 #define AUTO_RATE_20 03
389 #define WIDE_NEGO_BIT BIT(7)
390 #define DISC_ENABLE_BIT BIT(6)
392 #define hp_vendor_id_0 0x00 /* LSB */
393 #define ORION_VEND_0 0x4B
395 #define hp_vendor_id_1 0x01 /* MSB */
396 #define ORION_VEND_1 0x10
398 #define hp_device_id_0 0x02 /* LSB */
399 #define ORION_DEV_0 0x30
401 #define hp_device_id_1 0x03 /* MSB */
402 #define ORION_DEV_1 0x81
404 /* Sub Vendor ID and Sub Device ID only available in
405 Harpoon Version 2 and higher */
407 #define hp_sub_device_id_0 0x06 /* LSB */
409 #define hp_semaphore 0x0C
410 #define SCCB_MGR_ACTIVE BIT(0)
411 #define TICKLE_ME BIT(1)
412 #define SCCB_MGR_PRESENT BIT(3)
413 #define BIOS_IN_USE BIT(4)
415 #define hp_sys_ctrl 0x0F
417 #define STOP_CLK BIT(0) /*Turn off BusMaster Clock */
418 #define DRVR_RST BIT(1) /*Firmware Reset to 80C15 chip */
419 #define HALT_MACH BIT(3) /*Halt State Machine */
420 #define HARD_ABORT BIT(4) /*Hard Abort */
422 #define hp_host_blk_cnt 0x13
424 #define XFER_BLK64 0x06 /* 1 1 0 64 byte per block */
426 #define BM_THRESHOLD 0x40 /* PCI mode can only xfer 16 bytes */
428 #define hp_int_mask 0x17
430 #define INT_CMD_COMPL BIT(0) /* DMA command complete */
431 #define INT_EXT_STATUS BIT(1) /* Extended Status Set */
433 #define hp_xfer_cnt_lo 0x18
434 #define hp_xfer_cnt_hi 0x1A
435 #define hp_xfer_cmd 0x1B
437 #define XFER_HOST_DMA 0x00 /* 0 0 0 Transfer Host -> DMA */
438 #define XFER_DMA_HOST 0x01 /* 0 0 1 Transfer DMA -> Host */
440 #define XFER_HOST_AUTO 0x00 /* 0 0 Auto Transfer Size */
442 #define XFER_DMA_8BIT 0x20 /* 0 1 8 BIT Transfer Size */
444 #define DISABLE_INT BIT(7) /*Do not interrupt at end of cmd. */
446 #define HOST_WRT_CMD ((DISABLE_INT + XFER_HOST_DMA + XFER_HOST_AUTO + XFER_DMA_8BIT))
447 #define HOST_RD_CMD ((DISABLE_INT + XFER_DMA_HOST + XFER_HOST_AUTO + XFER_DMA_8BIT))
449 #define hp_host_addr_lo 0x1C
450 #define hp_host_addr_hmi 0x1E
452 #define hp_ee_ctrl 0x22
454 #define EXT_ARB_ACK BIT(7)
455 #define SCSI_TERM_ENA_H BIT(6) /* SCSI high byte terminator */
456 #define SEE_MS BIT(5)
457 #define SEE_CS BIT(3)
458 #define SEE_CLK BIT(2)
459 #define SEE_DO BIT(1)
460 #define SEE_DI BIT(0)
463 #define EE_WRITE 0x05
465 #define EWEN_ADDR 0x03C0
467 #define EWDS_ADDR 0x0000
469 #define hp_bm_ctrl 0x26
471 #define SCSI_TERM_ENA_L BIT(0) /*Enable/Disable external terminators */
472 #define FLUSH_XFER_CNTR BIT(1) /*Flush transfer counter */
473 #define FORCE1_XFER BIT(5) /*Always xfer one byte in byte mode */
474 #define FAST_SINGLE BIT(6) /*?? */
476 #define BMCTRL_DEFAULT (FORCE1_XFER|FAST_SINGLE|SCSI_TERM_ENA_L)
478 #define hp_sg_addr 0x28
479 #define hp_page_ctrl 0x29
481 #define SCATTER_EN BIT(0)
482 #define SGRAM_ARAM BIT(1)
483 #define G_INT_DISABLE BIT(3) /* Enable/Disable all Interrupts */
484 #define NARROW_SCSI_CARD BIT(4) /* NARROW/WIDE SCSI config pin */
486 #define hp_pci_stat_cfg 0x2D
488 #define REC_MASTER_ABORT BIT(5) /*received Master abort */
490 #define hp_rev_num 0x33
492 #define hp_stack_data 0x34
493 #define hp_stack_addr 0x35
495 #define hp_ext_status 0x36
497 #define BM_FORCE_OFF BIT(0) /*Bus Master is forced to get off */
498 #define PCI_TGT_ABORT BIT(0) /*PCI bus master transaction aborted */
499 #define PCI_DEV_TMOUT BIT(1) /*PCI Device Time out */
500 #define CMD_ABORTED BIT(4) /*Command aborted */
501 #define BM_PARITY_ERR BIT(5) /*parity error on data received */
502 #define PIO_OVERRUN BIT(6) /*Slave data overrun */
503 #define BM_CMD_BUSY BIT(7) /*Bus master transfer command busy */
504 #define BAD_EXT_STATUS (BM_FORCE_OFF | PCI_DEV_TMOUT | CMD_ABORTED | \
505 BM_PARITY_ERR | PIO_OVERRUN)
507 #define hp_int_status 0x37
509 #define EXT_STATUS_ON BIT(1) /*Extended status is valid */
510 #define SCSI_INTERRUPT BIT(2) /*Global indication of a SCSI int. */
511 #define INT_ASSERTED BIT(5) /* */
513 #define hp_fifo_cnt 0x38
515 #define hp_intena 0x40
518 #define PROG_HLT BIT(6)
519 #define PARITY BIT(5)
522 #define SCAM_SEL BIT(2)
524 #define TIMEOUT BIT(0)
525 #define BUS_FREE BIT(15)
526 #define XFER_CNT_0 BIT(14)
527 #define PHASE BIT(13)
528 #define IUNKWN BIT(12)
529 #define ICMD_COMP BIT(11)
530 #define ITICKLE BIT(10)
531 #define IDO_STRT BIT(9)
532 #define ITAR_DISC BIT(8)
533 #define AUTO_INT (BIT(12)+BIT(11)+BIT(10)+BIT(9)+BIT(8))
534 #define CLR_ALL_INT 0xFFFF
535 #define CLR_ALL_INT_1 0xFF00
537 #define hp_intstat 0x42
539 #define hp_scsisig 0x44
541 #define SCSI_SEL BIT(7)
542 #define SCSI_BSY BIT(6)
543 #define SCSI_REQ BIT(5)
544 #define SCSI_ACK BIT(4)
545 #define SCSI_ATN BIT(3)
546 #define SCSI_CD BIT(2)
547 #define SCSI_MSG BIT(1)
548 #define SCSI_IOBIT BIT(0)
550 #define S_SCSI_PHZ (BIT(2)+BIT(1)+BIT(0))
551 #define S_MSGO_PH (BIT(2)+BIT(1) )
552 #define S_MSGI_PH (BIT(2)+BIT(1)+BIT(0))
553 #define S_DATAI_PH ( BIT(0))
554 #define S_DATAO_PH 0x00
555 #define S_ILL_PH ( BIT(1) )
557 #define hp_scsictrl_0 0x45
559 #define SEL_TAR BIT(6)
560 #define ENA_ATN BIT(4)
561 #define ENA_RESEL BIT(2)
562 #define SCSI_RST BIT(1)
563 #define ENA_SCAM_SEL BIT(0)
565 #define hp_portctrl_0 0x46
567 #define SCSI_PORT BIT(7)
568 #define SCSI_INBIT BIT(6)
569 #define DMA_PORT BIT(5)
570 #define DMA_RD BIT(4)
571 #define HOST_PORT BIT(3)
572 #define HOST_WRT BIT(2)
573 #define SCSI_BUS_EN BIT(1)
574 #define START_TO BIT(0)
576 #define hp_scsireset 0x47
578 #define SCSI_INI BIT(6)
579 #define SCAM_EN BIT(5)
580 #define DMA_RESET BIT(3)
581 #define HPSCSI_RESET BIT(2)
582 #define PROG_RESET BIT(1)
583 #define FIFO_CLR BIT(0)
585 #define hp_xfercnt_0 0x48
586 #define hp_xfercnt_2 0x4A
588 #define hp_fifodata_0 0x4C
589 #define hp_addstat 0x4E
591 #define SCAM_TIMER BIT(7)
592 #define SCSI_MODE8 BIT(3)
593 #define SCSI_PAR_ERR BIT(0)
595 #define hp_prgmcnt_0 0x4F
597 #define hp_selfid_0 0x50
598 #define hp_selfid_1 0x51
599 #define hp_arb_id 0x52
601 #define hp_select_id 0x53
603 #define hp_synctarg_base 0x54
604 #define hp_synctarg_12 0x54
605 #define hp_synctarg_13 0x55
606 #define hp_synctarg_14 0x56
607 #define hp_synctarg_15 0x57
609 #define hp_synctarg_8 0x58
610 #define hp_synctarg_9 0x59
611 #define hp_synctarg_10 0x5A
612 #define hp_synctarg_11 0x5B
614 #define hp_synctarg_4 0x5C
615 #define hp_synctarg_5 0x5D
616 #define hp_synctarg_6 0x5E
617 #define hp_synctarg_7 0x5F
619 #define hp_synctarg_0 0x60
620 #define hp_synctarg_1 0x61
621 #define hp_synctarg_2 0x62
622 #define hp_synctarg_3 0x63
624 #define NARROW_SCSI BIT(4)
625 #define DEFAULT_OFFSET 0x0F
627 #define hp_autostart_0 0x64
628 #define hp_autostart_1 0x65
629 #define hp_autostart_3 0x67
631 #define AUTO_IMMED BIT(5)
632 #define SELECT BIT(6)
633 #define END_DATA (BIT(7)+BIT(6))
635 #define hp_gp_reg_0 0x68
636 #define hp_gp_reg_1 0x69
637 #define hp_gp_reg_3 0x6B
639 #define hp_seltimeout 0x6C
641 #define TO_4ms 0x67 /* 3.9959ms */
643 #define TO_5ms 0x03 /* 4.9152ms */
644 #define TO_10ms 0x07 /* 11.xxxms */
645 #define TO_250ms 0x99 /* 250.68ms */
646 #define TO_290ms 0xB1 /* 289.99ms */
648 #define hp_clkctrl_0 0x6D
650 #define PWR_DWN BIT(6)
651 #define ACTdeassert BIT(4)
652 #define CLK_40MHZ (BIT(1) + BIT(0))
654 #define CLKCTRL_DEFAULT (ACTdeassert | CLK_40MHZ)
656 #define hp_fiforead 0x6E
657 #define hp_fifowrite 0x6F
659 #define hp_offsetctr 0x70
660 #define hp_xferstat 0x71
662 #define FIFO_EMPTY BIT(6)
664 #define hp_portctrl_1 0x72
666 #define CHK_SCSI_P BIT(3)
667 #define HOST_MODE8 BIT(0)
669 #define hp_xfer_pad 0x73
671 #define ID_UNLOCK BIT(3)
673 #define hp_scsidata_0 0x74
674 #define hp_scsidata_1 0x75
676 #define hp_aramBase 0x80
677 #define BIOS_DATA_OFFSET 0x60
678 #define BIOS_RELATIVE_CARD 0x64
680 #define AR3 (BIT(9) + BIT(8))
681 #define SDATA BIT(10)
683 #define CRD_OP BIT(11) /* Cmp Reg. w/ Data */
685 #define CRR_OP BIT(12) /* Cmp Reg. w. Reg. */
687 #define CPE_OP (BIT(14)+BIT(11)) /* Cmp SCSI phs & Branch EQ */
689 #define CPN_OP (BIT(14)+BIT(12)) /* Cmp SCSI phs & Branch NOT EQ */
691 #define ADATA_OUT 0x00
692 #define ADATA_IN BIT(8)
693 #define ACOMMAND BIT(10)
694 #define ASTATUS (BIT(10)+BIT(8))
695 #define AMSG_OUT (BIT(10)+BIT(9))
696 #define AMSG_IN (BIT(10)+BIT(9)+BIT(8))
698 #define BRH_OP BIT(13) /* Branch */
702 #define NOT_EQ BIT(9)
704 #define TCB_OP (BIT(13)+BIT(11)) /* Test condition & branch */
706 #define FIFO_0 BIT(10)
708 #define MPM_OP BIT(15) /* Match phase and move data */
710 #define MRR_OP BIT(14) /* Move DReg. to Reg. */
712 #define S_IDREG (BIT(2)+BIT(1)+BIT(0))
716 #define D_BUCKET (BIT(2) + BIT(1) + BIT(0))
718 #define RAT_OP (BIT(14)+BIT(13)+BIT(11))
720 #define SSI_OP (BIT(15)+BIT(11))
722 #define SSI_ITAR_DISC (ITAR_DISC >> 8)
723 #define SSI_IDO_STRT (IDO_STRT >> 8)
725 #define SSI_ICMD_COMP (ICMD_COMP >> 8)
726 #define SSI_ITICKLE (ITICKLE >> 8)
728 #define SSI_IUNKWN (IUNKWN >> 8)
729 #define SSI_INO_CC (IUNKWN >> 8)
730 #define SSI_IRFAIL (IUNKWN >> 8)
732 #define NP 0x10 /*Next Phase */
733 #define NTCMD 0x02 /*Non- Tagged Command start */
734 #define CMDPZ 0x04 /*Command phase */
735 #define DINT 0x12 /*Data Out/In interrupt */
736 #define DI 0x13 /*Data Out */
737 #define DC 0x19 /*Disconnect Message */
738 #define ST 0x1D /*Status Phase */
739 #define UNKNWN 0x24 /*Unknown bus action */
740 #define CC 0x25 /*Command Completion failure */
741 #define TICK 0x26 /*New target reselected us. */
742 #define SELCHK 0x28 /*Select & Check SCSI ID latch reg */
744 #define ID_MSG_STRT hp_aramBase + 0x00
745 #define NON_TAG_ID_MSG hp_aramBase + 0x06
746 #define CMD_STRT hp_aramBase + 0x08
747 #define SYNC_MSGS hp_aramBase + 0x08
749 #define TAG_STRT 0x00
750 #define DISCONNECT_START 0x10/2
751 #define END_DATA_START 0x14/2
752 #define CMD_ONLY_STRT CMDPZ/2
753 #define SELCHK_STRT SELCHK/2
755 #define GET_XFER_CNT(port, xfercnt) {RD_HARP32(port,hp_xfercnt_0,xfercnt); xfercnt &= 0xFFFFFF;}
756 /* #define GET_XFER_CNT(port, xfercnt) (xfercnt = RD_HARPOON(port+hp_xfercnt_2), \
758 xfercnt |= RDW_HARPOON((unsigned short)(port+hp_xfercnt_0)))
760 #define HP_SETUP_ADDR_CNT(port,addr,count) (WRW_HARPOON((port+hp_host_addr_lo), (unsigned short)(addr & 0x0000FFFFL)),\
762 WRW_HARPOON((port+hp_host_addr_hmi), (unsigned short)(addr & 0x0000FFFFL)),\
763 WR_HARP32(port,hp_xfercnt_0,count),\
764 WRW_HARPOON((port+hp_xfer_cnt_lo), (unsigned short)(count & 0x0000FFFFL)),\
766 WR_HARPOON(port+hp_xfer_cnt_hi, (count & 0xFF)))
768 #define ACCEPT_MSG(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
769 WR_HARPOON(port+hp_scsisig, S_ILL_PH);}
771 #define ACCEPT_MSG_ATN(port) {while(RD_HARPOON(port+hp_scsisig) & SCSI_REQ){}\
772 WR_HARPOON(port+hp_scsisig, (S_ILL_PH|SCSI_ATN));}
774 #define DISABLE_AUTO(port) (WR_HARPOON(port+hp_scsireset, PROG_RESET),\
775 WR_HARPOON(port+hp_scsireset, 0x00))
777 #define ARAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
778 (RD_HARPOON(p_port+hp_page_ctrl) | SGRAM_ARAM)))
780 #define SGRAM_ACCESS(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
781 (RD_HARPOON(p_port+hp_page_ctrl) & ~SGRAM_ARAM)))
783 #define MDISABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
784 (RD_HARPOON(p_port+hp_page_ctrl) | G_INT_DISABLE)))
786 #define MENABLE_INT(p_port) (WR_HARPOON(p_port+hp_page_ctrl, \
787 (RD_HARPOON(p_port+hp_page_ctrl) & ~G_INT_DISABLE)))
789 static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
790 unsigned char syncFlag);
791 static void FPT_ssel(u32 port, unsigned char p_card);
792 static void FPT_sres(u32 port, unsigned char p_card,
793 struct sccb_card *pCurrCard);
794 static void FPT_shandem(u32 port, unsigned char p_card,
795 struct sccb *pCurrSCCB);
796 static void FPT_stsyncn(u32 port, unsigned char p_card);
797 static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
798 unsigned char offset);
799 static void FPT_sssyncv(u32 p_port, unsigned char p_id,
800 unsigned char p_sync_value,
801 struct sccb_mgr_tar_info *currTar_Info);
802 static void FPT_sresb(u32 port, unsigned char p_card);
803 static void FPT_sxfrp(u32 p_port, unsigned char p_card);
804 static void FPT_schkdd(u32 port, unsigned char p_card);
805 static unsigned char FPT_RdStack(u32 port, unsigned char index);
806 static void FPT_WrStack(u32 portBase, unsigned char index,
808 static unsigned char FPT_ChkIfChipInitialized(u32 ioPort);
810 static void FPT_SendMsg(u32 port, unsigned char message);
811 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
812 unsigned char error_code);
814 static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card);
815 static void FPT_RNVRamData(struct nvram_info *pNvRamInfo);
817 static unsigned char FPT_siwidn(u32 port, unsigned char p_card);
818 static void FPT_stwidn(u32 port, unsigned char p_card);
819 static void FPT_siwidr(u32 port, unsigned char width);
821 static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
822 unsigned char p_card);
823 static void FPT_queueDisconnect(struct sccb *p_SCCB, unsigned char p_card);
824 static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
825 struct sccb *p_SCCB, unsigned char p_card);
826 static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
827 unsigned char p_card);
828 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code);
829 static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char card);
830 static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
831 unsigned char p_card);
832 static void FPT_utilUpdateResidual(struct sccb *p_SCCB);
833 static unsigned short FPT_CalcCrc16(unsigned char buffer[]);
834 static unsigned char FPT_CalcLrc(unsigned char buffer[]);
836 static void FPT_Wait1Second(u32 p_port);
837 static void FPT_Wait(u32 p_port, unsigned char p_delay);
838 static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode);
839 static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
840 unsigned short ee_addr);
841 static unsigned short FPT_utilEERead(u32 p_port,
842 unsigned short ee_addr);
843 static unsigned short FPT_utilEEReadOrg(u32 p_port,
844 unsigned short ee_addr);
845 static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
846 unsigned short ee_addr);
848 static void FPT_phaseDataOut(u32 port, unsigned char p_card);
849 static void FPT_phaseDataIn(u32 port, unsigned char p_card);
850 static void FPT_phaseCommand(u32 port, unsigned char p_card);
851 static void FPT_phaseStatus(u32 port, unsigned char p_card);
852 static void FPT_phaseMsgOut(u32 port, unsigned char p_card);
853 static void FPT_phaseMsgIn(u32 port, unsigned char p_card);
854 static void FPT_phaseIllegal(u32 port, unsigned char p_card);
856 static void FPT_phaseDecode(u32 port, unsigned char p_card);
857 static void FPT_phaseChkFifo(u32 port, unsigned char p_card);
858 static void FPT_phaseBusFree(u32 p_port, unsigned char p_card);
860 static void FPT_XbowInit(u32 port, unsigned char scamFlg);
861 static void FPT_BusMasterInit(u32 p_port);
862 static void FPT_DiagEEPROM(u32 p_port);
864 static void FPT_dataXferProcessor(u32 port,
865 struct sccb_card *pCurrCard);
866 static void FPT_busMstrSGDataXferStart(u32 port,
867 struct sccb *pCurrSCCB);
868 static void FPT_busMstrDataXferStart(u32 port,
869 struct sccb *pCurrSCCB);
870 static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
871 struct sccb *pCurrSCCB);
872 static void FPT_hostDataXferRestart(struct sccb *currSCCB);
874 static unsigned char FPT_SccbMgr_bad_isr(u32 p_port,
875 unsigned char p_card,
876 struct sccb_card *pCurrCard,
877 unsigned short p_int);
879 static void FPT_SccbMgrTableInitAll(void);
880 static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
881 unsigned char p_card);
882 static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
883 unsigned char target);
885 static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
886 unsigned char p_power_up);
888 static int FPT_scarb(u32 p_port, unsigned char p_sel_type);
889 static void FPT_scbusf(u32 p_port);
890 static void FPT_scsel(u32 p_port);
891 static void FPT_scasid(unsigned char p_card, u32 p_port);
892 static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data);
893 static unsigned char FPT_scsendi(u32 p_port,
894 unsigned char p_id_string[]);
895 static unsigned char FPT_sciso(u32 p_port,
896 unsigned char p_id_string[]);
897 static void FPT_scwirod(u32 p_port, unsigned char p_data_bit);
898 static void FPT_scwiros(u32 p_port, unsigned char p_data_bit);
899 static unsigned char FPT_scvalq(unsigned char p_quintet);
900 static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id);
901 static void FPT_scwtsel(u32 p_port);
902 static void FPT_inisci(unsigned char p_card, u32 p_port,
903 unsigned char p_our_id);
904 static void FPT_scsavdi(unsigned char p_card, u32 p_port);
905 static unsigned char FPT_scmachid(unsigned char p_card,
906 unsigned char p_id_string[]);
908 static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card);
909 static void FPT_autoLoadDefaultMap(u32 p_port);
911 static struct sccb_mgr_tar_info FPT_sccbMgrTbl[MAX_CARDS][MAX_SCSI_TAR] =
913 static struct sccb_card FPT_BL_Card[MAX_CARDS] = { {0} };
914 static SCCBSCAM_INFO FPT_scamInfo[MAX_SCSI_TAR] = { {{0}} };
915 static struct nvram_info FPT_nvRamInfo[MAX_MB_CARDS] = { {0} };
917 static unsigned char FPT_mbCards = 0;
918 static unsigned char FPT_scamHAString[] =
919 { 0x63, 0x07, 'B', 'U', 'S', 'L', 'O', 'G', 'I', 'C',
920 ' ', 'B', 'T', '-', '9', '3', '0',
921 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
922 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
925 static unsigned short FPT_default_intena = 0;
927 static void (*FPT_s_PhaseTbl[8]) (u32, unsigned char) = {
930 /*---------------------------------------------------------------------
932 * Function: FlashPoint_ProbeHostAdapter
934 * Description: Setup and/or Search for cards and return info to caller.
936 *---------------------------------------------------------------------*/
938 static int FlashPoint_ProbeHostAdapter(struct sccb_mgr_info *pCardInfo)
940 static unsigned char first_time = 1;
942 unsigned char i, j, id, ScamFlg;
943 unsigned short temp, temp2, temp3, temp4, temp5, temp6;
945 struct nvram_info *pCurrNvRam;
947 ioport = pCardInfo->si_baseaddr;
949 if (RD_HARPOON(ioport + hp_vendor_id_0) != ORION_VEND_0)
952 if ((RD_HARPOON(ioport + hp_vendor_id_1) != ORION_VEND_1))
955 if ((RD_HARPOON(ioport + hp_device_id_0) != ORION_DEV_0))
958 if ((RD_HARPOON(ioport + hp_device_id_1) != ORION_DEV_1))
961 if (RD_HARPOON(ioport + hp_rev_num) != 0x0f) {
963 /* For new Harpoon then check for sub_device ID LSB
964 the bits(0-3) must be all ZERO for compatible with
965 current version of SCCBMgr, else skip this Harpoon
968 if (RD_HARPOON(ioport + hp_sub_device_id_0) & 0x0f)
973 FPT_SccbMgrTableInitAll();
978 if (FPT_RdStack(ioport, 0) != 0x00) {
979 if (FPT_ChkIfChipInitialized(ioport) == 0) {
981 WR_HARPOON(ioport + hp_semaphore, 0x00);
982 FPT_XbowInit(ioport, 0); /*Must Init the SCSI before attempting */
983 FPT_DiagEEPROM(ioport);
985 if (FPT_mbCards < MAX_MB_CARDS) {
986 pCurrNvRam = &FPT_nvRamInfo[FPT_mbCards];
988 pCurrNvRam->niBaseAddr = ioport;
989 FPT_RNVRamData(pCurrNvRam);
996 WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
997 WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
1000 pCardInfo->si_id = pCurrNvRam->niAdapId;
1004 char)(FPT_utilEERead(ioport,
1006 2)) & (unsigned char)0x0FF);
1008 pCardInfo->si_lun = 0x00;
1009 pCardInfo->si_fw_revision = ORION_FW_REV;
1016 for (id = 0; id < (16 / 2); id++) {
1019 temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
1020 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1021 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1024 FPT_utilEERead(ioport,
1025 (unsigned short)((SYNC_RATE_TBL / 2)
1028 for (i = 0; i < 2; temp >>= 8, i++) {
1035 switch (temp & 0x3) {
1036 case AUTO_RATE_20: /* Synchronous, 20 mega-transfers/second */
1039 case AUTO_RATE_10: /* Synchronous, 10 mega-transfers/second */
1042 case AUTO_RATE_05: /* Synchronous, 5 mega-transfers/second */
1045 case AUTO_RATE_00: /* Asynchronous */
1049 if (temp & DISC_ENABLE_BIT)
1052 if (temp & WIDE_NEGO_BIT)
1058 pCardInfo->si_per_targ_init_sync = temp2;
1059 pCardInfo->si_per_targ_no_disc = temp3;
1060 pCardInfo->si_per_targ_wide_nego = temp4;
1061 pCardInfo->si_per_targ_fast_nego = temp5;
1062 pCardInfo->si_per_targ_ultra_nego = temp6;
1065 i = pCurrNvRam->niSysConf;
1068 char)(FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)));
1071 ScamFlg = pCurrNvRam->niScamConf;
1074 (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1076 pCardInfo->si_flags = 0x0000;
1079 pCardInfo->si_flags |= SCSI_PARITY_ENA;
1082 pCardInfo->si_flags |= SOFT_RESET;
1085 pCardInfo->si_flags |= EXTENDED_TRANSLATION;
1087 if (ScamFlg & SCAM_ENABLED)
1088 pCardInfo->si_flags |= FLAG_SCAM_ENABLED;
1090 if (ScamFlg & SCAM_LEVEL2)
1091 pCardInfo->si_flags |= FLAG_SCAM_LEVEL2;
1093 j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1095 j |= SCSI_TERM_ENA_L;
1097 WR_HARPOON(ioport + hp_bm_ctrl, j);
1099 j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1101 j |= SCSI_TERM_ENA_H;
1103 WR_HARPOON(ioport + hp_ee_ctrl, j);
1105 if (!(RD_HARPOON(ioport + hp_page_ctrl) & NARROW_SCSI_CARD))
1107 pCardInfo->si_flags |= SUPPORT_16TAR_32LUN;
1109 pCardInfo->si_card_family = HARPOON_FAMILY;
1110 pCardInfo->si_bustype = BUSTYPE_PCI;
1113 pCardInfo->si_card_model[0] = '9';
1114 switch (pCurrNvRam->niModel & 0x0f) {
1116 pCardInfo->si_card_model[1] = '3';
1117 pCardInfo->si_card_model[2] = '0';
1120 pCardInfo->si_card_model[1] = '5';
1121 pCardInfo->si_card_model[2] = '0';
1124 pCardInfo->si_card_model[1] = '3';
1125 pCardInfo->si_card_model[2] = '2';
1128 pCardInfo->si_card_model[1] = '5';
1129 pCardInfo->si_card_model[2] = '2';
1133 temp = FPT_utilEERead(ioport, (MODEL_NUMB_0 / 2));
1134 pCardInfo->si_card_model[0] = (unsigned char)(temp >> 8);
1135 temp = FPT_utilEERead(ioport, (MODEL_NUMB_2 / 2));
1137 pCardInfo->si_card_model[1] = (unsigned char)(temp & 0x00FF);
1138 pCardInfo->si_card_model[2] = (unsigned char)(temp >> 8);
1141 if (pCardInfo->si_card_model[1] == '3') {
1142 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1143 pCardInfo->si_flags |= LOW_BYTE_TERM;
1144 } else if (pCardInfo->si_card_model[2] == '0') {
1145 temp = RD_HARPOON(ioport + hp_xfer_pad);
1146 WR_HARPOON(ioport + hp_xfer_pad, (temp & ~BIT(4)));
1147 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1148 pCardInfo->si_flags |= LOW_BYTE_TERM;
1149 WR_HARPOON(ioport + hp_xfer_pad, (temp | BIT(4)));
1150 if (RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7))
1151 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1152 WR_HARPOON(ioport + hp_xfer_pad, temp);
1154 temp = RD_HARPOON(ioport + hp_ee_ctrl);
1155 temp2 = RD_HARPOON(ioport + hp_xfer_pad);
1156 WR_HARPOON(ioport + hp_ee_ctrl, (temp | SEE_CS));
1157 WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1159 for (i = 0; i < 8; i++) {
1161 if (!(RD_HARPOON(ioport + hp_ee_ctrl) & BIT(7)))
1163 WR_HARPOON(ioport + hp_xfer_pad, (temp2 & ~BIT(4)));
1164 WR_HARPOON(ioport + hp_xfer_pad, (temp2 | BIT(4)));
1166 WR_HARPOON(ioport + hp_ee_ctrl, temp);
1167 WR_HARPOON(ioport + hp_xfer_pad, temp2);
1168 if (!(temp3 & BIT(7)))
1169 pCardInfo->si_flags |= LOW_BYTE_TERM;
1170 if (!(temp3 & BIT(6)))
1171 pCardInfo->si_flags |= HIGH_BYTE_TERM;
1174 ARAM_ACCESS(ioport);
1176 for (i = 0; i < 4; i++) {
1178 pCardInfo->si_XlatInfo[i] =
1179 RD_HARPOON(ioport + hp_aramBase + BIOS_DATA_OFFSET + i);
1182 /* return with -1 if no sort, else return with
1183 logical card number sorted by BIOS (zero-based) */
1185 pCardInfo->si_relative_cardnum =
1187 char)(RD_HARPOON(ioport + hp_aramBase + BIOS_RELATIVE_CARD) - 1);
1189 SGRAM_ACCESS(ioport);
1191 FPT_s_PhaseTbl[0] = FPT_phaseDataOut;
1192 FPT_s_PhaseTbl[1] = FPT_phaseDataIn;
1193 FPT_s_PhaseTbl[2] = FPT_phaseIllegal;
1194 FPT_s_PhaseTbl[3] = FPT_phaseIllegal;
1195 FPT_s_PhaseTbl[4] = FPT_phaseCommand;
1196 FPT_s_PhaseTbl[5] = FPT_phaseStatus;
1197 FPT_s_PhaseTbl[6] = FPT_phaseMsgOut;
1198 FPT_s_PhaseTbl[7] = FPT_phaseMsgIn;
1200 pCardInfo->si_present = 0x01;
1205 /*---------------------------------------------------------------------
1207 * Function: FlashPoint_HardwareResetHostAdapter
1209 * Description: Setup adapter for normal operation (hard reset).
1211 *---------------------------------------------------------------------*/
1213 static void *FlashPoint_HardwareResetHostAdapter(struct sccb_mgr_info
1216 struct sccb_card *CurrCard = NULL;
1217 struct nvram_info *pCurrNvRam;
1218 unsigned char i, j, thisCard, ScamFlg;
1219 unsigned short temp, sync_bit_map, id;
1222 ioport = pCardInfo->si_baseaddr;
1224 for (thisCard = 0; thisCard <= MAX_CARDS; thisCard++) {
1226 if (thisCard == MAX_CARDS)
1227 return (void *)FAILURE;
1229 if (FPT_BL_Card[thisCard].ioPort == ioport) {
1231 CurrCard = &FPT_BL_Card[thisCard];
1232 FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1236 else if (FPT_BL_Card[thisCard].ioPort == 0x00) {
1238 FPT_BL_Card[thisCard].ioPort = ioport;
1239 CurrCard = &FPT_BL_Card[thisCard];
1242 for (i = 0; i < FPT_mbCards; i++) {
1243 if (CurrCard->ioPort ==
1244 FPT_nvRamInfo[i].niBaseAddr)
1245 CurrCard->pNvRamInfo =
1248 FPT_SccbMgrTableInitCard(CurrCard, thisCard);
1249 CurrCard->cardIndex = thisCard;
1250 CurrCard->cardInfo = pCardInfo;
1256 pCurrNvRam = CurrCard->pNvRamInfo;
1259 ScamFlg = pCurrNvRam->niScamConf;
1262 (unsigned char)FPT_utilEERead(ioport, SCAM_CONFIG / 2);
1265 FPT_BusMasterInit(ioport);
1266 FPT_XbowInit(ioport, ScamFlg);
1268 FPT_autoLoadDefaultMap(ioport);
1270 for (i = 0, id = 0x01; i != pCardInfo->si_id; i++, id <<= 1) {
1273 WR_HARPOON(ioport + hp_selfid_0, id);
1274 WR_HARPOON(ioport + hp_selfid_1, 0x00);
1275 WR_HARPOON(ioport + hp_arb_id, pCardInfo->si_id);
1276 CurrCard->ourId = pCardInfo->si_id;
1278 i = (unsigned char)pCardInfo->si_flags;
1279 if (i & SCSI_PARITY_ENA)
1280 WR_HARPOON(ioport + hp_portctrl_1, (HOST_MODE8 | CHK_SCSI_P));
1282 j = (RD_HARPOON(ioport + hp_bm_ctrl) & ~SCSI_TERM_ENA_L);
1283 if (i & LOW_BYTE_TERM)
1284 j |= SCSI_TERM_ENA_L;
1285 WR_HARPOON(ioport + hp_bm_ctrl, j);
1287 j = (RD_HARPOON(ioport + hp_ee_ctrl) & ~SCSI_TERM_ENA_H);
1288 if (i & HIGH_BYTE_TERM)
1289 j |= SCSI_TERM_ENA_H;
1290 WR_HARPOON(ioport + hp_ee_ctrl, j);
1292 if (!(pCardInfo->si_flags & SOFT_RESET)) {
1294 FPT_sresb(ioport, thisCard);
1296 FPT_scini(thisCard, pCardInfo->si_id, 0);
1299 if (pCardInfo->si_flags & POST_ALL_UNDERRRUNS)
1300 CurrCard->globalFlags |= F_NO_FILTER;
1303 if (pCurrNvRam->niSysConf & 0x10)
1304 CurrCard->globalFlags |= F_GREEN_PC;
1306 if (FPT_utilEERead(ioport, (SYSTEM_CONFIG / 2)) & GREEN_PC_ENA)
1307 CurrCard->globalFlags |= F_GREEN_PC;
1310 /* Set global flag to indicate Re-Negotiation to be done on all
1313 if (pCurrNvRam->niScsiConf & 0x04)
1314 CurrCard->globalFlags |= F_DO_RENEGO;
1316 if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & RENEGO_ENA)
1317 CurrCard->globalFlags |= F_DO_RENEGO;
1321 if (pCurrNvRam->niScsiConf & 0x08)
1322 CurrCard->globalFlags |= F_CONLUN_IO;
1324 if (FPT_utilEERead(ioport, (SCSI_CONFIG / 2)) & CONNIO_ENA)
1325 CurrCard->globalFlags |= F_CONLUN_IO;
1328 temp = pCardInfo->si_per_targ_no_disc;
1330 for (i = 0, id = 1; i < MAX_SCSI_TAR; i++, id <<= 1) {
1333 FPT_sccbMgrTbl[thisCard][i].TarStatus |= TAR_ALLOW_DISC;
1336 sync_bit_map = 0x0001;
1338 for (id = 0; id < (MAX_SCSI_TAR / 2); id++) {
1341 temp = (unsigned short)pCurrNvRam->niSyncTbl[id];
1342 temp = ((temp & 0x03) + ((temp << 4) & 0xc0)) +
1343 (((temp << 4) & 0x0300) + ((temp << 8) & 0xc000));
1346 FPT_utilEERead(ioport,
1347 (unsigned short)((SYNC_RATE_TBL / 2)
1350 for (i = 0; i < 2; temp >>= 8, i++) {
1352 if (pCardInfo->si_per_targ_init_sync & sync_bit_map) {
1354 FPT_sccbMgrTbl[thisCard][id * 2 +
1356 (unsigned char)temp;
1360 FPT_sccbMgrTbl[thisCard][id * 2 +
1363 FPT_sccbMgrTbl[thisCard][id * 2 +
1365 (unsigned char)(temp & ~EE_SYNC_MASK);
1368 /* if ((pCardInfo->si_per_targ_wide_nego & sync_bit_map) ||
1371 if (pCardInfo->si_per_targ_wide_nego & sync_bit_map) {
1373 FPT_sccbMgrTbl[thisCard][id * 2 +
1379 else { /* NARROW SCSI */
1380 FPT_sccbMgrTbl[thisCard][id * 2 +
1390 WR_HARPOON((ioport + hp_semaphore),
1391 (unsigned char)(RD_HARPOON((ioport + hp_semaphore)) |
1394 return (void *)CurrCard;
1397 static void FlashPoint_ReleaseHostAdapter(void *pCurrCard)
1404 struct nvram_info *pCurrNvRam;
1406 pCurrNvRam = ((struct sccb_card *)pCurrCard)->pNvRamInfo;
1409 FPT_WrStack(pCurrNvRam->niBaseAddr, 0, pCurrNvRam->niModel);
1410 FPT_WrStack(pCurrNvRam->niBaseAddr, 1, pCurrNvRam->niSysConf);
1411 FPT_WrStack(pCurrNvRam->niBaseAddr, 2, pCurrNvRam->niScsiConf);
1412 FPT_WrStack(pCurrNvRam->niBaseAddr, 3, pCurrNvRam->niScamConf);
1413 FPT_WrStack(pCurrNvRam->niBaseAddr, 4, pCurrNvRam->niAdapId);
1415 for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1416 FPT_WrStack(pCurrNvRam->niBaseAddr,
1417 (unsigned char)(i + 5),
1418 pCurrNvRam->niSyncTbl[i]);
1420 portBase = pCurrNvRam->niBaseAddr;
1422 for (i = 0; i < MAX_SCSI_TAR; i++) {
1423 regOffset = hp_aramBase + 64 + i * 4;
1424 pScamTbl = (u32 *)&pCurrNvRam->niScamTbl[i];
1425 scamData = *pScamTbl;
1426 WR_HARP32(portBase, regOffset, scamData);
1430 FPT_WrStack(((struct sccb_card *)pCurrCard)->ioPort, 0, 0);
1434 static void FPT_RNVRamData(struct nvram_info *pNvRamInfo)
1442 pNvRamInfo->niModel = FPT_RdStack(pNvRamInfo->niBaseAddr, 0);
1443 pNvRamInfo->niSysConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 1);
1444 pNvRamInfo->niScsiConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 2);
1445 pNvRamInfo->niScamConf = FPT_RdStack(pNvRamInfo->niBaseAddr, 3);
1446 pNvRamInfo->niAdapId = FPT_RdStack(pNvRamInfo->niBaseAddr, 4);
1448 for (i = 0; i < MAX_SCSI_TAR / 2; i++)
1449 pNvRamInfo->niSyncTbl[i] =
1450 FPT_RdStack(pNvRamInfo->niBaseAddr, (unsigned char)(i + 5));
1452 portBase = pNvRamInfo->niBaseAddr;
1454 for (i = 0; i < MAX_SCSI_TAR; i++) {
1455 regOffset = hp_aramBase + 64 + i * 4;
1456 RD_HARP32(portBase, regOffset, scamData);
1457 pScamTbl = (u32 *)&pNvRamInfo->niScamTbl[i];
1458 *pScamTbl = scamData;
1463 static unsigned char FPT_RdStack(u32 portBase, unsigned char index)
1465 WR_HARPOON(portBase + hp_stack_addr, index);
1466 return RD_HARPOON(portBase + hp_stack_data);
1469 static void FPT_WrStack(u32 portBase, unsigned char index, unsigned char data)
1471 WR_HARPOON(portBase + hp_stack_addr, index);
1472 WR_HARPOON(portBase + hp_stack_data, data);
1475 static unsigned char FPT_ChkIfChipInitialized(u32 ioPort)
1477 if ((RD_HARPOON(ioPort + hp_arb_id) & 0x0f) != FPT_RdStack(ioPort, 4))
1479 if ((RD_HARPOON(ioPort + hp_clkctrl_0) & CLKCTRL_DEFAULT)
1482 if ((RD_HARPOON(ioPort + hp_seltimeout) == TO_250ms) ||
1483 (RD_HARPOON(ioPort + hp_seltimeout) == TO_290ms))
1489 /*---------------------------------------------------------------------
1491 * Function: FlashPoint_StartCCB
1493 * Description: Start a command pointed to by p_Sccb. When the
1494 * command is completed it will be returned via the
1495 * callback function.
1497 *---------------------------------------------------------------------*/
1498 static void FlashPoint_StartCCB(void *curr_card, struct sccb *p_Sccb)
1501 unsigned char thisCard, lun;
1502 struct sccb *pSaveSccb;
1503 CALL_BK_FN callback;
1504 struct sccb_card *pCurrCard = curr_card;
1506 thisCard = pCurrCard->cardIndex;
1507 ioport = pCurrCard->ioPort;
1509 if ((p_Sccb->TargID >= MAX_SCSI_TAR) || (p_Sccb->Lun >= MAX_LUN)) {
1511 p_Sccb->HostStatus = SCCB_COMPLETE;
1512 p_Sccb->SccbStatus = SCCB_ERROR;
1513 callback = (CALL_BK_FN) p_Sccb->SccbCallback;
1520 FPT_sinits(p_Sccb, thisCard);
1522 if (!pCurrCard->cmdCounter) {
1523 WR_HARPOON(ioport + hp_semaphore,
1524 (RD_HARPOON(ioport + hp_semaphore)
1525 | SCCB_MGR_ACTIVE));
1527 if (pCurrCard->globalFlags & F_GREEN_PC) {
1528 WR_HARPOON(ioport + hp_clkctrl_0, CLKCTRL_DEFAULT);
1529 WR_HARPOON(ioport + hp_sys_ctrl, 0x00);
1533 pCurrCard->cmdCounter++;
1535 if (RD_HARPOON(ioport + hp_semaphore) & BIOS_IN_USE) {
1537 WR_HARPOON(ioport + hp_semaphore,
1538 (RD_HARPOON(ioport + hp_semaphore)
1540 if (p_Sccb->OperationCode == RESET_COMMAND) {
1542 pCurrCard->currentSCCB;
1543 pCurrCard->currentSCCB = p_Sccb;
1544 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1545 pCurrCard->currentSCCB =
1548 FPT_queueAddSccb(p_Sccb, thisCard);
1552 else if ((RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1554 if (p_Sccb->OperationCode == RESET_COMMAND) {
1556 pCurrCard->currentSCCB;
1557 pCurrCard->currentSCCB = p_Sccb;
1558 FPT_queueSelectFail(&FPT_BL_Card[thisCard], thisCard);
1559 pCurrCard->currentSCCB =
1562 FPT_queueAddSccb(p_Sccb, thisCard);
1568 MDISABLE_INT(ioport);
1570 if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
1571 ((FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].
1572 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
1576 if ((pCurrCard->currentSCCB == NULL) &&
1577 (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarSelQ_Cnt == 0)
1578 && (FPT_sccbMgrTbl[thisCard][p_Sccb->TargID].TarLUNBusy[lun]
1581 pCurrCard->currentSCCB = p_Sccb;
1582 FPT_ssel(p_Sccb->SccbIOPort, thisCard);
1587 if (p_Sccb->OperationCode == RESET_COMMAND) {
1588 pSaveSccb = pCurrCard->currentSCCB;
1589 pCurrCard->currentSCCB = p_Sccb;
1590 FPT_queueSelectFail(&FPT_BL_Card[thisCard],
1592 pCurrCard->currentSCCB = pSaveSccb;
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(void *pCurrCard, struct sccb *p_Sccb)
1616 unsigned char thisCard;
1617 CALL_BK_FN callback;
1618 struct sccb *pSaveSCCB;
1619 struct sccb_mgr_tar_info *currTar_Info;
1621 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1623 thisCard = ((struct sccb_card *)pCurrCard)->cardIndex;
1625 if (!(RD_HARPOON(ioport + hp_page_ctrl) & G_INT_DISABLE)) {
1627 if (FPT_queueFindSccb(p_Sccb, thisCard)) {
1629 ((struct sccb_card *)pCurrCard)->cmdCounter--;
1631 if (!((struct sccb_card *)pCurrCard)->cmdCounter)
1632 WR_HARPOON(ioport + hp_semaphore,
1633 (RD_HARPOON(ioport + hp_semaphore)
1635 char)(~(SCCB_MGR_ACTIVE |
1638 p_Sccb->SccbStatus = SCCB_ABORT;
1639 callback = p_Sccb->SccbCallback;
1646 if (((struct sccb_card *)pCurrCard)->currentSCCB ==
1648 p_Sccb->SccbStatus = SCCB_ABORT;
1654 if (p_Sccb->Sccb_tag) {
1655 MDISABLE_INT(ioport);
1656 if (((struct sccb_card *)pCurrCard)->
1657 discQ_Tbl[p_Sccb->Sccb_tag] ==
1659 p_Sccb->SccbStatus = SCCB_ABORT;
1660 p_Sccb->Sccb_scsistat =
1662 p_Sccb->Sccb_scsimsg =
1665 if (((struct sccb_card *)
1666 pCurrCard)->currentSCCB ==
1668 ((struct sccb_card *)
1670 currentSCCB = p_Sccb;
1678 ((struct sccb_card *)
1680 currentSCCB = p_Sccb;
1681 FPT_queueSelectFail((struct sccb_card *)pCurrCard, thisCard);
1682 ((struct sccb_card *)
1684 currentSCCB = pSaveSCCB;
1687 MENABLE_INT(ioport);
1691 &FPT_sccbMgrTbl[thisCard][p_Sccb->
1694 if (FPT_BL_Card[thisCard].
1695 discQ_Tbl[currTar_Info->
1696 LunDiscQ_Idx[p_Sccb->Lun]]
1698 p_Sccb->SccbStatus = SCCB_ABORT;
1708 /*---------------------------------------------------------------------
1710 * Function: FlashPoint_InterruptPending
1712 * Description: Do a quick check to determine if there is a pending
1713 * interrupt for this card and disable the IRQ Pin if so.
1715 *---------------------------------------------------------------------*/
1716 static unsigned char FlashPoint_InterruptPending(void *pCurrCard)
1720 ioport = ((struct sccb_card *)pCurrCard)->ioPort;
1722 if (RD_HARPOON(ioport + hp_int_status) & INT_ASSERTED) {
1731 /*---------------------------------------------------------------------
1733 * Function: FlashPoint_HandleInterrupt
1735 * Description: This is our entry point when an interrupt is generated
1736 * by the card and the upper level driver passes it on to
1739 *---------------------------------------------------------------------*/
1740 static int FlashPoint_HandleInterrupt(void *pcard)
1742 struct sccb *currSCCB;
1743 unsigned char thisCard, result, bm_status, bm_int_st;
1744 unsigned short hp_int;
1745 unsigned char i, target;
1746 struct sccb_card *pCurrCard = pcard;
1749 thisCard = pCurrCard->cardIndex;
1750 ioport = pCurrCard->ioPort;
1752 MDISABLE_INT(ioport);
1754 if ((bm_int_st = RD_HARPOON(ioport + hp_int_status)) & EXT_STATUS_ON)
1755 bm_status = RD_HARPOON(ioport + hp_ext_status) &
1756 (unsigned char)BAD_EXT_STATUS;
1760 WR_HARPOON(ioport + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
1762 while ((hp_int = RDW_HARPOON((ioport + hp_intstat)) &
1763 FPT_default_intena) | bm_status) {
1765 currSCCB = pCurrCard->currentSCCB;
1767 if (hp_int & (FIFO | TIMEOUT | RESET | SCAM_SEL) || bm_status) {
1769 FPT_SccbMgr_bad_isr(ioport, thisCard, pCurrCard,
1771 WRW_HARPOON((ioport + hp_intstat),
1772 (FIFO | TIMEOUT | RESET | SCAM_SEL));
1777 MENABLE_INT(ioport);
1782 else if (hp_int & ICMD_COMP) {
1784 if (!(hp_int & BUS_FREE)) {
1785 /* Wait for the BusFree before starting a new command. We
1786 must also check for being reselected since the BusFree
1787 may not show up if another device reselects us in 1.5us or
1788 less. SRR Wednesday, 3/8/1995.
1791 (RDW_HARPOON((ioport + hp_intstat)) &
1792 (BUS_FREE | RSEL))) ;
1795 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1797 FPT_phaseChkFifo(ioport, thisCard);
1799 /* WRW_HARPOON((ioport+hp_intstat),
1800 (BUS_FREE | ICMD_COMP | ITAR_DISC | XFER_CNT_0));
1803 WRW_HARPOON((ioport + hp_intstat), CLR_ALL_INT_1);
1805 FPT_autoCmdCmplt(ioport, thisCard);
1809 else if (hp_int & ITAR_DISC) {
1811 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1812 FPT_phaseChkFifo(ioport, thisCard);
1814 if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1817 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1818 currSCCB->Sccb_XferState |= F_NO_DATA_YET;
1820 currSCCB->Sccb_savedATC = currSCCB->Sccb_ATC;
1823 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1824 FPT_queueDisconnect(currSCCB, thisCard);
1826 /* Wait for the BusFree before starting a new command. We
1827 must also check for being reselected since the BusFree
1828 may not show up if another device reselects us in 1.5us or
1829 less. SRR Wednesday, 3/8/1995.
1832 (RDW_HARPOON((ioport + hp_intstat)) &
1834 && !((RDW_HARPOON((ioport + hp_intstat)) & PHASE)
1835 && RD_HARPOON((ioport + hp_scsisig)) ==
1836 (SCSI_BSY | SCSI_REQ | SCSI_CD | SCSI_MSG |
1840 The additional loop exit condition above detects a timing problem
1841 with the revision D/E harpoon chips. The caller should reset the
1842 host adapter to recover when 0xFE is returned.
1845 (RDW_HARPOON((ioport + hp_intstat)) &
1846 (BUS_FREE | RSEL))) {
1847 MENABLE_INT(ioport);
1851 WRW_HARPOON((ioport + hp_intstat),
1852 (BUS_FREE | ITAR_DISC));
1854 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1858 else if (hp_int & RSEL) {
1860 WRW_HARPOON((ioport + hp_intstat),
1861 (PROG_HLT | RSEL | PHASE | BUS_FREE));
1863 if (RDW_HARPOON((ioport + hp_intstat)) & ITAR_DISC) {
1864 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
1865 FPT_phaseChkFifo(ioport, thisCard);
1867 if (RD_HARPOON(ioport + hp_gp_reg_1) ==
1869 WR_HARPOON(ioport + hp_gp_reg_1, 0x00);
1870 currSCCB->Sccb_XferState |=
1872 currSCCB->Sccb_savedATC =
1876 WRW_HARPOON((ioport + hp_intstat),
1877 (BUS_FREE | ITAR_DISC));
1878 currSCCB->Sccb_scsistat = DISCONNECT_ST;
1879 FPT_queueDisconnect(currSCCB, thisCard);
1882 FPT_sres(ioport, thisCard, pCurrCard);
1883 FPT_phaseDecode(ioport, thisCard);
1887 else if ((hp_int & IDO_STRT) && (!(hp_int & BUS_FREE))) {
1889 WRW_HARPOON((ioport + hp_intstat),
1890 (IDO_STRT | XFER_CNT_0));
1891 FPT_phaseDecode(ioport, thisCard);
1895 else if ((hp_int & IUNKWN) || (hp_int & PROG_HLT)) {
1896 WRW_HARPOON((ioport + hp_intstat),
1897 (PHASE | IUNKWN | PROG_HLT));
1898 if ((RD_HARPOON(ioport + hp_prgmcnt_0) & (unsigned char)
1899 0x3f) < (unsigned char)SELCHK) {
1900 FPT_phaseDecode(ioport, thisCard);
1902 /* Harpoon problem some SCSI target device respond to selection
1903 with short BUSY pulse (<400ns) this will make the Harpoon is not able
1904 to latch the correct Target ID into reg. x53.
1905 The work around require to correct this reg. But when write to this
1906 reg. (0x53) also increment the FIFO write addr reg (0x6f), thus we
1907 need to read this reg first then restore it later. After update to 0x53 */
1910 char)(RD_HARPOON(ioport + hp_fifowrite));
1913 char)(RD_HARPOON(ioport + hp_gp_reg_3));
1914 WR_HARPOON(ioport + hp_xfer_pad,
1915 (unsigned char)ID_UNLOCK);
1916 WR_HARPOON(ioport + hp_select_id,
1917 (unsigned char)(target | target <<
1919 WR_HARPOON(ioport + hp_xfer_pad,
1920 (unsigned char)0x00);
1921 WR_HARPOON(ioport + hp_fifowrite, i);
1922 WR_HARPOON(ioport + hp_autostart_3,
1923 (AUTO_IMMED + TAG_STRT));
1927 else if (hp_int & XFER_CNT_0) {
1929 WRW_HARPOON((ioport + hp_intstat), XFER_CNT_0);
1931 FPT_schkdd(ioport, thisCard);
1935 else if (hp_int & BUS_FREE) {
1937 WRW_HARPOON((ioport + hp_intstat), BUS_FREE);
1939 if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
1941 FPT_hostDataXferAbort(ioport, thisCard,
1945 FPT_phaseBusFree(ioport, thisCard);
1948 else if (hp_int & ITICKLE) {
1950 WRW_HARPOON((ioport + hp_intstat), ITICKLE);
1951 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
1954 if (((struct sccb_card *)pCurrCard)->
1955 globalFlags & F_NEW_SCCB_CMD) {
1957 pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1959 if (pCurrCard->currentSCCB == NULL)
1960 FPT_queueSearchSelect(pCurrCard, thisCard);
1962 if (pCurrCard->currentSCCB != NULL) {
1963 pCurrCard->globalFlags &= ~F_NEW_SCCB_CMD;
1964 FPT_ssel(ioport, thisCard);
1973 MENABLE_INT(ioport);
1978 /*---------------------------------------------------------------------
1980 * Function: Sccb_bad_isr
1982 * Description: Some type of interrupt has occurred which is slightly
1983 * out of the ordinary. We will now decode it fully, in
1984 * this routine. This is broken up in an attempt to save
1987 *---------------------------------------------------------------------*/
1988 static unsigned char FPT_SccbMgr_bad_isr(u32 p_port, unsigned char p_card,
1989 struct sccb_card *pCurrCard,
1990 unsigned short p_int)
1992 unsigned char temp, ScamFlg;
1993 struct sccb_mgr_tar_info *currTar_Info;
1994 struct nvram_info *pCurrNvRam;
1996 if (RD_HARPOON(p_port + hp_ext_status) &
1997 (BM_FORCE_OFF | PCI_DEV_TMOUT | BM_PARITY_ERR | PIO_OVERRUN)) {
1999 if (pCurrCard->globalFlags & F_HOST_XFER_ACT) {
2001 FPT_hostDataXferAbort(p_port, p_card,
2002 pCurrCard->currentSCCB);
2005 if (RD_HARPOON(p_port + hp_pci_stat_cfg) & REC_MASTER_ABORT)
2007 WR_HARPOON(p_port + hp_pci_stat_cfg,
2008 (RD_HARPOON(p_port + hp_pci_stat_cfg) &
2009 ~REC_MASTER_ABORT));
2011 WR_HARPOON(p_port + hp_host_blk_cnt, 0x00);
2015 if (pCurrCard->currentSCCB != NULL) {
2017 if (!pCurrCard->currentSCCB->HostStatus)
2018 pCurrCard->currentSCCB->HostStatus =
2021 FPT_sxfrp(p_port, p_card);
2023 temp = (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
2024 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
2025 WR_HARPOON(p_port + hp_ee_ctrl,
2026 ((unsigned char)temp | SEE_MS | SEE_CS));
2027 WR_HARPOON(p_port + hp_ee_ctrl, temp);
2030 (RDW_HARPOON((p_port + hp_intstat)) &
2031 (BUS_FREE | RESET))) {
2032 FPT_phaseDecode(p_port, p_card);
2037 else if (p_int & RESET) {
2039 WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
2040 WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
2041 if (pCurrCard->currentSCCB != NULL) {
2043 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
2045 FPT_hostDataXferAbort(p_port, p_card,
2046 pCurrCard->currentSCCB);
2049 DISABLE_AUTO(p_port);
2051 FPT_sresb(p_port, p_card);
2053 while (RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST) {
2056 pCurrNvRam = pCurrCard->pNvRamInfo;
2058 ScamFlg = pCurrNvRam->niScamConf;
2061 (unsigned char)FPT_utilEERead(p_port,
2065 FPT_XbowInit(p_port, ScamFlg);
2067 FPT_scini(p_card, pCurrCard->ourId, 0);
2072 else if (p_int & FIFO) {
2074 WRW_HARPOON((p_port + hp_intstat), FIFO);
2076 if (pCurrCard->currentSCCB != NULL)
2077 FPT_sxfrp(p_port, p_card);
2080 else if (p_int & TIMEOUT) {
2082 DISABLE_AUTO(p_port);
2084 WRW_HARPOON((p_port + hp_intstat),
2085 (PROG_HLT | TIMEOUT | SEL | BUS_FREE | PHASE |
2088 pCurrCard->currentSCCB->HostStatus = SCCB_SELECTION_TIMEOUT;
2091 &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2092 if ((pCurrCard->globalFlags & F_CONLUN_IO)
2093 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2095 currTar_Info->TarLUNBusy[pCurrCard->currentSCCB->Lun] =
2098 currTar_Info->TarLUNBusy[0] = 0;
2100 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2101 currTar_Info->TarSyncCtrl = 0;
2102 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2105 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2106 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2109 FPT_sssyncv(p_port, pCurrCard->currentSCCB->TargID, NARROW_SCSI,
2112 FPT_queueCmdComplete(pCurrCard, pCurrCard->currentSCCB, p_card);
2116 else if (p_int & SCAM_SEL) {
2118 FPT_scarb(p_port, LEVEL2_TAR);
2120 FPT_scasid(p_card, p_port);
2124 WRW_HARPOON((p_port + hp_intstat), SCAM_SEL);
2130 /*---------------------------------------------------------------------
2132 * Function: SccbMgrTableInit
2134 * Description: Initialize all Sccb manager data structures.
2136 *---------------------------------------------------------------------*/
2138 static void FPT_SccbMgrTableInitAll(void)
2140 unsigned char thisCard;
2142 for (thisCard = 0; thisCard < MAX_CARDS; thisCard++) {
2143 FPT_SccbMgrTableInitCard(&FPT_BL_Card[thisCard], thisCard);
2145 FPT_BL_Card[thisCard].ioPort = 0x00;
2146 FPT_BL_Card[thisCard].cardInfo = NULL;
2147 FPT_BL_Card[thisCard].cardIndex = 0xFF;
2148 FPT_BL_Card[thisCard].ourId = 0x00;
2149 FPT_BL_Card[thisCard].pNvRamInfo = NULL;
2153 /*---------------------------------------------------------------------
2155 * Function: SccbMgrTableInit
2157 * Description: Initialize all Sccb manager data structures.
2159 *---------------------------------------------------------------------*/
2161 static void FPT_SccbMgrTableInitCard(struct sccb_card *pCurrCard,
2162 unsigned char p_card)
2164 unsigned char scsiID, qtag;
2166 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2167 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2170 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
2171 FPT_sccbMgrTbl[p_card][scsiID].TarStatus = 0;
2172 FPT_sccbMgrTbl[p_card][scsiID].TarEEValue = 0;
2173 FPT_SccbMgrTableInitTarget(p_card, scsiID);
2176 pCurrCard->scanIndex = 0x00;
2177 pCurrCard->currentSCCB = NULL;
2178 pCurrCard->globalFlags = 0x00;
2179 pCurrCard->cmdCounter = 0x00;
2180 pCurrCard->tagQ_Lst = 0x01;
2181 pCurrCard->discQCount = 0;
2185 /*---------------------------------------------------------------------
2187 * Function: SccbMgrTableInit
2189 * Description: Initialize all Sccb manager data structures.
2191 *---------------------------------------------------------------------*/
2193 static void FPT_SccbMgrTableInitTarget(unsigned char p_card,
2194 unsigned char target)
2197 unsigned char lun, qtag;
2198 struct sccb_mgr_tar_info *currTar_Info;
2200 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2202 currTar_Info->TarSelQ_Cnt = 0;
2203 currTar_Info->TarSyncCtrl = 0;
2205 currTar_Info->TarSelQ_Head = NULL;
2206 currTar_Info->TarSelQ_Tail = NULL;
2207 currTar_Info->TarTagQ_Cnt = 0;
2208 currTar_Info->TarLUN_CA = 0;
2210 for (lun = 0; lun < MAX_LUN; lun++) {
2211 currTar_Info->TarLUNBusy[lun] = 0;
2212 currTar_Info->LunDiscQ_Idx[lun] = 0;
2215 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
2216 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] != NULL) {
2217 if (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
2219 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
2220 FPT_BL_Card[p_card].discQCount--;
2226 /*---------------------------------------------------------------------
2230 * Description: Read in a message byte from the SCSI bus, and check
2231 * for a parity error.
2233 *---------------------------------------------------------------------*/
2235 static unsigned char FPT_sfm(u32 port, struct sccb *pCurrSCCB)
2237 unsigned char message;
2238 unsigned short TimeOutLoop;
2241 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2242 (TimeOutLoop++ < 20000)) {
2245 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2247 message = RD_HARPOON(port + hp_scsidata_0);
2249 WR_HARPOON(port + hp_scsisig, SCSI_ACK + S_MSGI_PH);
2251 if (TimeOutLoop > 20000)
2252 message = 0x00; /* force message byte = 0 if Time Out on Req */
2254 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
2255 (RD_HARPOON(port + hp_addstat) & SCSI_PAR_ERR)) {
2256 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2257 WR_HARPOON(port + hp_xferstat, 0);
2258 WR_HARPOON(port + hp_fiforead, 0);
2259 WR_HARPOON(port + hp_fifowrite, 0);
2260 if (pCurrSCCB != NULL) {
2261 pCurrSCCB->Sccb_scsimsg = SMPARITY;
2265 ACCEPT_MSG_ATN(port);
2267 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2268 (TimeOutLoop++ < 20000)) {
2270 if (TimeOutLoop > 20000) {
2271 WRW_HARPOON((port + hp_intstat), PARITY);
2274 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) !=
2276 WRW_HARPOON((port + hp_intstat), PARITY);
2279 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
2281 RD_HARPOON(port + hp_scsidata_0);
2283 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2288 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2289 WR_HARPOON(port + hp_xferstat, 0);
2290 WR_HARPOON(port + hp_fiforead, 0);
2291 WR_HARPOON(port + hp_fifowrite, 0);
2295 /*---------------------------------------------------------------------
2297 * Function: FPT_ssel
2299 * Description: Load up automation and select target device.
2301 *---------------------------------------------------------------------*/
2303 static void FPT_ssel(u32 port, unsigned char p_card)
2306 unsigned char auto_loaded, i, target, *theCCB;
2309 struct sccb_card *CurrCard;
2310 struct sccb *currSCCB;
2311 struct sccb_mgr_tar_info *currTar_Info;
2312 unsigned char lastTag, lun;
2314 CurrCard = &FPT_BL_Card[p_card];
2315 currSCCB = CurrCard->currentSCCB;
2316 target = currSCCB->TargID;
2317 currTar_Info = &FPT_sccbMgrTbl[p_card][target];
2318 lastTag = CurrCard->tagQ_Lst;
2322 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
2323 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2325 if (((CurrCard->globalFlags & F_CONLUN_IO) &&
2326 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING)))
2328 lun = currSCCB->Lun;
2332 if (CurrCard->globalFlags & F_TAG_STARTED) {
2333 if (!(currSCCB->ControlByte & F_USE_CMD_Q)) {
2334 if ((currTar_Info->TarLUN_CA == 0)
2335 && ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2338 if (currTar_Info->TarTagQ_Cnt != 0) {
2339 currTar_Info->TarLUNBusy[lun] = 1;
2340 FPT_queueSelectFail(CurrCard, p_card);
2346 currTar_Info->TarLUNBusy[lun] = 1;
2352 currTar_Info->TarLUNBusy[lun] = 1;
2356 /*!Use cmd Q Tagged */
2358 if (currTar_Info->TarLUN_CA == 1) {
2359 FPT_queueSelectFail(CurrCard, p_card);
2364 currTar_Info->TarLUNBusy[lun] = 1;
2366 } /*else use cmd Q tagged */
2369 /*if glob tagged started */
2371 currTar_Info->TarLUNBusy[lun] = 1;
2374 if ((((CurrCard->globalFlags & F_CONLUN_IO) &&
2375 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
2376 || (!(currSCCB->ControlByte & F_USE_CMD_Q)))) {
2377 if (CurrCard->discQCount >= QUEUE_DEPTH) {
2378 currTar_Info->TarLUNBusy[lun] = 1;
2379 FPT_queueSelectFail(CurrCard, p_card);
2383 for (i = 1; i < QUEUE_DEPTH; i++) {
2384 if (++lastTag >= QUEUE_DEPTH)
2386 if (CurrCard->discQ_Tbl[lastTag] == NULL) {
2387 CurrCard->tagQ_Lst = lastTag;
2388 currTar_Info->LunDiscQ_Idx[lun] = lastTag;
2389 CurrCard->discQ_Tbl[lastTag] = currSCCB;
2390 CurrCard->discQCount++;
2394 if (i == QUEUE_DEPTH) {
2395 currTar_Info->TarLUNBusy[lun] = 1;
2396 FPT_queueSelectFail(CurrCard, p_card);
2404 WR_HARPOON(port + hp_select_id, target);
2405 WR_HARPOON(port + hp_gp_reg_3, target); /* Use by new automation logic */
2407 if (currSCCB->OperationCode == RESET_COMMAND) {
2408 WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2410 Sccb_idmsg & ~DISC_PRIV)));
2412 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + NP);
2414 currSCCB->Sccb_scsimsg = SMDEV_RESET;
2416 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2418 currSCCB->Sccb_scsistat = SELECT_BDR_ST;
2420 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
2421 currTar_Info->TarSyncCtrl = 0;
2422 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2425 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
2426 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2429 FPT_sssyncv(port, target, NARROW_SCSI, currTar_Info);
2430 FPT_SccbMgrTableInitTarget(p_card, target);
2434 else if (currSCCB->Sccb_scsistat == ABORT_ST) {
2435 WRW_HARPOON((port + ID_MSG_STRT), (MPM_OP + AMSG_OUT +
2437 Sccb_idmsg & ~DISC_PRIV)));
2439 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
2441 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT +
2446 >> 6) | (unsigned char)
2448 WRW_HARPOON((port + SYNC_MSGS + 2),
2449 (MPM_OP + AMSG_OUT + currSCCB->Sccb_tag));
2450 WRW_HARPOON((port + SYNC_MSGS + 4), (BRH_OP + ALWAYS + NP));
2452 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
2457 else if (!(currTar_Info->TarStatus & WIDE_NEGOCIATED)) {
2458 auto_loaded = FPT_siwidn(port, p_card);
2459 currSCCB->Sccb_scsistat = SELECT_WN_ST;
2462 else if (!((currTar_Info->TarStatus & TAR_SYNC_MASK)
2463 == SYNC_SUPPORTED)) {
2464 auto_loaded = FPT_sisyncn(port, p_card, 0);
2465 currSCCB->Sccb_scsistat = SELECT_SN_ST;
2470 if (currSCCB->ControlByte & F_USE_CMD_Q) {
2472 CurrCard->globalFlags |= F_TAG_STARTED;
2474 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK)
2476 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2478 /* Fix up the start instruction with a jump to
2479 Non-Tag-CMD handling */
2480 WRW_HARPOON((port + ID_MSG_STRT),
2481 BRH_OP + ALWAYS + NTCMD);
2483 WRW_HARPOON((port + NON_TAG_ID_MSG),
2484 (MPM_OP + AMSG_OUT +
2485 currSCCB->Sccb_idmsg));
2487 WR_HARPOON(port + hp_autostart_3,
2488 (SELECT + SELCHK_STRT));
2490 /* Setup our STATE so we know what happened when
2491 the wheels fall off. */
2492 currSCCB->Sccb_scsistat = SELECT_ST;
2494 currTar_Info->TarLUNBusy[lun] = 1;
2498 WRW_HARPOON((port + ID_MSG_STRT),
2499 (MPM_OP + AMSG_OUT +
2500 currSCCB->Sccb_idmsg));
2502 WRW_HARPOON((port + ID_MSG_STRT + 2),
2503 (MPM_OP + AMSG_OUT +
2504 (((unsigned char)(currSCCB->
2507 >> 6) | (unsigned char)0x20)));
2509 for (i = 1; i < QUEUE_DEPTH; i++) {
2510 if (++lastTag >= QUEUE_DEPTH)
2512 if (CurrCard->discQ_Tbl[lastTag] ==
2516 (MPM_OP + AMSG_OUT +
2518 CurrCard->tagQ_Lst = lastTag;
2519 currSCCB->Sccb_tag = lastTag;
2520 CurrCard->discQ_Tbl[lastTag] =
2522 CurrCard->discQCount++;
2527 if (i == QUEUE_DEPTH) {
2528 currTar_Info->TarLUNBusy[lun] = 1;
2529 FPT_queueSelectFail(CurrCard, p_card);
2534 currSCCB->Sccb_scsistat = SELECT_Q_ST;
2536 WR_HARPOON(port + hp_autostart_3,
2537 (SELECT + SELCHK_STRT));
2543 WRW_HARPOON((port + ID_MSG_STRT),
2544 BRH_OP + ALWAYS + NTCMD);
2546 WRW_HARPOON((port + NON_TAG_ID_MSG),
2547 (MPM_OP + AMSG_OUT + currSCCB->Sccb_idmsg));
2549 currSCCB->Sccb_scsistat = SELECT_ST;
2551 WR_HARPOON(port + hp_autostart_3,
2552 (SELECT + SELCHK_STRT));
2555 theCCB = (unsigned char *)&currSCCB->Cdb[0];
2557 cdb_reg = port + CMD_STRT;
2559 for (i = 0; i < currSCCB->CdbLength; i++) {
2560 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + *theCCB));
2565 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
2566 WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
2570 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2571 WR_HARPOON(port + hp_xferstat, 0x00);
2573 WRW_HARPOON((port + hp_intstat), (PROG_HLT | TIMEOUT | SEL | BUS_FREE));
2575 WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT));
2577 if (!(currSCCB->Sccb_MGRFlags & F_DEV_SELECTED)) {
2578 WR_HARPOON(port + hp_scsictrl_0,
2579 (SEL_TAR | ENA_ATN | ENA_RESEL | ENA_SCAM_SEL));
2582 /* auto_loaded = (RD_HARPOON(port+hp_autostart_3) & (unsigned char)0x1F);
2583 auto_loaded |= AUTO_IMMED; */
2584 auto_loaded = AUTO_IMMED;
2588 WR_HARPOON(port + hp_autostart_3, auto_loaded);
2594 /*---------------------------------------------------------------------
2596 * Function: FPT_sres
2598 * Description: Hookup the correct CCB and handle the incoming messages.
2600 *---------------------------------------------------------------------*/
2602 static void FPT_sres(u32 port, unsigned char p_card,
2603 struct sccb_card *pCurrCard)
2606 unsigned char our_target, message, lun = 0, tag, msgRetryCount;
2608 struct sccb_mgr_tar_info *currTar_Info;
2609 struct sccb *currSCCB;
2611 if (pCurrCard->currentSCCB != NULL) {
2613 &FPT_sccbMgrTbl[p_card][pCurrCard->currentSCCB->TargID];
2616 WR_HARPOON((port + hp_scsictrl_0), (ENA_RESEL | ENA_SCAM_SEL));
2618 currSCCB = pCurrCard->currentSCCB;
2619 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
2620 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
2621 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2623 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2624 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
2625 currSCCB->Sccb_scsistat = BUS_FREE_ST;
2627 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2628 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
2630 currTar_Info->TarLUNBusy[currSCCB->Lun] = 0;
2631 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2632 pCurrCard->discQCount--;
2633 pCurrCard->discQ_Tbl[currTar_Info->
2634 LunDiscQ_Idx[currSCCB->
2639 currTar_Info->TarLUNBusy[0] = 0;
2640 if (currSCCB->Sccb_tag) {
2641 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2642 pCurrCard->discQCount--;
2643 pCurrCard->discQ_Tbl[currSCCB->
2647 if (currSCCB->Sccb_scsistat != ABORT_ST) {
2648 pCurrCard->discQCount--;
2649 pCurrCard->discQ_Tbl[currTar_Info->
2656 FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
2659 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
2661 our_target = (unsigned char)(RD_HARPOON(port + hp_select_id) >> 4);
2662 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2667 currTar_Info = &FPT_sccbMgrTbl[p_card][our_target];
2670 while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2671 if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2673 WRW_HARPOON((port + hp_intstat), PHASE);
2678 WRW_HARPOON((port + hp_intstat), PHASE);
2679 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGI_PH) {
2681 message = FPT_sfm(port, pCurrCard->currentSCCB);
2684 if (message <= (0x80 | LUN_MASK)) {
2685 lun = message & (unsigned char)LUN_MASK;
2688 TarStatus & TAR_TAG_Q_MASK) ==
2690 if (currTar_Info->TarTagQ_Cnt !=
2696 ACCEPT_MSG(port); /*Release the ACK for ID msg. */
2732 /*End Tag cmds supported! */
2734 /*End valid ID message. */
2737 ACCEPT_MSG_ATN(port);
2741 /* End good id message. */
2747 ACCEPT_MSG_ATN(port);
2750 (RDW_HARPOON((port + hp_intstat)) &
2752 && !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
2753 && (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2760 if (msgRetryCount == 1) {
2761 FPT_SendMsg(port, SMPARITY);
2763 FPT_SendMsg(port, SMDEV_RESET);
2765 FPT_sssyncv(port, our_target, NARROW_SCSI,
2768 if (FPT_sccbMgrTbl[p_card][our_target].
2769 TarEEValue & EE_SYNC_MASK) {
2771 FPT_sccbMgrTbl[p_card][our_target].
2772 TarStatus &= ~TAR_SYNC_MASK;
2776 if (FPT_sccbMgrTbl[p_card][our_target].
2777 TarEEValue & EE_WIDE_SCSI) {
2779 FPT_sccbMgrTbl[p_card][our_target].
2780 TarStatus &= ~TAR_WIDE_MASK;
2783 FPT_queueFlushTargSccb(p_card, our_target,
2785 FPT_SccbMgrTableInitTarget(p_card, our_target);
2789 } while (message == 0);
2791 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
2792 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
2793 currTar_Info->TarLUNBusy[lun] = 1;
2794 pCurrCard->currentSCCB =
2795 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[lun]];
2796 if (pCurrCard->currentSCCB != NULL) {
2799 ACCEPT_MSG_ATN(port);
2802 currTar_Info->TarLUNBusy[0] = 1;
2805 if (pCurrCard->discQ_Tbl[tag] != NULL) {
2806 pCurrCard->currentSCCB =
2807 pCurrCard->discQ_Tbl[tag];
2808 currTar_Info->TarTagQ_Cnt--;
2811 ACCEPT_MSG_ATN(port);
2814 pCurrCard->currentSCCB =
2815 pCurrCard->discQ_Tbl[currTar_Info->LunDiscQ_Idx[0]];
2816 if (pCurrCard->currentSCCB != NULL) {
2819 ACCEPT_MSG_ATN(port);
2824 if (pCurrCard->currentSCCB != NULL) {
2825 if (pCurrCard->currentSCCB->Sccb_scsistat == ABORT_ST) {
2826 /* During Abort Tag command, the target could have got re-selected
2827 and completed the command. Check the select Q and remove the CCB
2828 if it is in the Select Q */
2829 FPT_queueFindSccb(pCurrCard->currentSCCB, p_card);
2833 while (!(RDW_HARPOON((port + hp_intstat)) & (PHASE | RESET)) &&
2834 !(RD_HARPOON(port + hp_scsisig) & SCSI_REQ) &&
2835 (RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ;
2838 static void FPT_SendMsg(u32 port, unsigned char message)
2840 while (!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) {
2841 if (!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) {
2843 WRW_HARPOON((port + hp_intstat), PHASE);
2848 WRW_HARPOON((port + hp_intstat), PHASE);
2849 if ((RD_HARPOON(port + hp_scsisig) & S_SCSI_PHZ) == S_MSGO_PH) {
2850 WRW_HARPOON((port + hp_intstat),
2851 (BUS_FREE | PHASE | XFER_CNT_0));
2853 WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
2855 WR_HARPOON(port + hp_scsidata_0, message);
2857 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
2861 WR_HARPOON(port + hp_portctrl_0, 0x00);
2863 if ((message == SMABORT) || (message == SMDEV_RESET) ||
2864 (message == SMABORT_TAG)) {
2866 (RDW_HARPOON((port + hp_intstat)) &
2867 (BUS_FREE | PHASE))) {
2870 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2871 WRW_HARPOON((port + hp_intstat), BUS_FREE);
2877 /*---------------------------------------------------------------------
2879 * Function: FPT_sdecm
2881 * Description: Determine the proper response to the message from the
2884 *---------------------------------------------------------------------*/
2885 static void FPT_sdecm(unsigned char message, u32 port, unsigned char p_card)
2887 struct sccb *currSCCB;
2888 struct sccb_card *CurrCard;
2889 struct sccb_mgr_tar_info *currTar_Info;
2891 CurrCard = &FPT_BL_Card[p_card];
2892 currSCCB = CurrCard->currentSCCB;
2894 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
2896 if (message == SMREST_DATA_PTR) {
2897 if (!(currSCCB->Sccb_XferState & F_NO_DATA_YET)) {
2898 currSCCB->Sccb_ATC = currSCCB->Sccb_savedATC;
2900 FPT_hostDataXferRestart(currSCCB);
2904 WR_HARPOON(port + hp_autostart_1,
2905 (AUTO_IMMED + DISCONNECT_START));
2908 else if (message == SMCMD_COMP) {
2910 if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
2911 currTar_Info->TarStatus &=
2912 ~(unsigned char)TAR_TAG_Q_MASK;
2913 currTar_Info->TarStatus |= (unsigned char)TAG_Q_REJECT;
2920 else if ((message == SMNO_OP) || (message >= SMIDENT)
2921 || (message == SMINIT_RECOVERY) || (message == SMREL_RECOVERY)) {
2924 WR_HARPOON(port + hp_autostart_1,
2925 (AUTO_IMMED + DISCONNECT_START));
2928 else if (message == SMREJECT) {
2930 if ((currSCCB->Sccb_scsistat == SELECT_SN_ST) ||
2931 (currSCCB->Sccb_scsistat == SELECT_WN_ST) ||
2932 ((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)
2933 || ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) ==
2936 WRW_HARPOON((port + hp_intstat), BUS_FREE);
2940 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
2941 (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
2945 if (currSCCB->Lun == 0x00) {
2946 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
2948 currTar_Info->TarStatus |=
2949 (unsigned char)SYNC_SUPPORTED;
2951 currTar_Info->TarEEValue &=
2955 else if (currSCCB->Sccb_scsistat ==
2958 currTar_Info->TarStatus =
2960 TarStatus & ~WIDE_ENABLED) |
2963 currTar_Info->TarEEValue &=
2968 else if ((currTar_Info->
2969 TarStatus & TAR_TAG_Q_MASK) ==
2971 currTar_Info->TarStatus =
2973 TarStatus & ~(unsigned char)
2974 TAR_TAG_Q_MASK) | TAG_Q_REJECT;
2976 currSCCB->ControlByte &= ~F_USE_CMD_Q;
2977 CurrCard->discQCount--;
2978 CurrCard->discQ_Tbl[currSCCB->
2980 currSCCB->Sccb_tag = 0x00;
2985 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
2987 if (currSCCB->Lun == 0x00) {
2988 WRW_HARPOON((port + hp_intstat),
2990 CurrCard->globalFlags |= F_NEW_SCCB_CMD;
2996 if ((CurrCard->globalFlags & F_CONLUN_IO) &&
2998 TarStatus & TAR_TAG_Q_MASK) !=
3000 currTar_Info->TarLUNBusy[currSCCB->
3003 currTar_Info->TarLUNBusy[0] = 1;
3005 currSCCB->ControlByte &=
3006 ~(unsigned char)F_USE_CMD_Q;
3008 WR_HARPOON(port + hp_autostart_1,
3009 (AUTO_IMMED + DISCONNECT_START));
3017 while ((!(RD_HARPOON(port + hp_scsisig) & SCSI_REQ)) &&
3018 (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)))
3022 if (!(RDW_HARPOON((port + hp_intstat)) & BUS_FREE)) {
3023 WR_HARPOON(port + hp_autostart_1,
3024 (AUTO_IMMED + DISCONNECT_START));
3029 else if (message == SMEXT) {
3032 FPT_shandem(port, p_card, currSCCB);
3035 else if (message == SMIGNORWR) {
3037 ACCEPT_MSG(port); /* ACK the RESIDUE MSG */
3039 message = FPT_sfm(port, currSCCB);
3041 if (currSCCB->Sccb_scsimsg != SMPARITY)
3043 WR_HARPOON(port + hp_autostart_1,
3044 (AUTO_IMMED + DISCONNECT_START));
3049 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
3050 currSCCB->Sccb_scsimsg = SMREJECT;
3052 ACCEPT_MSG_ATN(port);
3053 WR_HARPOON(port + hp_autostart_1,
3054 (AUTO_IMMED + DISCONNECT_START));
3058 /*---------------------------------------------------------------------
3060 * Function: FPT_shandem
3062 * Description: Decide what to do with the extended message.
3064 *---------------------------------------------------------------------*/
3065 static void FPT_shandem(u32 port, unsigned char p_card, struct sccb *pCurrSCCB)
3067 unsigned char length, message;
3069 length = FPT_sfm(port, pCurrSCCB);
3073 message = FPT_sfm(port, pCurrSCCB);
3076 if (message == SMSYNC) {
3078 if (length == 0x03) {
3081 FPT_stsyncn(port, p_card);
3084 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3085 ACCEPT_MSG_ATN(port);
3087 } else if (message == SMWDTR) {
3089 if (length == 0x02) {
3092 FPT_stwidn(port, p_card);
3095 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3096 ACCEPT_MSG_ATN(port);
3098 WR_HARPOON(port + hp_autostart_1,
3104 pCurrSCCB->Sccb_scsimsg = SMREJECT;
3105 ACCEPT_MSG_ATN(port);
3107 WR_HARPOON(port + hp_autostart_1,
3108 (AUTO_IMMED + DISCONNECT_START));
3111 if (pCurrSCCB->Sccb_scsimsg != SMPARITY)
3113 WR_HARPOON(port + hp_autostart_1,
3114 (AUTO_IMMED + DISCONNECT_START));
3117 if (pCurrSCCB->Sccb_scsimsg == SMPARITY)
3118 WR_HARPOON(port + hp_autostart_1,
3119 (AUTO_IMMED + DISCONNECT_START));
3123 /*---------------------------------------------------------------------
3125 * Function: FPT_sisyncn
3127 * Description: Read in a message byte from the SCSI bus, and check
3128 * for a parity error.
3130 *---------------------------------------------------------------------*/
3132 static unsigned char FPT_sisyncn(u32 port, unsigned char p_card,
3133 unsigned char syncFlag)
3135 struct sccb *currSCCB;
3136 struct sccb_mgr_tar_info *currTar_Info;
3138 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3139 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3141 if (!((currTar_Info->TarStatus & TAR_SYNC_MASK) == SYNC_TRYING)) {
3143 WRW_HARPOON((port + ID_MSG_STRT),
3144 (MPM_OP + AMSG_OUT +
3146 Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3148 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3150 WRW_HARPOON((port + SYNC_MSGS + 0),
3151 (MPM_OP + AMSG_OUT + SMEXT));
3152 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3153 WRW_HARPOON((port + SYNC_MSGS + 4),
3154 (MPM_OP + AMSG_OUT + SMSYNC));
3156 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3158 WRW_HARPOON((port + SYNC_MSGS + 6),
3159 (MPM_OP + AMSG_OUT + 12));
3161 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3164 WRW_HARPOON((port + SYNC_MSGS + 6),
3165 (MPM_OP + AMSG_OUT + 25));
3167 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) ==
3170 WRW_HARPOON((port + SYNC_MSGS + 6),
3171 (MPM_OP + AMSG_OUT + 50));
3174 WRW_HARPOON((port + SYNC_MSGS + 6),
3175 (MPM_OP + AMSG_OUT + 00));
3177 WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3178 WRW_HARPOON((port + SYNC_MSGS + 10),
3179 (MPM_OP + AMSG_OUT + DEFAULT_OFFSET));
3180 WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3182 if (syncFlag == 0) {
3183 WR_HARPOON(port + hp_autostart_3,
3184 (SELECT + SELCHK_STRT));
3185 currTar_Info->TarStatus =
3187 TarStatus & ~(unsigned char)TAR_SYNC_MASK) |
3188 (unsigned char)SYNC_TRYING);
3190 WR_HARPOON(port + hp_autostart_3,
3191 (AUTO_IMMED + CMD_ONLY_STRT));
3199 currTar_Info->TarStatus |= (unsigned char)SYNC_SUPPORTED;
3200 currTar_Info->TarEEValue &= ~EE_SYNC_MASK;
3205 /*---------------------------------------------------------------------
3207 * Function: FPT_stsyncn
3209 * Description: The has sent us a Sync Nego message so handle it as
3212 *---------------------------------------------------------------------*/
3213 static void FPT_stsyncn(u32 port, unsigned char p_card)
3215 unsigned char sync_msg, offset, sync_reg, our_sync_msg;
3216 struct sccb *currSCCB;
3217 struct sccb_mgr_tar_info *currTar_Info;
3219 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3220 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3222 sync_msg = FPT_sfm(port, currSCCB);
3224 if ((sync_msg == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3225 WR_HARPOON(port + hp_autostart_1,
3226 (AUTO_IMMED + DISCONNECT_START));
3232 offset = FPT_sfm(port, currSCCB);
3234 if ((offset == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3235 WR_HARPOON(port + hp_autostart_1,
3236 (AUTO_IMMED + DISCONNECT_START));
3240 if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_20MB)
3242 our_sync_msg = 12; /* Setup our Message to 20mb/s */
3244 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_10MB)
3246 our_sync_msg = 25; /* Setup our Message to 10mb/s */
3248 else if ((currTar_Info->TarEEValue & EE_SYNC_MASK) == EE_SYNC_5MB)
3250 our_sync_msg = 50; /* Setup our Message to 5mb/s */
3253 our_sync_msg = 0; /* Message = Async */
3255 if (sync_msg < our_sync_msg) {
3256 sync_msg = our_sync_msg; /*if faster, then set to max. */
3259 if (offset == ASYNC)
3262 if (offset > MAX_OFFSET)
3263 offset = MAX_OFFSET;
3269 sync_reg = 0x20; /* Use 10MB/s */
3273 sync_reg = 0x40; /* Use 6.6MB/s */
3277 sync_reg = 0x60; /* Use 5MB/s */
3281 sync_reg = 0x80; /* Use 4MB/s */
3285 sync_reg = 0xA0; /* Use 3.33MB/s */
3289 sync_reg = 0xC0; /* Use 2.85MB/s */
3293 sync_reg = 0xE0; /* Use 2.5MB/s */
3295 if (sync_msg > 100) {
3297 sync_reg = 0x00; /* Use ASYNC */
3301 if (currTar_Info->TarStatus & WIDE_ENABLED)
3307 sync_reg |= (offset | NARROW_SCSI);
3309 FPT_sssyncv(port, currSCCB->TargID, sync_reg, currTar_Info);
3311 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
3315 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3316 ~(unsigned char)TAR_SYNC_MASK) |
3317 (unsigned char)SYNC_SUPPORTED);
3319 WR_HARPOON(port + hp_autostart_1,
3320 (AUTO_IMMED + DISCONNECT_START));
3325 ACCEPT_MSG_ATN(port);
3327 FPT_sisyncr(port, sync_msg, offset);
3329 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3330 ~(unsigned char)TAR_SYNC_MASK) |
3331 (unsigned char)SYNC_SUPPORTED);
3335 /*---------------------------------------------------------------------
3337 * Function: FPT_sisyncr
3339 * Description: Answer the targets sync message.
3341 *---------------------------------------------------------------------*/
3342 static void FPT_sisyncr(u32 port, unsigned char sync_pulse,
3343 unsigned char offset)
3346 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
3347 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x03));
3348 WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMSYNC));
3349 WRW_HARPOON((port + SYNC_MSGS + 6), (MPM_OP + AMSG_OUT + sync_pulse));
3350 WRW_HARPOON((port + SYNC_MSGS + 8), (RAT_OP));
3351 WRW_HARPOON((port + SYNC_MSGS + 10), (MPM_OP + AMSG_OUT + offset));
3352 WRW_HARPOON((port + SYNC_MSGS + 12), (BRH_OP + ALWAYS + NP));
3355 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3356 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3358 WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3360 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3364 /*---------------------------------------------------------------------
3366 * Function: FPT_siwidn
3368 * Description: Read in a message byte from the SCSI bus, and check
3369 * for a parity error.
3371 *---------------------------------------------------------------------*/
3373 static unsigned char FPT_siwidn(u32 port, unsigned char p_card)
3375 struct sccb *currSCCB;
3376 struct sccb_mgr_tar_info *currTar_Info;
3378 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3379 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3381 if (!((currTar_Info->TarStatus & TAR_WIDE_MASK) == WIDE_NEGOCIATED)) {
3383 WRW_HARPOON((port + ID_MSG_STRT),
3384 (MPM_OP + AMSG_OUT +
3386 Sccb_idmsg & ~(unsigned char)DISC_PRIV)));
3388 WRW_HARPOON((port + ID_MSG_STRT + 2), BRH_OP + ALWAYS + CMDPZ);
3390 WRW_HARPOON((port + SYNC_MSGS + 0),
3391 (MPM_OP + AMSG_OUT + SMEXT));
3392 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3393 WRW_HARPOON((port + SYNC_MSGS + 4),
3394 (MPM_OP + AMSG_OUT + SMWDTR));
3395 WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3396 WRW_HARPOON((port + SYNC_MSGS + 8),
3397 (MPM_OP + AMSG_OUT + SM16BIT));
3398 WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3400 WR_HARPOON(port + hp_autostart_3, (SELECT + SELCHK_STRT));
3402 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3403 ~(unsigned char)TAR_WIDE_MASK) |
3404 (unsigned char)WIDE_ENABLED);
3411 currTar_Info->TarStatus = ((currTar_Info->TarStatus &
3412 ~(unsigned char)TAR_WIDE_MASK) |
3415 currTar_Info->TarEEValue &= ~EE_WIDE_SCSI;
3420 /*---------------------------------------------------------------------
3422 * Function: FPT_stwidn
3424 * Description: The has sent us a Wide Nego message so handle it as
3427 *---------------------------------------------------------------------*/
3428 static void FPT_stwidn(u32 port, unsigned char p_card)
3430 unsigned char width;
3431 struct sccb *currSCCB;
3432 struct sccb_mgr_tar_info *currTar_Info;
3434 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3435 currTar_Info = &FPT_sccbMgrTbl[p_card][currSCCB->TargID];
3437 width = FPT_sfm(port, currSCCB);
3439 if ((width == 0x00) && (currSCCB->Sccb_scsimsg == SMPARITY)) {
3440 WR_HARPOON(port + hp_autostart_1,
3441 (AUTO_IMMED + DISCONNECT_START));
3445 if (!(currTar_Info->TarEEValue & EE_WIDE_SCSI))
3449 currTar_Info->TarStatus |= WIDE_ENABLED;
3452 width = NARROW_SCSI;
3453 currTar_Info->TarStatus &= ~WIDE_ENABLED;
3456 FPT_sssyncv(port, currSCCB->TargID, width, currTar_Info);
3458 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
3460 currTar_Info->TarStatus |= WIDE_NEGOCIATED;
3463 ((currTar_Info->TarStatus & TAR_SYNC_MASK) ==
3465 ACCEPT_MSG_ATN(port);
3467 FPT_sisyncn(port, p_card, 1);
3468 currSCCB->Sccb_scsistat = SELECT_SN_ST;
3472 WR_HARPOON(port + hp_autostart_1,
3473 (AUTO_IMMED + DISCONNECT_START));
3479 ACCEPT_MSG_ATN(port);
3481 if (currTar_Info->TarEEValue & EE_WIDE_SCSI)
3486 FPT_siwidr(port, width);
3488 currTar_Info->TarStatus |= (WIDE_NEGOCIATED | WIDE_ENABLED);
3492 /*---------------------------------------------------------------------
3494 * Function: FPT_siwidr
3496 * Description: Answer the targets Wide nego message.
3498 *---------------------------------------------------------------------*/
3499 static void FPT_siwidr(u32 port, unsigned char width)
3502 WRW_HARPOON((port + SYNC_MSGS + 0), (MPM_OP + AMSG_OUT + SMEXT));
3503 WRW_HARPOON((port + SYNC_MSGS + 2), (MPM_OP + AMSG_OUT + 0x02));
3504 WRW_HARPOON((port + SYNC_MSGS + 4), (MPM_OP + AMSG_OUT + SMWDTR));
3505 WRW_HARPOON((port + SYNC_MSGS + 6), (RAT_OP));
3506 WRW_HARPOON((port + SYNC_MSGS + 8), (MPM_OP + AMSG_OUT + width));
3507 WRW_HARPOON((port + SYNC_MSGS + 10), (BRH_OP + ALWAYS + NP));
3510 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3511 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT_1);
3513 WR_HARPOON(port + hp_autostart_3, (AUTO_IMMED + CMD_ONLY_STRT));
3515 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | AUTO_INT))) {
3519 /*---------------------------------------------------------------------
3521 * Function: FPT_sssyncv
3523 * Description: Write the desired value to the Sync Register for the
3526 *---------------------------------------------------------------------*/
3527 static void FPT_sssyncv(u32 p_port, unsigned char p_id,
3528 unsigned char p_sync_value,
3529 struct sccb_mgr_tar_info *currTar_Info)
3531 unsigned char index;
3538 index = 12; /* hp_synctarg_0 */
3541 index = 13; /* hp_synctarg_1 */
3544 index = 14; /* hp_synctarg_2 */
3547 index = 15; /* hp_synctarg_3 */
3550 index = 8; /* hp_synctarg_4 */
3553 index = 9; /* hp_synctarg_5 */
3556 index = 10; /* hp_synctarg_6 */
3559 index = 11; /* hp_synctarg_7 */
3562 index = 4; /* hp_synctarg_8 */
3565 index = 5; /* hp_synctarg_9 */
3568 index = 6; /* hp_synctarg_10 */
3571 index = 7; /* hp_synctarg_11 */
3574 index = 0; /* hp_synctarg_12 */
3577 index = 1; /* hp_synctarg_13 */
3580 index = 2; /* hp_synctarg_14 */
3583 index = 3; /* hp_synctarg_15 */
3587 WR_HARPOON(p_port + hp_synctarg_base + index, p_sync_value);
3589 currTar_Info->TarSyncCtrl = p_sync_value;
3592 /*---------------------------------------------------------------------
3594 * Function: FPT_sresb
3596 * Description: Reset the desired card's SCSI bus.
3598 *---------------------------------------------------------------------*/
3599 static void FPT_sresb(u32 port, unsigned char p_card)
3601 unsigned char scsiID, i;
3603 struct sccb_mgr_tar_info *currTar_Info;
3605 WR_HARPOON(port + hp_page_ctrl,
3606 (RD_HARPOON(port + hp_page_ctrl) | G_INT_DISABLE));
3607 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3609 WR_HARPOON(port + hp_scsictrl_0, SCSI_RST);
3611 scsiID = RD_HARPOON(port + hp_seltimeout);
3612 WR_HARPOON(port + hp_seltimeout, TO_5ms);
3613 WRW_HARPOON((port + hp_intstat), TIMEOUT);
3615 WR_HARPOON(port + hp_portctrl_0, (SCSI_PORT | START_TO));
3617 while (!(RDW_HARPOON((port + hp_intstat)) & TIMEOUT)) {
3620 WR_HARPOON(port + hp_seltimeout, scsiID);
3622 WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
3624 FPT_Wait(port, TO_5ms);
3626 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
3628 WR_HARPOON(port + hp_int_mask, (RD_HARPOON(port + hp_int_mask) | 0x00));
3630 for (scsiID = 0; scsiID < MAX_SCSI_TAR; scsiID++) {
3631 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
3633 if (currTar_Info->TarEEValue & EE_SYNC_MASK) {
3634 currTar_Info->TarSyncCtrl = 0;
3635 currTar_Info->TarStatus &= ~TAR_SYNC_MASK;
3638 if (currTar_Info->TarEEValue & EE_WIDE_SCSI) {
3639 currTar_Info->TarStatus &= ~TAR_WIDE_MASK;
3642 FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
3644 FPT_SccbMgrTableInitTarget(p_card, scsiID);
3647 FPT_BL_Card[p_card].scanIndex = 0x00;
3648 FPT_BL_Card[p_card].currentSCCB = NULL;
3649 FPT_BL_Card[p_card].globalFlags &= ~(F_TAG_STARTED | F_HOST_XFER_ACT
3651 FPT_BL_Card[p_card].cmdCounter = 0x00;
3652 FPT_BL_Card[p_card].discQCount = 0x00;
3653 FPT_BL_Card[p_card].tagQ_Lst = 0x01;
3655 for (i = 0; i < QUEUE_DEPTH; i++)
3656 FPT_BL_Card[p_card].discQ_Tbl[i] = NULL;
3658 WR_HARPOON(port + hp_page_ctrl,
3659 (RD_HARPOON(port + hp_page_ctrl) & ~G_INT_DISABLE));
3663 /*---------------------------------------------------------------------
3665 * Function: FPT_ssenss
3667 * Description: Setup for the Auto Sense command.
3669 *---------------------------------------------------------------------*/
3670 static void FPT_ssenss(struct sccb_card *pCurrCard)
3673 struct sccb *currSCCB;
3675 currSCCB = pCurrCard->currentSCCB;
3677 currSCCB->Save_CdbLen = currSCCB->CdbLength;
3679 for (i = 0; i < 6; i++) {
3681 currSCCB->Save_Cdb[i] = currSCCB->Cdb[i];
3684 currSCCB->CdbLength = SIX_BYTE_CMD;
3685 currSCCB->Cdb[0] = SCSI_REQUEST_SENSE;
3686 currSCCB->Cdb[1] = currSCCB->Cdb[1] & (unsigned char)0xE0; /*Keep LUN. */
3687 currSCCB->Cdb[2] = 0x00;
3688 currSCCB->Cdb[3] = 0x00;
3689 currSCCB->Cdb[4] = currSCCB->RequestSenseLength;
3690 currSCCB->Cdb[5] = 0x00;
3692 currSCCB->Sccb_XferCnt = (u32)currSCCB->RequestSenseLength;
3694 currSCCB->Sccb_ATC = 0x00;
3696 currSCCB->Sccb_XferState |= F_AUTO_SENSE;
3698 currSCCB->Sccb_XferState &= ~F_SG_XFER;
3700 currSCCB->Sccb_idmsg = currSCCB->Sccb_idmsg & ~(unsigned char)DISC_PRIV;
3702 currSCCB->ControlByte = 0x00;
3704 currSCCB->Sccb_MGRFlags &= F_STATUSLOADED;
3707 /*---------------------------------------------------------------------
3709 * Function: FPT_sxfrp
3711 * Description: Transfer data into the bit bucket until the device
3712 * decides to switch phase.
3714 *---------------------------------------------------------------------*/
3716 static void FPT_sxfrp(u32 p_port, unsigned char p_card)
3718 unsigned char curr_phz;
3720 DISABLE_AUTO(p_port);
3722 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
3724 FPT_hostDataXferAbort(p_port, p_card,
3725 FPT_BL_Card[p_card].currentSCCB);
3729 /* If the Automation handled the end of the transfer then do not
3730 match the phase or we will get out of sync with the ISR. */
3732 if (RDW_HARPOON((p_port + hp_intstat)) &
3733 (BUS_FREE | XFER_CNT_0 | AUTO_INT))
3736 WR_HARPOON(p_port + hp_xfercnt_0, 0x00);
3738 curr_phz = RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ;
3740 WRW_HARPOON((p_port + hp_intstat), XFER_CNT_0);
3742 WR_HARPOON(p_port + hp_scsisig, curr_phz);
3744 while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET)) &&
3746 (RD_HARPOON(p_port + hp_scsisig) & (unsigned char)S_SCSI_PHZ)))
3748 if (curr_phz & (unsigned char)SCSI_IOBIT) {
3749 WR_HARPOON(p_port + hp_portctrl_0,
3750 (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3752 if (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3753 RD_HARPOON(p_port + hp_fifodata_0);
3756 WR_HARPOON(p_port + hp_portctrl_0,
3757 (SCSI_PORT | HOST_PORT | HOST_WRT));
3758 if (RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY) {
3759 WR_HARPOON(p_port + hp_fifodata_0, 0xFA);
3762 } /* End of While loop for padding data I/O phase */
3764 while (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3765 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ)
3769 WR_HARPOON(p_port + hp_portctrl_0,
3770 (SCSI_PORT | HOST_PORT | SCSI_INBIT));
3771 while (!(RD_HARPOON(p_port + hp_xferstat) & FIFO_EMPTY)) {
3772 RD_HARPOON(p_port + hp_fifodata_0);
3775 if (!(RDW_HARPOON((p_port + hp_intstat)) & (BUS_FREE | RESET))) {
3776 WR_HARPOON(p_port + hp_autostart_0,
3777 (AUTO_IMMED + DISCONNECT_START));
3778 while (!(RDW_HARPOON((p_port + hp_intstat)) & AUTO_INT)) {
3781 if (RDW_HARPOON((p_port + hp_intstat)) &
3782 (ICMD_COMP | ITAR_DISC))
3784 (RDW_HARPOON((p_port + hp_intstat)) &
3785 (BUS_FREE | RSEL))) ;
3789 /*---------------------------------------------------------------------
3791 * Function: FPT_schkdd
3793 * Description: Make sure data has been flushed from both FIFOs and abort
3794 * the operations if necessary.
3796 *---------------------------------------------------------------------*/
3798 static void FPT_schkdd(u32 port, unsigned char p_card)
3800 unsigned short TimeOutLoop;
3801 unsigned char sPhase;
3803 struct sccb *currSCCB;
3805 currSCCB = FPT_BL_Card[p_card].currentSCCB;
3807 if ((currSCCB->Sccb_scsistat != DATA_OUT_ST) &&
3808 (currSCCB->Sccb_scsistat != DATA_IN_ST)) {
3812 if (currSCCB->Sccb_XferState & F_ODD_BALL_CNT) {
3814 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - 1);
3816 currSCCB->Sccb_XferCnt = 1;
3818 currSCCB->Sccb_XferState &= ~F_ODD_BALL_CNT;
3819 WRW_HARPOON((port + hp_fiforead), (unsigned short)0x00);
3820 WR_HARPOON(port + hp_xferstat, 0x00);
3825 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
3827 currSCCB->Sccb_XferCnt = 0;
3830 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
3831 (currSCCB->HostStatus == SCCB_COMPLETE)) {
3833 currSCCB->HostStatus = SCCB_PARITY_ERR;
3834 WRW_HARPOON((port + hp_intstat), PARITY);
3837 FPT_hostDataXferAbort(port, p_card, currSCCB);
3839 while (RD_HARPOON(port + hp_scsisig) & SCSI_ACK) {
3844 while (RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY) {
3845 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
3848 if (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) {
3851 if (RDW_HARPOON((port + hp_intstat)) & RESET) {
3854 if ((RD_HARPOON(port + hp_scsisig) & SCSI_REQ)
3855 || (TimeOutLoop++ > 0x3000))
3859 sPhase = RD_HARPOON(port + hp_scsisig) & (SCSI_BSY | S_SCSI_PHZ);
3860 if ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) ||
3861 (RD_HARPOON(port + hp_offsetctr) & (unsigned char)0x1F) ||
3862 (sPhase == (SCSI_BSY | S_DATAO_PH)) ||
3863 (sPhase == (SCSI_BSY | S_DATAI_PH))) {
3865 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
3867 if (!(currSCCB->Sccb_XferState & F_ALL_XFERRED)) {
3868 if (currSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
3869 FPT_phaseDataIn(port, p_card);
3873 FPT_phaseDataOut(port, p_card);
3876 FPT_sxfrp(port, p_card);
3877 if (!(RDW_HARPOON((port + hp_intstat)) &
3878 (BUS_FREE | ICMD_COMP | ITAR_DISC | RESET))) {
3879 WRW_HARPOON((port + hp_intstat), AUTO_INT);
3880 FPT_phaseDecode(port, p_card);
3887 WR_HARPOON(port + hp_portctrl_0, 0x00);
3891 /*---------------------------------------------------------------------
3893 * Function: FPT_sinits
3895 * Description: Setup SCCB manager fields in this SCCB.
3897 *---------------------------------------------------------------------*/
3899 static void FPT_sinits(struct sccb *p_sccb, unsigned char p_card)
3901 struct sccb_mgr_tar_info *currTar_Info;
3903 if ((p_sccb->TargID >= MAX_SCSI_TAR) || (p_sccb->Lun >= MAX_LUN)) {
3906 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
3908 p_sccb->Sccb_XferState = 0x00;
3909 p_sccb->Sccb_XferCnt = p_sccb->DataLength;
3911 if ((p_sccb->OperationCode == SCATTER_GATHER_COMMAND) ||
3912 (p_sccb->OperationCode == RESIDUAL_SG_COMMAND)) {
3914 p_sccb->Sccb_SGoffset = 0;
3915 p_sccb->Sccb_XferState = F_SG_XFER;
3916 p_sccb->Sccb_XferCnt = 0x00;
3919 if (p_sccb->DataLength == 0x00)
3921 p_sccb->Sccb_XferState |= F_ALL_XFERRED;
3923 if (p_sccb->ControlByte & F_USE_CMD_Q) {
3924 if ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) == TAG_Q_REJECT)
3925 p_sccb->ControlByte &= ~F_USE_CMD_Q;
3928 currTar_Info->TarStatus |= TAG_Q_TRYING;
3931 /* For !single SCSI device in system & device allow Disconnect
3932 or command is tag_q type then send Cmd with Disconnect Enable
3933 else send Cmd with Disconnect Disable */
3936 if (((!(FPT_BL_Card[p_card].globalFlags & F_SINGLE_DEVICE)) &&
3937 (currTar_Info->TarStatus & TAR_ALLOW_DISC)) ||
3938 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3940 if ((currTar_Info->TarStatus & TAR_ALLOW_DISC) ||
3941 (currTar_Info->TarStatus & TAG_Q_TRYING)) {
3942 p_sccb->Sccb_idmsg =
3943 (unsigned char)(SMIDENT | DISC_PRIV) | p_sccb->Lun;
3948 p_sccb->Sccb_idmsg = (unsigned char)SMIDENT | p_sccb->Lun;
3951 p_sccb->HostStatus = 0x00;
3952 p_sccb->TargetStatus = 0x00;
3953 p_sccb->Sccb_tag = 0x00;
3954 p_sccb->Sccb_MGRFlags = 0x00;
3955 p_sccb->Sccb_sgseg = 0x00;
3956 p_sccb->Sccb_ATC = 0x00;
3957 p_sccb->Sccb_savedATC = 0x00;
3959 p_sccb->SccbVirtDataPtr = 0x00;
3960 p_sccb->Sccb_forwardlink = NULL;
3961 p_sccb->Sccb_backlink = NULL;
3963 p_sccb->Sccb_scsistat = BUS_FREE_ST;
3964 p_sccb->SccbStatus = SCCB_IN_PROCESS;
3965 p_sccb->Sccb_scsimsg = SMNO_OP;
3969 /*---------------------------------------------------------------------
3971 * Function: Phase Decode
3973 * Description: Determine the phase and call the appropriate function.
3975 *---------------------------------------------------------------------*/
3977 static void FPT_phaseDecode(u32 p_port, unsigned char p_card)
3979 unsigned char phase_ref;
3980 void (*phase) (u32, unsigned char);
3982 DISABLE_AUTO(p_port);
3985 (unsigned char)(RD_HARPOON(p_port + hp_scsisig) & S_SCSI_PHZ);
3987 phase = FPT_s_PhaseTbl[phase_ref];
3989 (*phase) (p_port, p_card); /* Call the correct phase func */
3992 /*---------------------------------------------------------------------
3994 * Function: Data Out Phase
3996 * Description: Start up both the BusMaster and Xbow.
3998 *---------------------------------------------------------------------*/
4000 static void FPT_phaseDataOut(u32 port, unsigned char p_card)
4003 struct sccb *currSCCB;
4005 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4006 if (currSCCB == NULL) {
4007 return; /* Exit if No SCCB record */
4010 currSCCB->Sccb_scsistat = DATA_OUT_ST;
4011 currSCCB->Sccb_XferState &= ~(F_HOST_XFER_DIR | F_NO_DATA_YET);
4013 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4015 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4017 WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4019 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4021 if (currSCCB->Sccb_XferCnt == 0) {
4023 if ((currSCCB->ControlByte & SCCB_DATA_XFER_OUT) &&
4024 (currSCCB->HostStatus == SCCB_COMPLETE))
4025 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4027 FPT_sxfrp(port, p_card);
4028 if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4029 FPT_phaseDecode(port, p_card);
4033 /*---------------------------------------------------------------------
4035 * Function: Data In Phase
4037 * Description: Startup the BusMaster and the XBOW.
4039 *---------------------------------------------------------------------*/
4041 static void FPT_phaseDataIn(u32 port, unsigned char p_card)
4044 struct sccb *currSCCB;
4046 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4048 if (currSCCB == NULL) {
4049 return; /* Exit if No SCCB record */
4052 currSCCB->Sccb_scsistat = DATA_IN_ST;
4053 currSCCB->Sccb_XferState |= F_HOST_XFER_DIR;
4054 currSCCB->Sccb_XferState &= ~F_NO_DATA_YET;
4056 WR_HARPOON(port + hp_portctrl_0, SCSI_PORT);
4058 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4060 WR_HARPOON(port + hp_autostart_0, (END_DATA + END_DATA_START));
4062 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4064 if (currSCCB->Sccb_XferCnt == 0) {
4066 if ((currSCCB->ControlByte & SCCB_DATA_XFER_IN) &&
4067 (currSCCB->HostStatus == SCCB_COMPLETE))
4068 currSCCB->HostStatus = SCCB_DATA_OVER_RUN;
4070 FPT_sxfrp(port, p_card);
4071 if (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | RESET)))
4072 FPT_phaseDecode(port, p_card);
4077 /*---------------------------------------------------------------------
4079 * Function: Command Phase
4081 * Description: Load the CDB into the automation and start it up.
4083 *---------------------------------------------------------------------*/
4085 static void FPT_phaseCommand(u32 p_port, unsigned char p_card)
4087 struct sccb *currSCCB;
4091 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4093 if (currSCCB->OperationCode == RESET_COMMAND) {
4095 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4096 currSCCB->CdbLength = SIX_BYTE_CMD;
4099 WR_HARPOON(p_port + hp_scsisig, 0x00);
4101 ARAM_ACCESS(p_port);
4103 cdb_reg = p_port + CMD_STRT;
4105 for (i = 0; i < currSCCB->CdbLength; i++) {
4107 if (currSCCB->OperationCode == RESET_COMMAND)
4109 WRW_HARPOON(cdb_reg, (MPM_OP + ACOMMAND + 0x00));
4112 WRW_HARPOON(cdb_reg,
4113 (MPM_OP + ACOMMAND + currSCCB->Cdb[i]));
4117 if (currSCCB->CdbLength != TWELVE_BYTE_CMD)
4118 WRW_HARPOON(cdb_reg, (BRH_OP + ALWAYS + NP));
4120 WR_HARPOON(p_port + hp_portctrl_0, (SCSI_PORT));
4122 currSCCB->Sccb_scsistat = COMMAND_ST;
4124 WR_HARPOON(p_port + hp_autostart_3, (AUTO_IMMED | CMD_ONLY_STRT));
4125 SGRAM_ACCESS(p_port);
4128 /*---------------------------------------------------------------------
4130 * Function: Status phase
4132 * Description: Bring in the status and command complete message bytes
4134 *---------------------------------------------------------------------*/
4136 static void FPT_phaseStatus(u32 port, unsigned char p_card)
4138 /* Start-up the automation to finish off this command and let the
4139 isr handle the interrupt for command complete when it comes in.
4140 We could wait here for the interrupt to be generated?
4143 WR_HARPOON(port + hp_scsisig, 0x00);
4145 WR_HARPOON(port + hp_autostart_0, (AUTO_IMMED + END_DATA_START));
4148 /*---------------------------------------------------------------------
4150 * Function: Phase Message Out
4152 * Description: Send out our message (if we have one) and handle whatever
4155 *---------------------------------------------------------------------*/
4157 static void FPT_phaseMsgOut(u32 port, unsigned char p_card)
4159 unsigned char message, scsiID;
4160 struct sccb *currSCCB;
4161 struct sccb_mgr_tar_info *currTar_Info;
4163 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4165 if (currSCCB != NULL) {
4167 message = currSCCB->Sccb_scsimsg;
4168 scsiID = currSCCB->TargID;
4170 if (message == SMDEV_RESET) {
4172 currTar_Info = &FPT_sccbMgrTbl[p_card][scsiID];
4173 currTar_Info->TarSyncCtrl = 0;
4174 FPT_sssyncv(port, scsiID, NARROW_SCSI, currTar_Info);
4176 if (FPT_sccbMgrTbl[p_card][scsiID].
4177 TarEEValue & EE_SYNC_MASK) {
4179 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4184 if (FPT_sccbMgrTbl[p_card][scsiID].
4185 TarEEValue & EE_WIDE_SCSI) {
4187 FPT_sccbMgrTbl[p_card][scsiID].TarStatus &=
4191 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4192 FPT_SccbMgrTableInitTarget(p_card, scsiID);
4193 } else if (currSCCB->Sccb_scsistat == ABORT_ST) {
4194 currSCCB->HostStatus = SCCB_COMPLETE;
4195 if (FPT_BL_Card[p_card].discQ_Tbl[currSCCB->Sccb_tag] !=
4197 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4199 FPT_sccbMgrTbl[p_card][scsiID].TarTagQ_Cnt--;
4204 else if (currSCCB->Sccb_scsistat < COMMAND_ST) {
4206 if (message == SMNO_OP) {
4207 currSCCB->Sccb_MGRFlags |= F_DEV_SELECTED;
4209 FPT_ssel(port, p_card);
4214 if (message == SMABORT)
4216 FPT_queueFlushSccb(p_card, SCCB_COMPLETE);
4223 WRW_HARPOON((port + hp_intstat), (BUS_FREE | PHASE | XFER_CNT_0));
4225 WR_HARPOON(port + hp_portctrl_0, SCSI_BUS_EN);
4227 WR_HARPOON(port + hp_scsidata_0, message);
4229 WR_HARPOON(port + hp_scsisig, (SCSI_ACK + S_ILL_PH));
4233 WR_HARPOON(port + hp_portctrl_0, 0x00);
4235 if ((message == SMABORT) || (message == SMDEV_RESET) ||
4236 (message == SMABORT_TAG)) {
4238 while (!(RDW_HARPOON((port + hp_intstat)) & (BUS_FREE | PHASE))) {
4241 if (RDW_HARPOON((port + hp_intstat)) & BUS_FREE) {
4242 WRW_HARPOON((port + hp_intstat), BUS_FREE);
4244 if (currSCCB != NULL) {
4246 if ((FPT_BL_Card[p_card].
4247 globalFlags & F_CONLUN_IO)
4249 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4250 TarStatus & TAR_TAG_Q_MASK) !=
4252 FPT_sccbMgrTbl[p_card][currSCCB->
4254 TarLUNBusy[currSCCB->Lun] = 0;
4256 FPT_sccbMgrTbl[p_card][currSCCB->
4260 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
4265 FPT_BL_Card[p_card].globalFlags |=
4272 FPT_sxfrp(port, p_card);
4278 if (message == SMPARITY) {
4279 currSCCB->Sccb_scsimsg = SMNO_OP;
4280 WR_HARPOON(port + hp_autostart_1,
4281 (AUTO_IMMED + DISCONNECT_START));
4283 FPT_sxfrp(port, p_card);
4288 /*---------------------------------------------------------------------
4290 * Function: Message In phase
4292 * Description: Bring in the message and determine what to do with it.
4294 *---------------------------------------------------------------------*/
4296 static void FPT_phaseMsgIn(u32 port, unsigned char p_card)
4298 unsigned char message;
4299 struct sccb *currSCCB;
4301 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4303 if (FPT_BL_Card[p_card].globalFlags & F_HOST_XFER_ACT) {
4305 FPT_phaseChkFifo(port, p_card);
4308 message = RD_HARPOON(port + hp_scsidata_0);
4309 if ((message == SMDISC) || (message == SMSAVE_DATA_PTR)) {
4311 WR_HARPOON(port + hp_autostart_1,
4312 (AUTO_IMMED + END_DATA_START));
4318 message = FPT_sfm(port, currSCCB);
4321 FPT_sdecm(message, port, p_card);
4324 if (currSCCB->Sccb_scsimsg != SMPARITY)
4326 WR_HARPOON(port + hp_autostart_1,
4327 (AUTO_IMMED + DISCONNECT_START));
4333 /*---------------------------------------------------------------------
4335 * Function: Illegal phase
4337 * Description: Target switched to some illegal phase, so all we can do
4338 * is report an error back to the host (if that is possible)
4339 * and send an ABORT message to the misbehaving target.
4341 *---------------------------------------------------------------------*/
4343 static void FPT_phaseIllegal(u32 port, unsigned char p_card)
4345 struct sccb *currSCCB;
4347 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4349 WR_HARPOON(port + hp_scsisig, RD_HARPOON(port + hp_scsisig));
4350 if (currSCCB != NULL) {
4352 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4353 currSCCB->Sccb_scsistat = ABORT_ST;
4354 currSCCB->Sccb_scsimsg = SMABORT;
4357 ACCEPT_MSG_ATN(port);
4360 /*---------------------------------------------------------------------
4362 * Function: Phase Check FIFO
4364 * Description: Make sure data has been flushed from both FIFOs and abort
4365 * the operations if necessary.
4367 *---------------------------------------------------------------------*/
4369 static void FPT_phaseChkFifo(u32 port, unsigned char p_card)
4372 struct sccb *currSCCB;
4374 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4376 if (currSCCB->Sccb_scsistat == DATA_IN_ST) {
4378 while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) &&
4379 (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)) {
4382 if (!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY)) {
4383 currSCCB->Sccb_ATC += currSCCB->Sccb_XferCnt;
4385 currSCCB->Sccb_XferCnt = 0;
4387 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4388 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4389 currSCCB->HostStatus = SCCB_PARITY_ERR;
4390 WRW_HARPOON((port + hp_intstat), PARITY);
4393 FPT_hostDataXferAbort(port, p_card, currSCCB);
4395 FPT_dataXferProcessor(port, &FPT_BL_Card[p_card]);
4397 while ((!(RD_HARPOON(port + hp_xferstat) & FIFO_EMPTY))
4398 && (RD_HARPOON(port + hp_ext_status) &
4405 /*End Data In specific code. */
4406 GET_XFER_CNT(port, xfercnt);
4408 WR_HARPOON(port + hp_xfercnt_0, 0x00);
4410 WR_HARPOON(port + hp_portctrl_0, 0x00);
4412 currSCCB->Sccb_ATC += (currSCCB->Sccb_XferCnt - xfercnt);
4414 currSCCB->Sccb_XferCnt = xfercnt;
4416 if ((RDW_HARPOON((port + hp_intstat)) & PARITY) &&
4417 (currSCCB->HostStatus == SCCB_COMPLETE)) {
4419 currSCCB->HostStatus = SCCB_PARITY_ERR;
4420 WRW_HARPOON((port + hp_intstat), PARITY);
4423 FPT_hostDataXferAbort(port, p_card, currSCCB);
4425 WR_HARPOON(port + hp_fifowrite, 0x00);
4426 WR_HARPOON(port + hp_fiforead, 0x00);
4427 WR_HARPOON(port + hp_xferstat, 0x00);
4429 WRW_HARPOON((port + hp_intstat), XFER_CNT_0);
4432 /*---------------------------------------------------------------------
4434 * Function: Phase Bus Free
4436 * Description: We just went bus free so figure out if it was
4437 * because of command complete or from a disconnect.
4439 *---------------------------------------------------------------------*/
4440 static void FPT_phaseBusFree(u32 port, unsigned char p_card)
4442 struct sccb *currSCCB;
4444 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4446 if (currSCCB != NULL) {
4450 if (currSCCB->OperationCode == RESET_COMMAND) {
4452 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4453 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4454 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4455 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4456 TarLUNBusy[currSCCB->Lun] = 0;
4458 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4461 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4464 FPT_queueSearchSelect(&FPT_BL_Card[p_card], p_card);
4468 else if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4469 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4470 (unsigned char)SYNC_SUPPORTED;
4471 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4475 else if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4476 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4477 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4478 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4480 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4484 else if (currSCCB->Sccb_scsistat == SELECT_Q_ST) {
4485 /* Make sure this is not a phony BUS_FREE. If we were
4486 reselected or if BUSY is NOT on then this is a
4487 valid BUS FREE. SRR Wednesday, 5/10/1995. */
4489 if ((!(RD_HARPOON(port + hp_scsisig) & SCSI_BSY)) ||
4490 (RDW_HARPOON((port + hp_intstat)) & RSEL)) {
4491 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4492 TarStatus &= ~TAR_TAG_Q_MASK;
4493 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4494 TarStatus |= TAG_Q_REJECT;
4504 currSCCB->Sccb_scsistat = BUS_FREE_ST;
4506 if (!currSCCB->HostStatus) {
4507 currSCCB->HostStatus = SCCB_PHASE_SEQUENCE_FAIL;
4510 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4511 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4512 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4513 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4514 TarLUNBusy[currSCCB->Lun] = 0;
4516 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4519 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB,
4524 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4526 } /*end if !=null */
4529 /*---------------------------------------------------------------------
4531 * Function: Auto Load Default Map
4533 * Description: Load the Automation RAM with the default map values.
4535 *---------------------------------------------------------------------*/
4536 static void FPT_autoLoadDefaultMap(u32 p_port)
4540 ARAM_ACCESS(p_port);
4541 map_addr = p_port + hp_aramBase;
4543 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0xC0)); /*ID MESSAGE */
4545 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x20)); /*SIMPLE TAG QUEUEING MSG */
4547 WRW_HARPOON(map_addr, RAT_OP); /*RESET ATTENTION */
4549 WRW_HARPOON(map_addr, (MPM_OP + AMSG_OUT + 0x00)); /*TAG ID MSG */
4551 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 0 */
4553 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 1 */
4555 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 2 */
4557 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 3 */
4559 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 4 */
4561 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 5 */
4563 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 6 */
4565 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 7 */
4567 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 8 */
4569 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 9 */
4571 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 10 */
4573 WRW_HARPOON(map_addr, (MPM_OP + ACOMMAND + 0x00)); /*CDB BYTE 11 */
4575 WRW_HARPOON(map_addr, (CPE_OP + ADATA_OUT + DINT)); /*JUMP IF DATA OUT */
4577 WRW_HARPOON(map_addr, (TCB_OP + FIFO_0 + DI)); /*JUMP IF NO DATA IN FIFO */
4578 map_addr += 2; /*This means AYNC DATA IN */
4579 WRW_HARPOON(map_addr, (SSI_OP + SSI_IDO_STRT)); /*STOP AND INTERRUPT */
4581 WRW_HARPOON(map_addr, (CPE_OP + ADATA_IN + DINT)); /*JUMP IF NOT DATA IN PHZ */
4583 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK 4 DATA IN */
4585 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x02)); /*SAVE DATA PTR MSG? */
4587 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + DC)); /*GO CHECK FOR DISCONNECT MSG */
4589 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR1)); /*SAVE DATA PTRS MSG */
4591 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + ST)); /*IF NOT MSG IN CHECK DATA IN */
4593 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x04)); /*DISCONNECT MSG? */
4595 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + UNKNWN)); /*UKNKNOWN MSG */
4597 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*XFER DISCONNECT MSG */
4599 WRW_HARPOON(map_addr, (SSI_OP + SSI_ITAR_DISC)); /*STOP AND INTERRUPT */
4601 WRW_HARPOON(map_addr, (CPN_OP + ASTATUS + UNKNWN)); /*JUMP IF NOT STATUS PHZ. */
4603 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_AR0)); /*GET STATUS BYTE */
4605 WRW_HARPOON(map_addr, (CPN_OP + AMSG_IN + CC)); /*ERROR IF NOT MSG IN PHZ */
4607 WRW_HARPOON(map_addr, (CRD_OP + SDATA + 0x00)); /*CHECK FOR CMD COMPLETE MSG. */
4609 WRW_HARPOON(map_addr, (BRH_OP + NOT_EQ + CC)); /*ERROR IF NOT CMD COMPLETE MSG. */
4611 WRW_HARPOON(map_addr, (MRR_OP + SDATA + D_BUCKET)); /*GET CMD COMPLETE MSG */
4613 WRW_HARPOON(map_addr, (SSI_OP + SSI_ICMD_COMP)); /*END OF COMMAND */
4616 WRW_HARPOON(map_addr, (SSI_OP + SSI_IUNKWN)); /*RECEIVED UNKNOWN MSG BYTE */
4618 WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4620 WRW_HARPOON(map_addr, (SSI_OP + SSI_ITICKLE)); /*BIOS Tickled the Mgr */
4622 WRW_HARPOON(map_addr, (SSI_OP + SSI_IRFAIL)); /*EXPECTED ID/TAG MESSAGES AND */
4623 map_addr += 2; /* DIDN'T GET ONE */
4624 WRW_HARPOON(map_addr, (CRR_OP + AR3 + S_IDREG)); /* comp SCSI SEL ID & AR3 */
4626 WRW_HARPOON(map_addr, (BRH_OP + EQUAL + 0x00)); /*SEL ID OK then Conti. */
4628 WRW_HARPOON(map_addr, (SSI_OP + SSI_INO_CC)); /*NO COMMAND COMPLETE AFTER STATUS */
4630 SGRAM_ACCESS(p_port);
4633 /*---------------------------------------------------------------------
4635 * Function: Auto Command Complete
4637 * Description: Post command back to host and find another command
4640 *---------------------------------------------------------------------*/
4642 static void FPT_autoCmdCmplt(u32 p_port, unsigned char p_card)
4644 struct sccb *currSCCB;
4645 unsigned char status_byte;
4647 currSCCB = FPT_BL_Card[p_card].currentSCCB;
4649 status_byte = RD_HARPOON(p_port + hp_gp_reg_0);
4651 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUN_CA = 0;
4653 if (status_byte != SSGOOD) {
4655 if (status_byte == SSQ_FULL) {
4657 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4658 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4659 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4660 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4661 TarLUNBusy[currSCCB->Lun] = 1;
4662 if (FPT_BL_Card[p_card].discQCount != 0)
4663 FPT_BL_Card[p_card].discQCount--;
4664 FPT_BL_Card[p_card].
4665 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4667 LunDiscQ_Idx[currSCCB->Lun]] =
4670 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4672 if (currSCCB->Sccb_tag) {
4673 if (FPT_BL_Card[p_card].discQCount != 0)
4674 FPT_BL_Card[p_card].
4676 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4680 if (FPT_BL_Card[p_card].discQCount != 0)
4681 FPT_BL_Card[p_card].
4683 FPT_BL_Card[p_card].
4684 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4686 LunDiscQ_Idx[0]] = NULL;
4690 currSCCB->Sccb_MGRFlags |= F_STATUSLOADED;
4692 FPT_queueSelectFail(&FPT_BL_Card[p_card], p_card);
4697 if (currSCCB->Sccb_scsistat == SELECT_SN_ST) {
4698 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus |=
4699 (unsigned char)SYNC_SUPPORTED;
4701 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4703 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4705 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4706 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4707 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4708 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4709 TarLUNBusy[currSCCB->Lun] = 1;
4710 if (FPT_BL_Card[p_card].discQCount != 0)
4711 FPT_BL_Card[p_card].discQCount--;
4712 FPT_BL_Card[p_card].
4713 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4715 LunDiscQ_Idx[currSCCB->Lun]] =
4718 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4720 if (currSCCB->Sccb_tag) {
4721 if (FPT_BL_Card[p_card].discQCount != 0)
4722 FPT_BL_Card[p_card].
4724 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4728 if (FPT_BL_Card[p_card].discQCount != 0)
4729 FPT_BL_Card[p_card].
4731 FPT_BL_Card[p_card].
4732 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4734 LunDiscQ_Idx[0]] = NULL;
4741 if (currSCCB->Sccb_scsistat == SELECT_WN_ST) {
4743 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarStatus =
4744 (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4745 TarStatus & ~WIDE_ENABLED) | WIDE_NEGOCIATED;
4747 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarEEValue &=
4749 FPT_BL_Card[p_card].globalFlags |= F_NEW_SCCB_CMD;
4751 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4752 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4753 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
4754 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4755 TarLUNBusy[currSCCB->Lun] = 1;
4756 if (FPT_BL_Card[p_card].discQCount != 0)
4757 FPT_BL_Card[p_card].discQCount--;
4758 FPT_BL_Card[p_card].
4759 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4761 LunDiscQ_Idx[currSCCB->Lun]] =
4764 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4766 if (currSCCB->Sccb_tag) {
4767 if (FPT_BL_Card[p_card].discQCount != 0)
4768 FPT_BL_Card[p_card].
4770 FPT_BL_Card[p_card].discQ_Tbl[currSCCB->
4774 if (FPT_BL_Card[p_card].discQCount != 0)
4775 FPT_BL_Card[p_card].
4777 FPT_BL_Card[p_card].
4778 discQ_Tbl[FPT_sccbMgrTbl[p_card]
4780 LunDiscQ_Idx[0]] = NULL;
4787 if (status_byte == SSCHECK) {
4788 if (FPT_BL_Card[p_card].globalFlags & F_DO_RENEGO) {
4789 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4790 TarEEValue & EE_SYNC_MASK) {
4791 FPT_sccbMgrTbl[p_card][currSCCB->
4793 TarStatus &= ~TAR_SYNC_MASK;
4795 if (FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4796 TarEEValue & EE_WIDE_SCSI) {
4797 FPT_sccbMgrTbl[p_card][currSCCB->
4799 TarStatus &= ~TAR_WIDE_MASK;
4804 if (!(currSCCB->Sccb_XferState & F_AUTO_SENSE)) {
4806 currSCCB->SccbStatus = SCCB_ERROR;
4807 currSCCB->TargetStatus = status_byte;
4809 if (status_byte == SSCHECK) {
4811 FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4814 if (currSCCB->RequestSenseLength !=
4815 NO_AUTO_REQUEST_SENSE) {
4817 if (currSCCB->RequestSenseLength == 0)
4818 currSCCB->RequestSenseLength =
4821 FPT_ssenss(&FPT_BL_Card[p_card]);
4822 FPT_BL_Card[p_card].globalFlags |=
4825 if (((FPT_BL_Card[p_card].
4826 globalFlags & F_CONLUN_IO)
4828 ((FPT_sccbMgrTbl[p_card]
4830 TarStatus & TAR_TAG_Q_MASK) !=
4832 FPT_sccbMgrTbl[p_card]
4834 TarLUNBusy[currSCCB->Lun] =
4836 if (FPT_BL_Card[p_card].
4838 FPT_BL_Card[p_card].
4840 FPT_BL_Card[p_card].
4841 discQ_Tbl[FPT_sccbMgrTbl
4849 FPT_sccbMgrTbl[p_card]
4852 if (currSCCB->Sccb_tag) {
4853 if (FPT_BL_Card[p_card].
4858 FPT_BL_Card[p_card].
4859 discQ_Tbl[currSCCB->
4863 if (FPT_BL_Card[p_card].
4868 FPT_BL_Card[p_card].
4883 if ((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
4884 ((FPT_sccbMgrTbl[p_card][currSCCB->TargID].
4885 TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))
4886 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[currSCCB->
4889 FPT_sccbMgrTbl[p_card][currSCCB->TargID].TarLUNBusy[0] = 0;
4891 FPT_queueCmdComplete(&FPT_BL_Card[p_card], currSCCB, p_card);
4894 #define SHORT_WAIT 0x0000000F
4895 #define LONG_WAIT 0x0000FFFFL
4897 /*---------------------------------------------------------------------
4899 * Function: Data Transfer Processor
4901 * Description: This routine performs two tasks.
4902 * (1) Start data transfer by calling HOST_DATA_XFER_START
4903 * function. Once data transfer is started, (2) Depends
4904 * on the type of data transfer mode Scatter/Gather mode
4905 * or NON Scatter/Gather mode. In NON Scatter/Gather mode,
4906 * this routine checks Sccb_MGRFlag (F_HOST_XFER_ACT bit) for
4907 * data transfer done. In Scatter/Gather mode, this routine
4908 * checks bus master command complete and dual rank busy
4909 * bit to keep chaining SC transfer command. Similarly,
4910 * in Scatter/Gather mode, it checks Sccb_MGRFlag
4911 * (F_HOST_XFER_ACT bit) for data transfer done.
4913 *---------------------------------------------------------------------*/
4915 static void FPT_dataXferProcessor(u32 port, struct sccb_card *pCurrCard)
4917 struct sccb *currSCCB;
4919 currSCCB = pCurrCard->currentSCCB;
4921 if (currSCCB->Sccb_XferState & F_SG_XFER) {
4922 if (pCurrCard->globalFlags & F_HOST_XFER_ACT)
4924 currSCCB->Sccb_sgseg += (unsigned char)SG_BUF_CNT;
4925 currSCCB->Sccb_SGoffset = 0x00;
4927 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4929 FPT_busMstrSGDataXferStart(port, currSCCB);
4933 if (!(pCurrCard->globalFlags & F_HOST_XFER_ACT)) {
4934 pCurrCard->globalFlags |= F_HOST_XFER_ACT;
4936 FPT_busMstrDataXferStart(port, currSCCB);
4941 /*---------------------------------------------------------------------
4943 * Function: BusMaster Scatter Gather Data Transfer Start
4947 *---------------------------------------------------------------------*/
4948 static void FPT_busMstrSGDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
4950 u32 count, addr, tmpSGCnt;
4951 unsigned int sg_index;
4952 unsigned char sg_count, i;
4954 struct blogic_sg_seg *segp;
4956 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)
4957 count = ((u32)HOST_RD_CMD) << 24;
4959 count = ((u32)HOST_WRT_CMD) << 24;
4963 sg_index = pcurrSCCB->Sccb_sgseg;
4964 reg_offset = hp_aramBase;
4966 i = (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
4967 ~(SGRAM_ARAM | SCATTER_EN));
4969 WR_HARPOON(p_port + hp_page_ctrl, i);
4971 while ((sg_count < (unsigned char)SG_BUF_CNT) &&
4972 ((sg_index * (unsigned int)SG_ELEMENT_SIZE) <
4973 pcurrSCCB->DataLength)) {
4975 segp = (struct blogic_sg_seg *)(pcurrSCCB->DataPointer) +
4977 tmpSGCnt += segp->segbytes;
4978 count |= segp->segbytes;
4979 addr = segp->segdata;
4981 if ((!sg_count) && (pcurrSCCB->Sccb_SGoffset)) {
4983 ((count & 0x00FFFFFFL) - pcurrSCCB->Sccb_SGoffset);
4985 (count & 0xFF000000L) | pcurrSCCB->Sccb_SGoffset;
4986 tmpSGCnt = count & 0x00FFFFFFL;
4989 WR_HARP32(p_port, reg_offset, addr);
4992 WR_HARP32(p_port, reg_offset, count);
4995 count &= 0xFF000000L;
5001 pcurrSCCB->Sccb_XferCnt = tmpSGCnt;
5003 WR_HARPOON(p_port + hp_sg_addr, (sg_count << 4));
5005 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5007 WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
5009 WR_HARPOON(p_port + hp_portctrl_0,
5010 (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5011 WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5016 if ((!(RD_HARPOON(p_port + hp_synctarg_0) & NARROW_SCSI)) &&
5017 (tmpSGCnt & 0x000000001)) {
5019 pcurrSCCB->Sccb_XferState |= F_ODD_BALL_CNT;
5023 WR_HARP32(p_port, hp_xfercnt_0, tmpSGCnt);
5025 WR_HARPOON(p_port + hp_portctrl_0,
5026 (SCSI_PORT | DMA_PORT | DMA_RD));
5027 WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5030 WR_HARPOON(p_port + hp_page_ctrl, (unsigned char)(i | SCATTER_EN));
5034 /*---------------------------------------------------------------------
5036 * Function: BusMaster Data Transfer Start
5040 *---------------------------------------------------------------------*/
5041 static void FPT_busMstrDataXferStart(u32 p_port, struct sccb *pcurrSCCB)
5045 if (!(pcurrSCCB->Sccb_XferState & F_AUTO_SENSE)) {
5047 count = pcurrSCCB->Sccb_XferCnt;
5049 addr = (u32)(unsigned long)pcurrSCCB->DataPointer + pcurrSCCB->Sccb_ATC;
5053 addr = pcurrSCCB->SensePointer;
5054 count = pcurrSCCB->RequestSenseLength;
5058 HP_SETUP_ADDR_CNT(p_port, addr, count);
5060 if (pcurrSCCB->Sccb_XferState & F_HOST_XFER_DIR) {
5062 WR_HARPOON(p_port + hp_portctrl_0,
5063 (DMA_PORT | SCSI_PORT | SCSI_INBIT));
5064 WR_HARPOON(p_port + hp_scsisig, S_DATAI_PH);
5066 WR_HARPOON(p_port + hp_xfer_cmd,
5067 (XFER_DMA_HOST | XFER_HOST_AUTO | XFER_DMA_8BIT));
5072 WR_HARPOON(p_port + hp_portctrl_0,
5073 (SCSI_PORT | DMA_PORT | DMA_RD));
5074 WR_HARPOON(p_port + hp_scsisig, S_DATAO_PH);
5076 WR_HARPOON(p_port + hp_xfer_cmd,
5077 (XFER_HOST_DMA | XFER_HOST_AUTO | XFER_DMA_8BIT));
5082 /*---------------------------------------------------------------------
5084 * Function: BusMaster Timeout Handler
5086 * Description: This function is called after a bus master command busy time
5087 * out is detected. This routines issue halt state machine
5088 * with a software time out for command busy. If command busy
5089 * is still asserted at the end of the time out, it issues
5090 * hard abort with another software time out. It hard abort
5091 * command busy is also time out, it'll just give up.
5093 *---------------------------------------------------------------------*/
5094 static unsigned char FPT_busMstrTimeOut(u32 p_port)
5096 unsigned long timeout;
5098 timeout = LONG_WAIT;
5100 WR_HARPOON(p_port + hp_sys_ctrl, HALT_MACH);
5102 while ((!(RD_HARPOON(p_port + hp_ext_status) & CMD_ABORTED))
5106 if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5107 WR_HARPOON(p_port + hp_sys_ctrl, HARD_ABORT);
5109 timeout = LONG_WAIT;
5110 while ((RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY)
5115 RD_HARPOON(p_port + hp_int_status); /*Clear command complete */
5117 if (RD_HARPOON(p_port + hp_ext_status) & BM_CMD_BUSY) {
5126 /*---------------------------------------------------------------------
5128 * Function: Host Data Transfer Abort
5130 * Description: Abort any in progress transfer.
5132 *---------------------------------------------------------------------*/
5133 static void FPT_hostDataXferAbort(u32 port, unsigned char p_card,
5134 struct sccb *pCurrSCCB)
5137 unsigned long timeout;
5138 unsigned long remain_cnt;
5140 struct blogic_sg_seg *segp;
5142 FPT_BL_Card[p_card].globalFlags &= ~F_HOST_XFER_ACT;
5144 if (pCurrSCCB->Sccb_XferState & F_AUTO_SENSE) {
5146 if (!(RD_HARPOON(port + hp_int_status) & INT_CMD_COMPL)) {
5148 WR_HARPOON(port + hp_bm_ctrl,
5149 (RD_HARPOON(port + hp_bm_ctrl) |
5151 timeout = LONG_WAIT;
5153 while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5157 WR_HARPOON(port + hp_bm_ctrl,
5158 (RD_HARPOON(port + hp_bm_ctrl) &
5161 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5163 if (FPT_busMstrTimeOut(port)) {
5165 if (pCurrSCCB->HostStatus == 0x00)
5167 pCurrSCCB->HostStatus =
5172 if (RD_HARPOON(port + hp_int_status) &
5175 if (RD_HARPOON(port + hp_ext_status) &
5178 if (pCurrSCCB->HostStatus ==
5181 pCurrSCCB->HostStatus =
5188 else if (pCurrSCCB->Sccb_XferCnt) {
5190 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5192 WR_HARPOON(port + hp_page_ctrl,
5193 (RD_HARPOON(port + hp_page_ctrl) &
5196 WR_HARPOON(port + hp_sg_addr, 0x00);
5198 sg_ptr = pCurrSCCB->Sccb_sgseg + SG_BUF_CNT;
5201 (unsigned int)(pCurrSCCB->DataLength /
5204 sg_ptr = (u32)(pCurrSCCB->DataLength /
5208 remain_cnt = pCurrSCCB->Sccb_XferCnt;
5210 while (remain_cnt < 0x01000000L) {
5213 segp = (struct blogic_sg_seg *)(pCurrSCCB->
5214 DataPointer) + (sg_ptr * 2);
5215 if (remain_cnt > (unsigned long)segp->segbytes)
5217 (unsigned long)segp->segbytes;
5222 if (remain_cnt < 0x01000000L) {
5224 pCurrSCCB->Sccb_SGoffset = remain_cnt;
5226 pCurrSCCB->Sccb_sgseg = (unsigned short)sg_ptr;
5228 if ((unsigned long)(sg_ptr * SG_ELEMENT_SIZE) ==
5229 pCurrSCCB->DataLength && (remain_cnt == 0))
5231 pCurrSCCB->Sccb_XferState |=
5237 if (pCurrSCCB->HostStatus == 0x00) {
5239 pCurrSCCB->HostStatus =
5245 if (!(pCurrSCCB->Sccb_XferState & F_HOST_XFER_DIR)) {
5247 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5249 FPT_busMstrTimeOut(port);
5254 if (RD_HARPOON(port + hp_int_status) &
5257 if (RD_HARPOON(port + hp_ext_status) &
5260 if (pCurrSCCB->HostStatus ==
5263 pCurrSCCB->HostStatus =
5274 if ((RD_HARPOON(port + hp_fifo_cnt)) >= BM_THRESHOLD) {
5276 timeout = SHORT_WAIT;
5278 while ((RD_HARPOON(port + hp_ext_status) &
5280 && ((RD_HARPOON(port + hp_fifo_cnt)) >=
5281 BM_THRESHOLD) && timeout--) {
5285 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5287 WR_HARPOON(port + hp_bm_ctrl,
5288 (RD_HARPOON(port + hp_bm_ctrl) |
5291 timeout = LONG_WAIT;
5293 while ((RD_HARPOON(port + hp_ext_status) &
5294 BM_CMD_BUSY) && timeout--) {
5297 WR_HARPOON(port + hp_bm_ctrl,
5298 (RD_HARPOON(port + hp_bm_ctrl) &
5301 if (RD_HARPOON(port + hp_ext_status) &
5304 if (pCurrSCCB->HostStatus == 0x00) {
5306 pCurrSCCB->HostStatus =
5310 FPT_busMstrTimeOut(port);
5314 if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5316 if (RD_HARPOON(port + hp_ext_status) &
5319 if (pCurrSCCB->HostStatus == 0x00) {
5321 pCurrSCCB->HostStatus =
5332 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5334 timeout = LONG_WAIT;
5336 while ((RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY)
5340 if (RD_HARPOON(port + hp_ext_status) & BM_CMD_BUSY) {
5342 if (pCurrSCCB->HostStatus == 0x00) {
5344 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5347 FPT_busMstrTimeOut(port);
5351 if (RD_HARPOON(port + hp_int_status) & INT_EXT_STATUS) {
5353 if (RD_HARPOON(port + hp_ext_status) & BAD_EXT_STATUS) {
5355 if (pCurrSCCB->HostStatus == 0x00) {
5357 pCurrSCCB->HostStatus = SCCB_BM_ERR;
5363 if (pCurrSCCB->Sccb_XferState & F_SG_XFER) {
5365 WR_HARPOON(port + hp_page_ctrl,
5366 (RD_HARPOON(port + hp_page_ctrl) &
5369 WR_HARPOON(port + hp_sg_addr, 0x00);
5371 pCurrSCCB->Sccb_sgseg += SG_BUF_CNT;
5373 pCurrSCCB->Sccb_SGoffset = 0x00;
5375 if ((u32)(pCurrSCCB->Sccb_sgseg * SG_ELEMENT_SIZE) >=
5376 pCurrSCCB->DataLength) {
5378 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5379 pCurrSCCB->Sccb_sgseg =
5380 (unsigned short)(pCurrSCCB->DataLength /
5386 if (!(pCurrSCCB->Sccb_XferState & F_AUTO_SENSE))
5387 pCurrSCCB->Sccb_XferState |= F_ALL_XFERRED;
5391 WR_HARPOON(port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
5394 /*---------------------------------------------------------------------
5396 * Function: Host Data Transfer Restart
5398 * Description: Reset the available count due to a restore data
5401 *---------------------------------------------------------------------*/
5402 static void FPT_hostDataXferRestart(struct sccb *currSCCB)
5404 unsigned long data_count;
5405 unsigned int sg_index;
5406 struct blogic_sg_seg *segp;
5408 if (currSCCB->Sccb_XferState & F_SG_XFER) {
5410 currSCCB->Sccb_XferCnt = 0;
5412 sg_index = 0xffff; /*Index by long words into sg list. */
5413 data_count = 0; /*Running count of SG xfer counts. */
5416 while (data_count < currSCCB->Sccb_ATC) {
5419 segp = (struct blogic_sg_seg *)(currSCCB->DataPointer) +
5421 data_count += segp->segbytes;
5424 if (data_count == currSCCB->Sccb_ATC) {
5426 currSCCB->Sccb_SGoffset = 0;
5431 currSCCB->Sccb_SGoffset =
5432 data_count - currSCCB->Sccb_ATC;
5435 currSCCB->Sccb_sgseg = (unsigned short)sg_index;
5439 currSCCB->Sccb_XferCnt =
5440 currSCCB->DataLength - currSCCB->Sccb_ATC;
5444 /*---------------------------------------------------------------------
5446 * Function: FPT_scini
5448 * Description: Setup all data structures necessary for SCAM selection.
5450 *---------------------------------------------------------------------*/
5452 static void FPT_scini(unsigned char p_card, unsigned char p_our_id,
5453 unsigned char p_power_up)
5456 unsigned char loser, assigned_id;
5459 unsigned char i, k, ScamFlg;
5460 struct sccb_card *currCard;
5461 struct nvram_info *pCurrNvRam;
5463 currCard = &FPT_BL_Card[p_card];
5464 p_port = currCard->ioPort;
5465 pCurrNvRam = currCard->pNvRamInfo;
5468 ScamFlg = pCurrNvRam->niScamConf;
5469 i = pCurrNvRam->niSysConf;
5472 (unsigned char)FPT_utilEERead(p_port, SCAM_CONFIG / 2);
5474 char)(FPT_utilEERead(p_port, (SYSTEM_CONFIG / 2)));
5476 if (!(i & 0x02)) /* check if reset bus in AutoSCSI parameter set */
5479 FPT_inisci(p_card, p_port, p_our_id);
5481 /* Force to wait 1 sec after SCSI bus reset. Some SCAM device FW
5482 too slow to return to SCAM selection */
5485 FPT_Wait1Second(p_port);
5487 FPT_Wait(p_port, TO_250ms); */
5489 FPT_Wait1Second(p_port);
5491 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2)) {
5492 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5498 FPT_scxferc(p_port, SYNC_PTRN);
5499 FPT_scxferc(p_port, DOM_MSTR);
5502 &FPT_scamInfo[p_our_id].id_string[0]);
5503 } while (loser == 0xFF);
5507 if ((p_power_up) && (!loser)) {
5508 FPT_sresb(p_port, p_card);
5509 FPT_Wait(p_port, TO_250ms);
5511 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5517 FPT_scxferc(p_port, SYNC_PTRN);
5518 FPT_scxferc(p_port, DOM_MSTR);
5521 &FPT_scamInfo[p_our_id].
5523 } while (loser == 0xFF);
5535 FPT_scamInfo[p_our_id].state = ID_ASSIGNED;
5537 if (ScamFlg & SCAM_ENABLED) {
5539 for (i = 0; i < MAX_SCSI_TAR; i++) {
5540 if ((FPT_scamInfo[i].state == ID_UNASSIGNED) ||
5541 (FPT_scamInfo[i].state == ID_UNUSED)) {
5542 if (FPT_scsell(p_port, i)) {
5543 FPT_scamInfo[i].state = LEGACY;
5544 if ((FPT_scamInfo[i].
5545 id_string[0] != 0xFF)
5546 || (FPT_scamInfo[i].
5547 id_string[1] != 0xFA)) {
5550 id_string[0] = 0xFF;
5552 id_string[1] = 0xFA;
5553 if (pCurrNvRam == NULL)
5563 FPT_sresb(p_port, p_card);
5564 FPT_Wait1Second(p_port);
5565 while (!(FPT_scarb(p_port, INIT_SELTD))) {
5568 FPT_scasid(p_card, p_port);
5573 else if ((loser) && (ScamFlg & SCAM_ENABLED)) {
5574 FPT_scamInfo[p_our_id].id_string[0] = SLV_TYPE_CODE0;
5576 FPT_scwtsel(p_port);
5579 while (FPT_scxferc(p_port, 0x00) != SYNC_PTRN) {
5582 i = FPT_scxferc(p_port, 0x00);
5583 if (i == ASSIGN_ID) {
5587 &FPT_scamInfo[p_our_id].id_string[0]))) {
5588 i = FPT_scxferc(p_port, 0x00);
5589 if (FPT_scvalq(i)) {
5590 k = FPT_scxferc(p_port, 0x00);
5592 if (FPT_scvalq(k)) {
5605 FPT_scamInfo[currCard->
5607 state = ID_ASSIGNED;
5608 FPT_scamInfo[currCard->
5618 else if (i == SET_P_FLAG) {
5619 if (!(FPT_scsendi(p_port,
5620 &FPT_scamInfo[p_our_id].
5622 FPT_scamInfo[p_our_id].id_string[0] |=
5625 } while (!assigned_id);
5627 while (FPT_scxferc(p_port, 0x00) != CFG_CMPLT) {
5631 if (ScamFlg & SCAM_ENABLED) {
5633 if (currCard->globalFlags & F_UPDATE_EEPROM) {
5634 FPT_scsavdi(p_card, p_port);
5635 currCard->globalFlags &= ~F_UPDATE_EEPROM;
5640 for (i=0,k=0; i < MAX_SCSI_TAR; i++)
5642 if ((FPT_scamInfo[i].state == ID_ASSIGNED) ||
5643 (FPT_scamInfo[i].state == LEGACY))
5648 currCard->globalFlags |= F_SINGLE_DEVICE;
5650 currCard->globalFlags &= ~F_SINGLE_DEVICE;
5654 /*---------------------------------------------------------------------
5656 * Function: FPT_scarb
5658 * Description: Gain control of the bus and wait SCAM select time (250ms)
5660 *---------------------------------------------------------------------*/
5662 static int FPT_scarb(u32 p_port, unsigned char p_sel_type)
5664 if (p_sel_type == INIT_SELTD) {
5666 while (RD_HARPOON(p_port + hp_scsisig) & (SCSI_SEL | SCSI_BSY)) {
5669 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL)
5672 if (RD_HARPOON(p_port + hp_scsidata_0) != 00)
5675 WR_HARPOON(p_port + hp_scsisig,
5676 (RD_HARPOON(p_port + hp_scsisig) | SCSI_BSY));
5678 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_SEL) {
5680 WR_HARPOON(p_port + hp_scsisig,
5681 (RD_HARPOON(p_port + hp_scsisig) &
5686 WR_HARPOON(p_port + hp_scsisig,
5687 (RD_HARPOON(p_port + hp_scsisig) | SCSI_SEL));
5689 if (RD_HARPOON(p_port + hp_scsidata_0) != 00) {
5691 WR_HARPOON(p_port + hp_scsisig,
5692 (RD_HARPOON(p_port + hp_scsisig) &
5693 ~(SCSI_BSY | SCSI_SEL)));
5698 WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5700 WR_HARPOON(p_port + hp_scsireset, SCAM_EN);
5701 WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5702 WR_HARPOON(p_port + hp_scsidata_1, 0x00);
5703 WR_HARPOON(p_port + hp_portctrl_0, SCSI_BUS_EN);
5705 WR_HARPOON(p_port + hp_scsisig,
5706 (RD_HARPOON(p_port + hp_scsisig) | SCSI_MSG));
5708 WR_HARPOON(p_port + hp_scsisig, (RD_HARPOON(p_port + hp_scsisig)
5711 FPT_Wait(p_port, TO_250ms);
5716 /*---------------------------------------------------------------------
5718 * Function: FPT_scbusf
5720 * Description: Release the SCSI bus and disable SCAM selection.
5722 *---------------------------------------------------------------------*/
5724 static void FPT_scbusf(u32 p_port)
5726 WR_HARPOON(p_port + hp_page_ctrl,
5727 (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
5729 WR_HARPOON(p_port + hp_scsidata_0, 0x00);
5731 WR_HARPOON(p_port + hp_portctrl_0, (RD_HARPOON(p_port + hp_portctrl_0)
5734 WR_HARPOON(p_port + hp_scsisig, 0x00);
5736 WR_HARPOON(p_port + hp_scsireset, (RD_HARPOON(p_port + hp_scsireset)
5739 WR_HARPOON(p_port + hp_clkctrl_0, (RD_HARPOON(p_port + hp_clkctrl_0)
5742 WRW_HARPOON((p_port + hp_intstat), (BUS_FREE | AUTO_INT | SCAM_SEL));
5744 WR_HARPOON(p_port + hp_page_ctrl,
5745 (RD_HARPOON(p_port + hp_page_ctrl) & ~G_INT_DISABLE));
5748 /*---------------------------------------------------------------------
5750 * Function: FPT_scasid
5752 * Description: Assign an ID to all the SCAM devices.
5754 *---------------------------------------------------------------------*/
5756 static void FPT_scasid(unsigned char p_card, u32 p_port)
5758 unsigned char temp_id_string[ID_STRING_LENGTH];
5760 unsigned char i, k, scam_id;
5761 unsigned char crcBytes[3];
5762 struct nvram_info *pCurrNvRam;
5763 unsigned short *pCrcBytes;
5765 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
5771 for (k = 0; k < ID_STRING_LENGTH; k++) {
5772 temp_id_string[k] = (unsigned char)0x00;
5775 FPT_scxferc(p_port, SYNC_PTRN);
5776 FPT_scxferc(p_port, ASSIGN_ID);
5778 if (!(FPT_sciso(p_port, &temp_id_string[0]))) {
5780 pCrcBytes = (unsigned short *)&crcBytes[0];
5781 *pCrcBytes = FPT_CalcCrc16(&temp_id_string[0]);
5782 crcBytes[2] = FPT_CalcLrc(&temp_id_string[0]);
5783 temp_id_string[1] = crcBytes[2];
5784 temp_id_string[2] = crcBytes[0];
5785 temp_id_string[3] = crcBytes[1];
5786 for (k = 4; k < ID_STRING_LENGTH; k++)
5787 temp_id_string[k] = (unsigned char)0x00;
5789 i = FPT_scmachid(p_card, temp_id_string);
5791 if (i == CLR_PRIORITY) {
5792 FPT_scxferc(p_port, MISC_CODE);
5793 FPT_scxferc(p_port, CLR_P_FLAG);
5794 i = 0; /*Not the last ID yet. */
5797 else if (i != NO_ID_AVAIL) {
5799 FPT_scxferc(p_port, ID_0_7);
5801 FPT_scxferc(p_port, ID_8_F);
5803 scam_id = (i & (unsigned char)0x07);
5805 for (k = 1; k < 0x08; k <<= 1)
5807 scam_id += 0x08; /*Count number of zeros in DB0-3. */
5809 FPT_scxferc(p_port, scam_id);
5811 i = 0; /*Not the last ID yet. */
5821 FPT_scxferc(p_port, SYNC_PTRN);
5822 FPT_scxferc(p_port, CFG_CMPLT);
5825 /*---------------------------------------------------------------------
5827 * Function: FPT_scsel
5829 * Description: Select all the SCAM devices.
5831 *---------------------------------------------------------------------*/
5833 static void FPT_scsel(u32 p_port)
5836 WR_HARPOON(p_port + hp_scsisig, SCSI_SEL);
5837 FPT_scwiros(p_port, SCSI_MSG);
5839 WR_HARPOON(p_port + hp_scsisig, (SCSI_SEL | SCSI_BSY));
5841 WR_HARPOON(p_port + hp_scsisig,
5842 (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5843 WR_HARPOON(p_port + hp_scsidata_0,
5844 (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) |
5845 (unsigned char)(BIT(7) + BIT(6))));
5847 WR_HARPOON(p_port + hp_scsisig, (SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5848 FPT_scwiros(p_port, SCSI_SEL);
5850 WR_HARPOON(p_port + hp_scsidata_0,
5851 (unsigned char)(RD_HARPOON(p_port + hp_scsidata_0) &
5852 ~(unsigned char)BIT(6)));
5853 FPT_scwirod(p_port, BIT(6));
5855 WR_HARPOON(p_port + hp_scsisig,
5856 (SCSI_SEL | SCSI_BSY | SCSI_IOBIT | SCSI_CD));
5859 /*---------------------------------------------------------------------
5861 * Function: FPT_scxferc
5863 * Description: Handshake the p_data (DB4-0) across the bus.
5865 *---------------------------------------------------------------------*/
5867 static unsigned char FPT_scxferc(u32 p_port, unsigned char p_data)
5869 unsigned char curr_data, ret_data;
5871 curr_data = p_data | BIT(7) | BIT(5); /*Start with DB7 & DB5 asserted. */
5873 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5875 curr_data &= ~BIT(7);
5877 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5879 FPT_scwirod(p_port, BIT(7)); /*Wait for DB7 to be released. */
5880 while (!(RD_HARPOON(p_port + hp_scsidata_0) & BIT(5))) ;
5882 ret_data = (RD_HARPOON(p_port + hp_scsidata_0) & (unsigned char)0x1F);
5884 curr_data |= BIT(6);
5886 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5888 curr_data &= ~BIT(5);
5890 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5892 FPT_scwirod(p_port, BIT(5)); /*Wait for DB5 to be released. */
5894 curr_data &= ~(BIT(4) | BIT(3) | BIT(2) | BIT(1) | BIT(0)); /*Release data bits */
5895 curr_data |= BIT(7);
5897 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5899 curr_data &= ~BIT(6);
5901 WR_HARPOON(p_port + hp_scsidata_0, curr_data);
5903 FPT_scwirod(p_port, BIT(6)); /*Wait for DB6 to be released. */
5908 /*---------------------------------------------------------------------
5910 * Function: FPT_scsendi
5912 * Description: Transfer our Identification string to determine if we
5913 * will be the dominant master.
5915 *---------------------------------------------------------------------*/
5917 static unsigned char FPT_scsendi(u32 p_port, unsigned char p_id_string[])
5919 unsigned char ret_data, byte_cnt, bit_cnt, defer;
5923 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5925 for (bit_cnt = 0x80; bit_cnt != 0; bit_cnt >>= 1) {
5928 ret_data = FPT_scxferc(p_port, 00);
5930 else if (p_id_string[byte_cnt] & bit_cnt)
5932 ret_data = FPT_scxferc(p_port, 02);
5936 ret_data = FPT_scxferc(p_port, 01);
5941 if ((ret_data & 0x1C) == 0x10)
5942 return 0x00; /*End of isolation stage, we won! */
5944 if (ret_data & 0x1C)
5947 if ((defer) && (!(ret_data & 0x1F)))
5948 return 0x01; /*End of isolation stage, we lost. */
5955 return 0x01; /*We lost */
5957 return 0; /*We WON! Yeeessss! */
5960 /*---------------------------------------------------------------------
5962 * Function: FPT_sciso
5964 * Description: Transfer the Identification string.
5966 *---------------------------------------------------------------------*/
5968 static unsigned char FPT_sciso(u32 p_port, unsigned char p_id_string[])
5970 unsigned char ret_data, the_data, byte_cnt, bit_cnt;
5974 for (byte_cnt = 0; byte_cnt < ID_STRING_LENGTH; byte_cnt++) {
5976 for (bit_cnt = 0; bit_cnt < 8; bit_cnt++) {
5978 ret_data = FPT_scxferc(p_port, 0);
5980 if (ret_data & 0xFC)
5986 if (ret_data & BIT(1)) {
5991 if ((ret_data & 0x1F) == 0) {
5993 if(bit_cnt != 0 || bit_cnt != 8)
5997 FPT_scxferc(p_port, SYNC_PTRN);
5998 FPT_scxferc(p_port, ASSIGN_ID);
6010 p_id_string[byte_cnt] = the_data;
6017 /*---------------------------------------------------------------------
6019 * Function: FPT_scwirod
6021 * Description: Sample the SCSI data bus making sure the signal has been
6022 * deasserted for the correct number of consecutive samples.
6024 *---------------------------------------------------------------------*/
6026 static void FPT_scwirod(u32 p_port, unsigned char p_data_bit)
6031 while (i < MAX_SCSI_TAR) {
6033 if (RD_HARPOON(p_port + hp_scsidata_0) & p_data_bit)
6044 /*---------------------------------------------------------------------
6046 * Function: FPT_scwiros
6048 * Description: Sample the SCSI Signal lines making sure the signal has been
6049 * deasserted for the correct number of consecutive samples.
6051 *---------------------------------------------------------------------*/
6053 static void FPT_scwiros(u32 p_port, unsigned char p_data_bit)
6058 while (i < MAX_SCSI_TAR) {
6060 if (RD_HARPOON(p_port + hp_scsisig) & p_data_bit)
6071 /*---------------------------------------------------------------------
6073 * Function: FPT_scvalq
6075 * Description: Make sure we received a valid data byte.
6077 *---------------------------------------------------------------------*/
6079 static unsigned char FPT_scvalq(unsigned char p_quintet)
6081 unsigned char count;
6083 for (count = 1; count < 0x08; count <<= 1) {
6084 if (!(p_quintet & count))
6088 if (p_quintet & 0x18)
6095 /*---------------------------------------------------------------------
6097 * Function: FPT_scsell
6099 * Description: Select the specified device ID using a selection timeout
6100 * less than 4ms. If somebody responds then it is a legacy
6101 * drive and this ID must be marked as such.
6103 *---------------------------------------------------------------------*/
6105 static unsigned char FPT_scsell(u32 p_port, unsigned char targ_id)
6109 WR_HARPOON(p_port + hp_page_ctrl,
6110 (RD_HARPOON(p_port + hp_page_ctrl) | G_INT_DISABLE));
6112 ARAM_ACCESS(p_port);
6114 WR_HARPOON(p_port + hp_addstat,
6115 (RD_HARPOON(p_port + hp_addstat) | SCAM_TIMER));
6116 WR_HARPOON(p_port + hp_seltimeout, TO_4ms);
6118 for (i = p_port + CMD_STRT; i < p_port + CMD_STRT + 12; i += 2) {
6119 WRW_HARPOON(i, (MPM_OP + ACOMMAND));
6121 WRW_HARPOON(i, (BRH_OP + ALWAYS + NP));
6123 WRW_HARPOON((p_port + hp_intstat),
6124 (RESET | TIMEOUT | SEL | BUS_FREE | AUTO_INT));
6126 WR_HARPOON(p_port + hp_select_id, targ_id);
6128 WR_HARPOON(p_port + hp_portctrl_0, SCSI_PORT);
6129 WR_HARPOON(p_port + hp_autostart_3, (SELECT | CMD_ONLY_STRT));
6130 WR_HARPOON(p_port + hp_scsictrl_0, (SEL_TAR | ENA_RESEL));
6132 while (!(RDW_HARPOON((p_port + hp_intstat)) &
6133 (RESET | PROG_HLT | TIMEOUT | AUTO_INT))) {
6136 if (RDW_HARPOON((p_port + hp_intstat)) & RESET)
6137 FPT_Wait(p_port, TO_250ms);
6139 DISABLE_AUTO(p_port);
6141 WR_HARPOON(p_port + hp_addstat,
6142 (RD_HARPOON(p_port + hp_addstat) & ~SCAM_TIMER));
6143 WR_HARPOON(p_port + hp_seltimeout, TO_290ms);
6145 SGRAM_ACCESS(p_port);
6147 if (RDW_HARPOON((p_port + hp_intstat)) & (RESET | TIMEOUT)) {
6149 WRW_HARPOON((p_port + hp_intstat),
6150 (RESET | TIMEOUT | SEL | BUS_FREE | PHASE));
6152 WR_HARPOON(p_port + hp_page_ctrl,
6153 (RD_HARPOON(p_port + hp_page_ctrl) &
6156 return 0; /*No legacy device */
6161 while (!(RDW_HARPOON((p_port + hp_intstat)) & BUS_FREE)) {
6162 if (RD_HARPOON(p_port + hp_scsisig) & SCSI_REQ) {
6163 WR_HARPOON(p_port + hp_scsisig,
6164 (SCSI_ACK + S_ILL_PH));
6169 WRW_HARPOON((p_port + hp_intstat), CLR_ALL_INT_1);
6171 WR_HARPOON(p_port + hp_page_ctrl,
6172 (RD_HARPOON(p_port + hp_page_ctrl) &
6175 return 1; /*Found one of them oldies! */
6179 /*---------------------------------------------------------------------
6181 * Function: FPT_scwtsel
6183 * Description: Wait to be selected by another SCAM initiator.
6185 *---------------------------------------------------------------------*/
6187 static void FPT_scwtsel(u32 p_port)
6189 while (!(RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL)) {
6193 /*---------------------------------------------------------------------
6195 * Function: FPT_inisci
6197 * Description: Setup the data Structure with the info from the EEPROM.
6199 *---------------------------------------------------------------------*/
6201 static void FPT_inisci(unsigned char p_card, u32 p_port, unsigned char p_our_id)
6203 unsigned char i, k, max_id;
6204 unsigned short ee_data;
6205 struct nvram_info *pCurrNvRam;
6207 pCurrNvRam = FPT_BL_Card[p_card].pNvRamInfo;
6209 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6216 for (i = 0; i < max_id; i++) {
6218 for (k = 0; k < 4; k++)
6219 FPT_scamInfo[i].id_string[k] =
6220 pCurrNvRam->niScamTbl[i][k];
6221 for (k = 4; k < ID_STRING_LENGTH; k++)
6222 FPT_scamInfo[i].id_string[k] =
6223 (unsigned char)0x00;
6225 if (FPT_scamInfo[i].id_string[0] == 0x00)
6226 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6228 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6232 for (i = 0; i < max_id; i++) {
6233 for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6235 FPT_utilEERead(p_port,
6237 short)((EE_SCAMBASE / 2) +
6238 (unsigned short)(i *
6239 ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6240 FPT_scamInfo[i].id_string[k] =
6241 (unsigned char)ee_data;
6243 FPT_scamInfo[i].id_string[k + 1] =
6244 (unsigned char)ee_data;
6247 if ((FPT_scamInfo[i].id_string[0] == 0x00) ||
6248 (FPT_scamInfo[i].id_string[0] == 0xFF))
6250 FPT_scamInfo[i].state = ID_UNUSED; /*Default to unused ID. */
6253 FPT_scamInfo[i].state = ID_UNASSIGNED; /*Default to unassigned ID. */
6257 for (k = 0; k < ID_STRING_LENGTH; k++)
6258 FPT_scamInfo[p_our_id].id_string[k] = FPT_scamHAString[k];
6262 /*---------------------------------------------------------------------
6264 * Function: FPT_scmachid
6266 * Description: Match the Device ID string with our values stored in
6269 *---------------------------------------------------------------------*/
6271 static unsigned char FPT_scmachid(unsigned char p_card,
6272 unsigned char p_id_string[])
6275 unsigned char i, k, match;
6277 for (i = 0; i < MAX_SCSI_TAR; i++) {
6281 for (k = 0; k < ID_STRING_LENGTH; k++) {
6282 if (p_id_string[k] != FPT_scamInfo[i].id_string[k])
6287 FPT_scamInfo[i].state = ID_ASSIGNED;
6293 if (p_id_string[0] & BIT(5))
6298 if (((p_id_string[0] & 0x06) == 0x02)
6299 || ((p_id_string[0] & 0x06) == 0x04))
6300 match = p_id_string[1] & (unsigned char)0x1F;
6307 if (FPT_scamInfo[match].state == ID_UNUSED) {
6308 for (k = 0; k < ID_STRING_LENGTH; k++) {
6309 FPT_scamInfo[match].id_string[k] =
6313 FPT_scamInfo[match].state = ID_ASSIGNED;
6315 if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6316 FPT_BL_Card[p_card].globalFlags |=
6324 if (match == 0xFF) {
6325 if (p_id_string[0] & BIT(5))
6328 match = MAX_SCSI_TAR - 1;
6332 if (p_id_string[0] & BIT(7)) {
6333 return CLR_PRIORITY;
6336 if (p_id_string[0] & BIT(5))
6341 if (((p_id_string[0] & 0x06) == 0x02)
6342 || ((p_id_string[0] & 0x06) == 0x04))
6343 match = p_id_string[1] & (unsigned char)0x1F;
6351 if (FPT_scamInfo[match].state == ID_UNASSIGNED) {
6352 for (k = 0; k < ID_STRING_LENGTH; k++) {
6353 FPT_scamInfo[match].id_string[k] =
6357 FPT_scamInfo[match].id_string[0] |= BIT(7);
6358 FPT_scamInfo[match].state = ID_ASSIGNED;
6359 if (FPT_BL_Card[p_card].pNvRamInfo == NULL)
6360 FPT_BL_Card[p_card].globalFlags |=
6368 if (match == 0xFF) {
6369 if (p_id_string[0] & BIT(5))
6372 match = MAX_SCSI_TAR - 1;
6379 /*---------------------------------------------------------------------
6381 * Function: FPT_scsavdi
6383 * Description: Save off the device SCAM ID strings.
6385 *---------------------------------------------------------------------*/
6387 static void FPT_scsavdi(unsigned char p_card, u32 p_port)
6389 unsigned char i, k, max_id;
6390 unsigned short ee_data, sum_data;
6394 for (i = 1; i < EE_SCAMBASE / 2; i++) {
6395 sum_data += FPT_utilEERead(p_port, i);
6398 FPT_utilEEWriteOnOff(p_port, 1); /* Enable write access to the EEPROM */
6400 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6406 for (i = 0; i < max_id; i++) {
6408 for (k = 0; k < ID_STRING_LENGTH; k += 2) {
6409 ee_data = FPT_scamInfo[i].id_string[k + 1];
6411 ee_data |= FPT_scamInfo[i].id_string[k];
6412 sum_data += ee_data;
6413 FPT_utilEEWrite(p_port, ee_data,
6414 (unsigned short)((EE_SCAMBASE / 2) +
6415 (unsigned short)(i *
6416 ((unsigned short)ID_STRING_LENGTH / 2)) + (unsigned short)(k / 2)));
6420 FPT_utilEEWrite(p_port, sum_data, EEPROM_CHECK_SUM / 2);
6421 FPT_utilEEWriteOnOff(p_port, 0); /* Turn off write access */
6424 /*---------------------------------------------------------------------
6426 * Function: FPT_XbowInit
6428 * Description: Setup the Xbow for normal operation.
6430 *---------------------------------------------------------------------*/
6432 static void FPT_XbowInit(u32 port, unsigned char ScamFlg)
6436 i = RD_HARPOON(port + hp_page_ctrl);
6437 WR_HARPOON(port + hp_page_ctrl, (unsigned char)(i | G_INT_DISABLE));
6439 WR_HARPOON(port + hp_scsireset, 0x00);
6440 WR_HARPOON(port + hp_portctrl_1, HOST_MODE8);
6442 WR_HARPOON(port + hp_scsireset, (DMA_RESET | HPSCSI_RESET | PROG_RESET |
6445 WR_HARPOON(port + hp_scsireset, SCSI_INI);
6447 WR_HARPOON(port + hp_clkctrl_0, CLKCTRL_DEFAULT);
6449 WR_HARPOON(port + hp_scsisig, 0x00); /* Clear any signals we might */
6450 WR_HARPOON(port + hp_scsictrl_0, ENA_SCAM_SEL);
6452 WRW_HARPOON((port + hp_intstat), CLR_ALL_INT);
6454 FPT_default_intena = RESET | RSEL | PROG_HLT | TIMEOUT |
6455 BUS_FREE | XFER_CNT_0 | AUTO_INT;
6457 if ((ScamFlg & SCAM_ENABLED) && (ScamFlg & SCAM_LEVEL2))
6458 FPT_default_intena |= SCAM_SEL;
6460 WRW_HARPOON((port + hp_intena), FPT_default_intena);
6462 WR_HARPOON(port + hp_seltimeout, TO_290ms);
6464 /* Turn on SCSI_MODE8 for narrow cards to fix the
6465 strapping issue with the DUAL CHANNEL card */
6466 if (RD_HARPOON(port + hp_page_ctrl) & NARROW_SCSI_CARD)
6467 WR_HARPOON(port + hp_addstat, SCSI_MODE8);
6469 WR_HARPOON(port + hp_page_ctrl, i);
6473 /*---------------------------------------------------------------------
6475 * Function: FPT_BusMasterInit
6477 * Description: Initialize the BusMaster for normal operations.
6479 *---------------------------------------------------------------------*/
6481 static void FPT_BusMasterInit(u32 p_port)
6484 WR_HARPOON(p_port + hp_sys_ctrl, DRVR_RST);
6485 WR_HARPOON(p_port + hp_sys_ctrl, 0x00);
6487 WR_HARPOON(p_port + hp_host_blk_cnt, XFER_BLK64);
6489 WR_HARPOON(p_port + hp_bm_ctrl, (BMCTRL_DEFAULT));
6491 WR_HARPOON(p_port + hp_ee_ctrl, (SCSI_TERM_ENA_H));
6493 RD_HARPOON(p_port + hp_int_status); /*Clear interrupts. */
6494 WR_HARPOON(p_port + hp_int_mask, (INT_CMD_COMPL | SCSI_INTERRUPT));
6495 WR_HARPOON(p_port + hp_page_ctrl, (RD_HARPOON(p_port + hp_page_ctrl) &
6499 /*---------------------------------------------------------------------
6501 * Function: FPT_DiagEEPROM
6503 * Description: Verfiy checksum and 'Key' and initialize the EEPROM if
6506 *---------------------------------------------------------------------*/
6508 static void FPT_DiagEEPROM(u32 p_port)
6510 unsigned short index, temp, max_wd_cnt;
6512 if (RD_HARPOON(p_port + hp_page_ctrl) & NARROW_SCSI_CARD)
6513 max_wd_cnt = EEPROM_WD_CNT;
6515 max_wd_cnt = EEPROM_WD_CNT * 2;
6517 temp = FPT_utilEERead(p_port, FW_SIGNATURE / 2);
6519 if (temp == 0x4641) {
6521 for (index = 2; index < max_wd_cnt; index++) {
6523 temp += FPT_utilEERead(p_port, index);
6527 if (temp == FPT_utilEERead(p_port, EEPROM_CHECK_SUM / 2)) {
6529 return; /*EEPROM is Okay so return now! */
6533 FPT_utilEEWriteOnOff(p_port, (unsigned char)1);
6535 for (index = 0; index < max_wd_cnt; index++) {
6537 FPT_utilEEWrite(p_port, 0x0000, index);
6542 FPT_utilEEWrite(p_port, 0x4641, FW_SIGNATURE / 2);
6544 FPT_utilEEWrite(p_port, 0x3920, MODEL_NUMB_0 / 2);
6546 FPT_utilEEWrite(p_port, 0x3033, MODEL_NUMB_2 / 2);
6548 FPT_utilEEWrite(p_port, 0x2020, MODEL_NUMB_4 / 2);
6550 FPT_utilEEWrite(p_port, 0x70D3, SYSTEM_CONFIG / 2);
6552 FPT_utilEEWrite(p_port, 0x0010, BIOS_CONFIG / 2);
6554 FPT_utilEEWrite(p_port, 0x0003, SCAM_CONFIG / 2);
6556 FPT_utilEEWrite(p_port, 0x0007, ADAPTER_SCSI_ID / 2);
6559 FPT_utilEEWrite(p_port, 0x0000, IGNORE_B_SCAN / 2);
6561 FPT_utilEEWrite(p_port, 0x0000, SEND_START_ENA / 2);
6563 FPT_utilEEWrite(p_port, 0x0000, DEVICE_ENABLE / 2);
6566 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL01 / 2);
6568 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL23 / 2);
6570 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL45 / 2);
6572 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL67 / 2);
6574 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBL89 / 2);
6576 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLab / 2);
6578 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLcd / 2);
6580 FPT_utilEEWrite(p_port, 0x4242, SYNC_RATE_TBLef / 2);
6583 FPT_utilEEWrite(p_port, 0x6C46, 64 / 2); /*PRODUCT ID */
6585 FPT_utilEEWrite(p_port, 0x7361, 66 / 2); /* FlashPoint LT */
6587 FPT_utilEEWrite(p_port, 0x5068, 68 / 2);
6589 FPT_utilEEWrite(p_port, 0x696F, 70 / 2);
6591 FPT_utilEEWrite(p_port, 0x746E, 72 / 2);
6593 FPT_utilEEWrite(p_port, 0x4C20, 74 / 2);
6595 FPT_utilEEWrite(p_port, 0x2054, 76 / 2);
6597 FPT_utilEEWrite(p_port, 0x2020, 78 / 2);
6600 index = ((EE_SCAMBASE / 2) + (7 * 16));
6601 FPT_utilEEWrite(p_port, (0x0700 + TYPE_CODE0), index);
6602 temp += (0x0700 + TYPE_CODE0);
6604 FPT_utilEEWrite(p_port, 0x5542, index); /*Vendor ID code */
6605 temp += 0x5542; /* BUSLOGIC */
6607 FPT_utilEEWrite(p_port, 0x4C53, index);
6610 FPT_utilEEWrite(p_port, 0x474F, index);
6613 FPT_utilEEWrite(p_port, 0x4349, index);
6616 FPT_utilEEWrite(p_port, 0x5442, index); /*Vendor unique code */
6617 temp += 0x5442; /* BT- 930 */
6619 FPT_utilEEWrite(p_port, 0x202D, index);
6622 FPT_utilEEWrite(p_port, 0x3339, index);
6624 index++; /*Serial # */
6625 FPT_utilEEWrite(p_port, 0x2030, index); /* 01234567 */
6628 FPT_utilEEWrite(p_port, 0x5453, index);
6631 FPT_utilEEWrite(p_port, 0x5645, index);
6634 FPT_utilEEWrite(p_port, 0x2045, index);
6637 FPT_utilEEWrite(p_port, 0x202F, index);
6640 FPT_utilEEWrite(p_port, 0x4F4A, index);
6643 FPT_utilEEWrite(p_port, 0x204E, index);
6646 FPT_utilEEWrite(p_port, 0x3539, index);
6649 FPT_utilEEWrite(p_port, temp, EEPROM_CHECK_SUM / 2);
6651 FPT_utilEEWriteOnOff(p_port, (unsigned char)0);
6655 /*---------------------------------------------------------------------
6657 * Function: Queue Search Select
6659 * Description: Try to find a new command to execute.
6661 *---------------------------------------------------------------------*/
6663 static void FPT_queueSearchSelect(struct sccb_card *pCurrCard,
6664 unsigned char p_card)
6666 unsigned char scan_ptr, lun;
6667 struct sccb_mgr_tar_info *currTar_Info;
6668 struct sccb *pOldSccb;
6670 scan_ptr = pCurrCard->scanIndex;
6672 currTar_Info = &FPT_sccbMgrTbl[p_card][scan_ptr];
6673 if ((pCurrCard->globalFlags & F_CONLUN_IO) &&
6674 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6676 if (currTar_Info->TarSelQ_Cnt != 0) {
6679 if (scan_ptr == MAX_SCSI_TAR)
6682 for (lun = 0; lun < MAX_LUN; lun++) {
6683 if (currTar_Info->TarLUNBusy[lun] == 0) {
6685 pCurrCard->currentSCCB =
6686 currTar_Info->TarSelQ_Head;
6690 currentSCCB != NULL)
6693 currentSCCB->Lun)) {
6697 pCurrCard->currentSCCB =
6703 if (pCurrCard->currentSCCB ==
6706 if (pOldSccb != NULL) {
6749 pCurrCard->scanIndex = scan_ptr;
6751 pCurrCard->globalFlags |=
6761 if (scan_ptr == MAX_SCSI_TAR) {
6767 if ((currTar_Info->TarSelQ_Cnt != 0) &&
6768 (currTar_Info->TarLUNBusy[0] == 0)) {
6770 pCurrCard->currentSCCB =
6771 currTar_Info->TarSelQ_Head;
6773 currTar_Info->TarSelQ_Head =
6774 (struct sccb *)(pCurrCard->currentSCCB)->
6777 if (currTar_Info->TarSelQ_Head == NULL) {
6778 currTar_Info->TarSelQ_Tail = NULL;
6779 currTar_Info->TarSelQ_Cnt = 0;
6781 currTar_Info->TarSelQ_Cnt--;
6782 currTar_Info->TarSelQ_Head->
6783 Sccb_backlink = (struct sccb *)NULL;
6787 if (scan_ptr == MAX_SCSI_TAR)
6790 pCurrCard->scanIndex = scan_ptr;
6792 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6799 if (scan_ptr == MAX_SCSI_TAR) {
6804 } while (scan_ptr != pCurrCard->scanIndex);
6807 /*---------------------------------------------------------------------
6809 * Function: Queue Select Fail
6811 * Description: Add the current SCCB to the head of the Queue.
6813 *---------------------------------------------------------------------*/
6815 static void FPT_queueSelectFail(struct sccb_card *pCurrCard,
6816 unsigned char p_card)
6818 unsigned char thisTarg;
6819 struct sccb_mgr_tar_info *currTar_Info;
6821 if (pCurrCard->currentSCCB != NULL) {
6823 (unsigned char)(((struct sccb *)(pCurrCard->currentSCCB))->
6825 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6827 pCurrCard->currentSCCB->Sccb_backlink = (struct sccb *)NULL;
6829 pCurrCard->currentSCCB->Sccb_forwardlink =
6830 currTar_Info->TarSelQ_Head;
6832 if (currTar_Info->TarSelQ_Cnt == 0) {
6833 currTar_Info->TarSelQ_Tail = pCurrCard->currentSCCB;
6837 currTar_Info->TarSelQ_Head->Sccb_backlink =
6838 pCurrCard->currentSCCB;
6841 currTar_Info->TarSelQ_Head = pCurrCard->currentSCCB;
6843 pCurrCard->currentSCCB = NULL;
6844 currTar_Info->TarSelQ_Cnt++;
6848 /*---------------------------------------------------------------------
6850 * Function: Queue Command Complete
6852 * Description: Call the callback function with the current SCCB.
6854 *---------------------------------------------------------------------*/
6856 static void FPT_queueCmdComplete(struct sccb_card *pCurrCard,
6857 struct sccb *p_sccb, unsigned char p_card)
6860 unsigned char i, SCSIcmd;
6861 CALL_BK_FN callback;
6862 struct sccb_mgr_tar_info *currTar_Info;
6864 SCSIcmd = p_sccb->Cdb[0];
6866 if (!(p_sccb->Sccb_XferState & F_ALL_XFERRED)) {
6869 ControlByte & (SCCB_DATA_XFER_OUT | SCCB_DATA_XFER_IN))
6870 && (p_sccb->HostStatus == SCCB_COMPLETE)
6871 && (p_sccb->TargetStatus != SSCHECK))
6873 if ((SCSIcmd == SCSI_READ) ||
6874 (SCSIcmd == SCSI_WRITE) ||
6875 (SCSIcmd == SCSI_READ_EXTENDED) ||
6876 (SCSIcmd == SCSI_WRITE_EXTENDED) ||
6877 (SCSIcmd == SCSI_WRITE_AND_VERIFY) ||
6878 (SCSIcmd == SCSI_START_STOP_UNIT) ||
6879 (pCurrCard->globalFlags & F_NO_FILTER)
6881 p_sccb->HostStatus = SCCB_DATA_UNDER_RUN;
6884 if (p_sccb->SccbStatus == SCCB_IN_PROCESS) {
6885 if (p_sccb->HostStatus || p_sccb->TargetStatus)
6886 p_sccb->SccbStatus = SCCB_ERROR;
6888 p_sccb->SccbStatus = SCCB_SUCCESS;
6891 if (p_sccb->Sccb_XferState & F_AUTO_SENSE) {
6893 p_sccb->CdbLength = p_sccb->Save_CdbLen;
6894 for (i = 0; i < 6; i++) {
6895 p_sccb->Cdb[i] = p_sccb->Save_Cdb[i];
6899 if ((p_sccb->OperationCode == RESIDUAL_SG_COMMAND) ||
6900 (p_sccb->OperationCode == RESIDUAL_COMMAND)) {
6902 FPT_utilUpdateResidual(p_sccb);
6905 pCurrCard->cmdCounter--;
6906 if (!pCurrCard->cmdCounter) {
6908 if (pCurrCard->globalFlags & F_GREEN_PC) {
6909 WR_HARPOON(pCurrCard->ioPort + hp_clkctrl_0,
6910 (PWR_DWN | CLKCTRL_DEFAULT));
6911 WR_HARPOON(pCurrCard->ioPort + hp_sys_ctrl, STOP_CLK);
6914 WR_HARPOON(pCurrCard->ioPort + hp_semaphore,
6915 (RD_HARPOON(pCurrCard->ioPort + hp_semaphore) &
6920 if (pCurrCard->discQCount != 0) {
6921 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6922 if (((pCurrCard->globalFlags & F_CONLUN_IO) &&
6923 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) !=
6925 pCurrCard->discQCount--;
6926 pCurrCard->discQ_Tbl[currTar_Info->
6927 LunDiscQ_Idx[p_sccb->Lun]] = NULL;
6929 if (p_sccb->Sccb_tag) {
6930 pCurrCard->discQCount--;
6931 pCurrCard->discQ_Tbl[p_sccb->Sccb_tag] = NULL;
6933 pCurrCard->discQCount--;
6934 pCurrCard->discQ_Tbl[currTar_Info->
6935 LunDiscQ_Idx[0]] = NULL;
6941 callback = (CALL_BK_FN) p_sccb->SccbCallback;
6943 pCurrCard->globalFlags |= F_NEW_SCCB_CMD;
6944 pCurrCard->currentSCCB = NULL;
6947 /*---------------------------------------------------------------------
6949 * Function: Queue Disconnect
6951 * Description: Add SCCB to our disconnect array.
6953 *---------------------------------------------------------------------*/
6954 static void FPT_queueDisconnect(struct sccb *p_sccb, unsigned char p_card)
6956 struct sccb_mgr_tar_info *currTar_Info;
6958 currTar_Info = &FPT_sccbMgrTbl[p_card][p_sccb->TargID];
6960 if (((FPT_BL_Card[p_card].globalFlags & F_CONLUN_IO) &&
6961 ((currTar_Info->TarStatus & TAR_TAG_Q_MASK) != TAG_Q_TRYING))) {
6962 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6963 LunDiscQ_Idx[p_sccb->Lun]] =
6966 if (p_sccb->Sccb_tag) {
6967 FPT_BL_Card[p_card].discQ_Tbl[p_sccb->Sccb_tag] =
6969 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarLUNBusy[0] =
6971 FPT_sccbMgrTbl[p_card][p_sccb->TargID].TarTagQ_Cnt++;
6973 FPT_BL_Card[p_card].discQ_Tbl[currTar_Info->
6974 LunDiscQ_Idx[0]] = p_sccb;
6977 FPT_BL_Card[p_card].currentSCCB = NULL;
6980 /*---------------------------------------------------------------------
6982 * Function: Queue Flush SCCB
6984 * Description: Flush all SCCB's back to the host driver for this target.
6986 *---------------------------------------------------------------------*/
6988 static void FPT_queueFlushSccb(unsigned char p_card, unsigned char error_code)
6990 unsigned char qtag, thisTarg;
6991 struct sccb *currSCCB;
6992 struct sccb_mgr_tar_info *currTar_Info;
6994 currSCCB = FPT_BL_Card[p_card].currentSCCB;
6995 if (currSCCB != NULL) {
6996 thisTarg = (unsigned char)currSCCB->TargID;
6997 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
6999 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7001 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7002 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID ==
7005 FPT_BL_Card[p_card].discQ_Tbl[qtag]->
7006 HostStatus = (unsigned char)error_code;
7008 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7009 FPT_BL_Card[p_card].
7010 discQ_Tbl[qtag], p_card);
7012 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7013 currTar_Info->TarTagQ_Cnt--;
7021 /*---------------------------------------------------------------------
7023 * Function: Queue Flush Target SCCB
7025 * Description: Flush all SCCB's back to the host driver for this target.
7027 *---------------------------------------------------------------------*/
7029 static void FPT_queueFlushTargSccb(unsigned char p_card, unsigned char thisTarg,
7030 unsigned char error_code)
7033 struct sccb_mgr_tar_info *currTar_Info;
7035 currTar_Info = &FPT_sccbMgrTbl[p_card][thisTarg];
7037 for (qtag = 0; qtag < QUEUE_DEPTH; qtag++) {
7039 if (FPT_BL_Card[p_card].discQ_Tbl[qtag] &&
7040 (FPT_BL_Card[p_card].discQ_Tbl[qtag]->TargID == thisTarg)) {
7042 FPT_BL_Card[p_card].discQ_Tbl[qtag]->HostStatus =
7043 (unsigned char)error_code;
7045 FPT_queueCmdComplete(&FPT_BL_Card[p_card],
7046 FPT_BL_Card[p_card].
7047 discQ_Tbl[qtag], p_card);
7049 FPT_BL_Card[p_card].discQ_Tbl[qtag] = NULL;
7050 currTar_Info->TarTagQ_Cnt--;
7057 static void FPT_queueAddSccb(struct sccb *p_SCCB, unsigned char p_card)
7059 struct sccb_mgr_tar_info *currTar_Info;
7060 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7062 p_SCCB->Sccb_forwardlink = NULL;
7064 p_SCCB->Sccb_backlink = currTar_Info->TarSelQ_Tail;
7066 if (currTar_Info->TarSelQ_Cnt == 0) {
7068 currTar_Info->TarSelQ_Head = p_SCCB;
7073 currTar_Info->TarSelQ_Tail->Sccb_forwardlink = p_SCCB;
7076 currTar_Info->TarSelQ_Tail = p_SCCB;
7077 currTar_Info->TarSelQ_Cnt++;
7080 /*---------------------------------------------------------------------
7082 * Function: Queue Find SCCB
7084 * Description: Search the target select Queue for this SCCB, and
7085 * remove it if found.
7087 *---------------------------------------------------------------------*/
7089 static unsigned char FPT_queueFindSccb(struct sccb *p_SCCB,
7090 unsigned char p_card)
7093 struct sccb_mgr_tar_info *currTar_Info;
7095 currTar_Info = &FPT_sccbMgrTbl[p_card][p_SCCB->TargID];
7097 q_ptr = currTar_Info->TarSelQ_Head;
7099 while (q_ptr != NULL) {
7101 if (q_ptr == p_SCCB) {
7103 if (currTar_Info->TarSelQ_Head == q_ptr) {
7105 currTar_Info->TarSelQ_Head =
7106 q_ptr->Sccb_forwardlink;
7109 if (currTar_Info->TarSelQ_Tail == q_ptr) {
7111 currTar_Info->TarSelQ_Tail =
7112 q_ptr->Sccb_backlink;
7115 if (q_ptr->Sccb_forwardlink != NULL) {
7116 q_ptr->Sccb_forwardlink->Sccb_backlink =
7117 q_ptr->Sccb_backlink;
7120 if (q_ptr->Sccb_backlink != NULL) {
7121 q_ptr->Sccb_backlink->Sccb_forwardlink =
7122 q_ptr->Sccb_forwardlink;
7125 currTar_Info->TarSelQ_Cnt--;
7131 q_ptr = q_ptr->Sccb_forwardlink;
7139 /*---------------------------------------------------------------------
7141 * Function: Utility Update Residual Count
7143 * Description: Update the XferCnt to the remaining byte count.
7144 * If we transferred all the data then just write zero.
7145 * If Non-SG transfer then report Total Cnt - Actual Transfer
7146 * Cnt. For SG transfers add the count fields of all
7147 * remaining SG elements, as well as any partial remaining
7150 *---------------------------------------------------------------------*/
7152 static void FPT_utilUpdateResidual(struct sccb *p_SCCB)
7154 unsigned long partial_cnt;
7155 unsigned int sg_index;
7156 struct blogic_sg_seg *segp;
7158 if (p_SCCB->Sccb_XferState & F_ALL_XFERRED) {
7160 p_SCCB->DataLength = 0x0000;
7163 else if (p_SCCB->Sccb_XferState & F_SG_XFER) {
7165 partial_cnt = 0x0000;
7167 sg_index = p_SCCB->Sccb_sgseg;
7170 if (p_SCCB->Sccb_SGoffset) {
7172 partial_cnt = p_SCCB->Sccb_SGoffset;
7176 while (((unsigned long)sg_index *
7177 (unsigned long)SG_ELEMENT_SIZE) < p_SCCB->DataLength) {
7178 segp = (struct blogic_sg_seg *)(p_SCCB->DataPointer) +
7180 partial_cnt += segp->segbytes;
7184 p_SCCB->DataLength = partial_cnt;
7189 p_SCCB->DataLength -= p_SCCB->Sccb_ATC;
7193 /*---------------------------------------------------------------------
7195 * Function: Wait 1 Second
7197 * Description: Wait for 1 second.
7199 *---------------------------------------------------------------------*/
7201 static void FPT_Wait1Second(u32 p_port)
7205 for (i = 0; i < 4; i++) {
7207 FPT_Wait(p_port, TO_250ms);
7209 if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7212 if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7217 /*---------------------------------------------------------------------
7219 * Function: FPT_Wait
7221 * Description: Wait the desired delay.
7223 *---------------------------------------------------------------------*/
7225 static void FPT_Wait(u32 p_port, unsigned char p_delay)
7227 unsigned char old_timer;
7228 unsigned char green_flag;
7230 old_timer = RD_HARPOON(p_port + hp_seltimeout);
7232 green_flag = RD_HARPOON(p_port + hp_clkctrl_0);
7233 WR_HARPOON(p_port + hp_clkctrl_0, CLKCTRL_DEFAULT);
7235 WR_HARPOON(p_port + hp_seltimeout, p_delay);
7236 WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7237 WRW_HARPOON((p_port + hp_intena), (FPT_default_intena & ~TIMEOUT));
7239 WR_HARPOON(p_port + hp_portctrl_0,
7240 (RD_HARPOON(p_port + hp_portctrl_0) | START_TO));
7242 while (!(RDW_HARPOON((p_port + hp_intstat)) & TIMEOUT)) {
7244 if ((RD_HARPOON(p_port + hp_scsictrl_0) & SCSI_RST))
7247 if ((RDW_HARPOON((p_port + hp_intstat)) & SCAM_SEL))
7251 WR_HARPOON(p_port + hp_portctrl_0,
7252 (RD_HARPOON(p_port + hp_portctrl_0) & ~START_TO));
7254 WRW_HARPOON((p_port + hp_intstat), TIMEOUT);
7255 WRW_HARPOON((p_port + hp_intena), FPT_default_intena);
7257 WR_HARPOON(p_port + hp_clkctrl_0, green_flag);
7259 WR_HARPOON(p_port + hp_seltimeout, old_timer);
7262 /*---------------------------------------------------------------------
7264 * Function: Enable/Disable Write to EEPROM
7266 * Description: The EEPROM must first be enabled for writes
7267 * A total of 9 clocks are needed.
7269 *---------------------------------------------------------------------*/
7271 static void FPT_utilEEWriteOnOff(u32 p_port, unsigned char p_mode)
7273 unsigned char ee_value;
7276 (unsigned char)(RD_HARPOON(p_port + hp_ee_ctrl) &
7277 (EXT_ARB_ACK | SCSI_TERM_ENA_H));
7281 FPT_utilEESendCmdAddr(p_port, EWEN, EWEN_ADDR);
7285 FPT_utilEESendCmdAddr(p_port, EWDS, EWDS_ADDR);
7287 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7288 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
7291 /*---------------------------------------------------------------------
7293 * Function: Write EEPROM
7295 * Description: Write a word to the EEPROM at the specified
7298 *---------------------------------------------------------------------*/
7300 static void FPT_utilEEWrite(u32 p_port, unsigned short ee_data,
7301 unsigned short ee_addr)
7304 unsigned char ee_value;
7309 char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7310 (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7312 FPT_utilEESendCmdAddr(p_port, EE_WRITE, ee_addr);
7314 ee_value |= (SEE_MS + SEE_CS);
7316 for (i = 0x8000; i != 0; i >>= 1) {
7321 ee_value &= ~SEE_DO;
7323 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7324 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7325 ee_value |= SEE_CLK; /* Clock data! */
7326 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7327 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7328 ee_value &= ~SEE_CLK;
7329 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7330 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7332 ee_value &= (EXT_ARB_ACK | SCSI_TERM_ENA_H);
7333 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS));
7335 FPT_Wait(p_port, TO_10ms);
7337 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS | SEE_CS)); /* Set CS to EEPROM */
7338 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /* Turn off CS */
7339 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /* Turn off Master Select */
7342 /*---------------------------------------------------------------------
7344 * Function: Read EEPROM
7346 * Description: Read a word from the EEPROM at the desired
7349 *---------------------------------------------------------------------*/
7351 static unsigned short FPT_utilEERead(u32 p_port,
7352 unsigned short ee_addr)
7354 unsigned short i, ee_data1, ee_data2;
7357 ee_data1 = FPT_utilEEReadOrg(p_port, ee_addr);
7359 ee_data2 = FPT_utilEEReadOrg(p_port, ee_addr);
7361 if (ee_data1 == ee_data2)
7364 ee_data1 = ee_data2;
7372 /*---------------------------------------------------------------------
7374 * Function: Read EEPROM Original
7376 * Description: Read a word from the EEPROM at the desired
7379 *---------------------------------------------------------------------*/
7381 static unsigned short FPT_utilEEReadOrg(u32 p_port, unsigned short ee_addr)
7384 unsigned char ee_value;
7385 unsigned short i, ee_data;
7389 char)((RD_HARPOON(p_port + hp_ee_ctrl) &
7390 (EXT_ARB_ACK | SCSI_TERM_ENA_H)) | (SEE_MS | SEE_CS));
7392 FPT_utilEESendCmdAddr(p_port, EE_READ, ee_addr);
7394 ee_value |= (SEE_MS + SEE_CS);
7397 for (i = 1; i <= 16; i++) {
7399 ee_value |= SEE_CLK; /* Clock data! */
7400 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7401 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7402 ee_value &= ~SEE_CLK;
7403 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7404 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7408 if (RD_HARPOON(p_port + hp_ee_ctrl) & SEE_DI)
7412 ee_value &= ~(SEE_MS + SEE_CS);
7413 WR_HARPOON(p_port + hp_ee_ctrl, (ee_value | SEE_MS)); /*Turn off CS */
7414 WR_HARPOON(p_port + hp_ee_ctrl, ee_value); /*Turn off Master Select */
7419 /*---------------------------------------------------------------------
7421 * Function: Send EE command and Address to the EEPROM
7423 * Description: Transfers the correct command and sends the address
7426 *---------------------------------------------------------------------*/
7428 static void FPT_utilEESendCmdAddr(u32 p_port, unsigned char ee_cmd,
7429 unsigned short ee_addr)
7431 unsigned char ee_value;
7432 unsigned char narrow_flg;
7437 (unsigned char)(RD_HARPOON(p_port + hp_page_ctrl) &
7441 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7443 ee_value |= SEE_CS; /* Set CS to EEPROM */
7444 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7446 for (i = 0x04; i != 0; i >>= 1) {
7451 ee_value &= ~SEE_DO;
7453 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7454 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7455 ee_value |= SEE_CLK; /* Clock data! */
7456 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7457 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7458 ee_value &= ~SEE_CLK;
7459 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7460 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7474 ee_value &= ~SEE_DO;
7476 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7477 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7478 ee_value |= SEE_CLK; /* Clock data! */
7479 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7480 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7481 ee_value &= ~SEE_CLK;
7482 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7483 WR_HARPOON(p_port + hp_ee_ctrl, ee_value);
7489 static unsigned short FPT_CalcCrc16(unsigned char buffer[])
7491 unsigned short crc = 0;
7494 for (i = 0; i < ID_STRING_LENGTH; i++) {
7495 ch = (unsigned short)buffer[i];
7496 for (j = 0; j < 8; j++) {
7498 crc = (crc >> 1) ^ CRCMASK;
7507 static unsigned char FPT_CalcLrc(unsigned char buffer[])
7512 for (i = 0; i < ID_STRING_LENGTH; i++)
7518 The following inline definitions avoid type conflicts.
7521 static inline unsigned char
7522 FlashPoint__ProbeHostAdapter(struct fpoint_info *FlashPointInfo)
7524 return FlashPoint_ProbeHostAdapter((struct sccb_mgr_info *)
7528 static inline void *
7529 FlashPoint__HardwareResetHostAdapter(struct fpoint_info *FlashPointInfo)
7531 return FlashPoint_HardwareResetHostAdapter((struct sccb_mgr_info *)
7536 FlashPoint__ReleaseHostAdapter(void *CardHandle)
7538 FlashPoint_ReleaseHostAdapter(CardHandle);
7542 FlashPoint__StartCCB(void *CardHandle, struct blogic_ccb *CCB)
7544 FlashPoint_StartCCB(CardHandle, (struct sccb *)CCB);
7548 FlashPoint__AbortCCB(void *CardHandle, struct blogic_ccb *CCB)
7550 FlashPoint_AbortCCB(CardHandle, (struct sccb *)CCB);
7554 FlashPoint__InterruptPending(void *CardHandle)
7556 return FlashPoint_InterruptPending(CardHandle);
7560 FlashPoint__HandleInterrupt(void *CardHandle)
7562 return FlashPoint_HandleInterrupt(CardHandle);
7565 #define FlashPoint_ProbeHostAdapter FlashPoint__ProbeHostAdapter
7566 #define FlashPoint_HardwareResetHostAdapter FlashPoint__HardwareResetHostAdapter
7567 #define FlashPoint_ReleaseHostAdapter FlashPoint__ReleaseHostAdapter
7568 #define FlashPoint_StartCCB FlashPoint__StartCCB
7569 #define FlashPoint_AbortCCB FlashPoint__AbortCCB
7570 #define FlashPoint_InterruptPending FlashPoint__InterruptPending
7571 #define FlashPoint_HandleInterrupt FlashPoint__HandleInterrupt
7573 #else /* !CONFIG_SCSI_FLASHPOINT */
7576 Define prototypes for the FlashPoint SCCB Manager Functions.
7579 extern unsigned char FlashPoint_ProbeHostAdapter(struct fpoint_info *);
7580 extern void *FlashPoint_HardwareResetHostAdapter(struct fpoint_info *);
7581 extern void FlashPoint_StartCCB(void *, struct blogic_ccb *);
7582 extern int FlashPoint_AbortCCB(void *, struct blogic_ccb *);
7583 extern bool FlashPoint_InterruptPending(void *);
7584 extern int FlashPoint_HandleInterrupt(void *);
7585 extern void FlashPoint_ReleaseHostAdapter(void *);
7587 #endif /* CONFIG_SCSI_FLASHPOINT */