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