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