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