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