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