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