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