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