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