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