1 /************************************************************************** 2 * Initio 9100 device driver for Linux. 3 * 4 * Copyright (c) 1994-1998 Initio Corporation 5 * Copyright (c) 1998 Bas Vermeulen <bvermeul@blackstar.xs4all.nl> 6 * All rights reserved. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2, or (at your option) 11 * any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; see the file COPYING. If not, write to 20 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. 21 * 22 * -------------------------------------------------------------------------- 23 * 24 * Redistribution and use in source and binary forms, with or without 25 * modification, are permitted provided that the following conditions 26 * are met: 27 * 1. Redistributions of source code must retain the above copyright 28 * notice, this list of conditions, and the following disclaimer, 29 * without modification, immediately at the beginning of the file. 30 * 2. Redistributions in binary form must reproduce the above copyright 31 * notice, this list of conditions and the following disclaimer in the 32 * documentation and/or other materials provided with the distribution. 33 * 3. The name of the author may not be used to endorse or promote products 34 * derived from this software without specific prior written permission. 35 * 36 * Where this Software is combined with software released under the terms of 37 * the GNU General Public License ("GPL") and the terms of the GPL would require the 38 * combined work to also be released under the terms of the GPL, the terms 39 * and conditions of this License will apply in addition to those of the 40 * GPL with the exception of any terms or conditions of this License that 41 * conflict with, or are expressly prohibited by, the GPL. 42 * 43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 44 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 45 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 46 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 47 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 48 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 49 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53 * SUCH DAMAGE. 54 * 55 ************************************************************************* 56 * 57 * DESCRIPTION: 58 * 59 * This is the Linux low-level SCSI driver for Initio INI-9X00U/UW SCSI host 60 * adapters 61 * 62 * 08/06/97 hc - v1.01h 63 * - Support inic-940 and inic-935 64 * 09/26/97 hc - v1.01i 65 * - Make correction from J.W. Schultz suggestion 66 * 10/13/97 hc - Support reset function 67 * 10/21/97 hc - v1.01j 68 * - Support 32 LUN (SCSI 3) 69 * 01/14/98 hc - v1.01k 70 * - Fix memory allocation problem 71 * 03/04/98 hc - v1.01l 72 * - Fix tape rewind which will hang the system problem 73 * - Set can_queue to tul_num_scb 74 * 06/25/98 hc - v1.01m 75 * - Get it work for kernel version >= 2.1.75 76 * - Dynamic assign SCSI bus reset holding time in init_tulip() 77 * 07/02/98 hc - v1.01n 78 * - Support 0002134A 79 * 08/07/98 hc - v1.01o 80 * - Change the tul_abort_srb routine to use scsi_done. <01> 81 * 09/07/98 hl - v1.02 82 * - Change the INI9100U define and proc_dir_entry to 83 * reflect the newer Kernel 2.1.118, but the v1.o1o 84 * should work with Kernel 2.1.118. 85 * 09/20/98 wh - v1.02a 86 * - Support Abort command. 87 * - Handle reset routine. 88 * 09/21/98 hl - v1.03 89 * - remove comments. 90 * 12/09/98 bv - v1.03a 91 * - Removed unused code 92 * 12/13/98 bv - v1.03b 93 * - Remove cli() locking for kernels >= 2.1.95. This uses 94 * spinlocks to serialize access to the pSRB_head and 95 * pSRB_tail members of the HCS structure. 96 * 09/01/99 bv - v1.03d 97 * - Fixed a deadlock problem in SMP. 98 * 21/01/99 bv - v1.03e 99 * - Add support for the Domex 3192U PCI SCSI 100 * This is a slightly modified patch by 101 * Brian Macy <bmacy@sunshinecomputing.com> 102 * 22/02/99 bv - v1.03f 103 * - Didn't detect the INIC-950 in 2.0.x correctly. 104 * Now fixed. 105 * 05/07/99 bv - v1.03g 106 * - Changed the assumption that HZ = 100 107 * 10/17/03 mc - v1.04 108 * - added new DMA API support 109 * 06/01/04 jmd - v1.04a 110 * - Re-add reset_bus support 111 **************************************************************************/ 112 113 #include <linux/module.h> 114 #include <linux/errno.h> 115 #include <linux/delay.h> 116 #include <linux/pci.h> 117 #include <linux/init.h> 118 #include <linux/blkdev.h> 119 #include <linux/spinlock.h> 120 #include <linux/stat.h> 121 #include <linux/config.h> 122 #include <linux/kernel.h> 123 #include <linux/proc_fs.h> 124 #include <linux/string.h> 125 #include <linux/interrupt.h> 126 #include <linux/ioport.h> 127 #include <linux/sched.h> 128 #include <linux/slab.h> 129 #include <linux/jiffies.h> 130 #include <asm/io.h> 131 132 #include <scsi/scsi.h> 133 #include <scsi/scsi_cmnd.h> 134 #include <scsi/scsi_device.h> 135 #include <scsi/scsi_host.h> 136 #include <scsi/scsi_tcq.h> 137 138 #include "initio.h" 139 140 #define SENSE_SIZE 14 141 142 #define i91u_MAXQUEUE 2 143 #define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a" 144 145 #define INI_VENDOR_ID 0x1101 /* Initio's PCI vendor ID */ 146 #define DMX_VENDOR_ID 0x134a /* Domex's PCI vendor ID */ 147 #define I950_DEVICE_ID 0x9500 /* Initio's inic-950 product ID */ 148 #define I940_DEVICE_ID 0x9400 /* Initio's inic-940 product ID */ 149 #define I935_DEVICE_ID 0x9401 /* Initio's inic-935 product ID */ 150 #define I920_DEVICE_ID 0x0002 /* Initio's other product ID */ 151 152 #ifdef DEBUG_i91u 153 static unsigned int i91u_debug = DEBUG_DEFAULT; 154 #endif 155 156 #define TULSZ(sz) (sizeof(sz) / sizeof(sz[0])) 157 #define TUL_RDWORD(x,y) (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) )) 158 159 typedef struct PCI_ID_Struc { 160 unsigned short vendor_id; 161 unsigned short device_id; 162 } PCI_ID; 163 164 static int tul_num_ch = 4; /* Maximum 4 adapters */ 165 static int tul_num_scb; 166 static int tul_tag_enable = 1; 167 static SCB *tul_scb; 168 169 #ifdef DEBUG_i91u 170 static int setup_debug = 0; 171 #endif 172 173 static void i91uSCBPost(BYTE * pHcb, BYTE * pScb); 174 175 static const PCI_ID i91u_pci_devices[] = { 176 { INI_VENDOR_ID, I950_DEVICE_ID }, 177 { INI_VENDOR_ID, I940_DEVICE_ID }, 178 { INI_VENDOR_ID, I935_DEVICE_ID }, 179 { INI_VENDOR_ID, I920_DEVICE_ID }, 180 { DMX_VENDOR_ID, I920_DEVICE_ID }, 181 }; 182 183 #define DEBUG_INTERRUPT 0 184 #define DEBUG_QUEUE 0 185 #define DEBUG_STATE 0 186 #define INT_DISC 0 187 188 /*--- external functions --*/ 189 static void tul_se2_wait(void); 190 191 /*--- forward refrence ---*/ 192 static SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun); 193 static SCB *tul_find_done_scb(HCS * pCurHcb); 194 195 static int tulip_main(HCS * pCurHcb); 196 197 static int tul_next_state(HCS * pCurHcb); 198 static int tul_state_1(HCS * pCurHcb); 199 static int tul_state_2(HCS * pCurHcb); 200 static int tul_state_3(HCS * pCurHcb); 201 static int tul_state_4(HCS * pCurHcb); 202 static int tul_state_5(HCS * pCurHcb); 203 static int tul_state_6(HCS * pCurHcb); 204 static int tul_state_7(HCS * pCurHcb); 205 static int tul_xfer_data_in(HCS * pCurHcb); 206 static int tul_xfer_data_out(HCS * pCurHcb); 207 static int tul_xpad_in(HCS * pCurHcb); 208 static int tul_xpad_out(HCS * pCurHcb); 209 static int tul_status_msg(HCS * pCurHcb); 210 211 static int tul_msgin(HCS * pCurHcb); 212 static int tul_msgin_sync(HCS * pCurHcb); 213 static int tul_msgin_accept(HCS * pCurHcb); 214 static int tul_msgout_reject(HCS * pCurHcb); 215 static int tul_msgin_extend(HCS * pCurHcb); 216 217 static int tul_msgout_ide(HCS * pCurHcb); 218 static int tul_msgout_abort_targ(HCS * pCurHcb); 219 static int tul_msgout_abort_tag(HCS * pCurHcb); 220 221 static int tul_bus_device_reset(HCS * pCurHcb); 222 static void tul_select_atn(HCS * pCurHcb, SCB * pCurScb); 223 static void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb); 224 static void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb); 225 static int int_tul_busfree(HCS * pCurHcb); 226 static int int_tul_scsi_rst(HCS * pCurHcb); 227 static int int_tul_bad_seq(HCS * pCurHcb); 228 static int int_tul_resel(HCS * pCurHcb); 229 static int tul_sync_done(HCS * pCurHcb); 230 static int wdtr_done(HCS * pCurHcb); 231 static int wait_tulip(HCS * pCurHcb); 232 static int tul_wait_done_disc(HCS * pCurHcb); 233 static int tul_wait_disc(HCS * pCurHcb); 234 static void tulip_scsi(HCS * pCurHcb); 235 static int tul_post_scsi_rst(HCS * pCurHcb); 236 237 static void tul_se2_ew_en(WORD CurBase); 238 static void tul_se2_ew_ds(WORD CurBase); 239 static int tul_se2_rd_all(WORD CurBase); 240 static void tul_se2_update_all(WORD CurBase); /* setup default pattern */ 241 static void tul_read_eeprom(WORD CurBase); 242 243 /* ---- INTERNAL VARIABLES ---- */ 244 static HCS tul_hcs[MAX_SUPPORTED_ADAPTERS]; 245 static INI_ADPT_STRUCT i91u_adpt[MAX_SUPPORTED_ADAPTERS]; 246 247 /*NVRAM nvram, *nvramp = &nvram; */ 248 static NVRAM i91unvram; 249 static NVRAM *i91unvramp; 250 251 252 253 static UCHAR i91udftNvRam[64] = 254 { 255 /*----------- header -----------*/ 256 0x25, 0xc9, /* Signature */ 257 0x40, /* Size */ 258 0x01, /* Revision */ 259 /* -- Host Adapter Structure -- */ 260 0x95, /* ModelByte0 */ 261 0x00, /* ModelByte1 */ 262 0x00, /* ModelInfo */ 263 0x01, /* NumOfCh */ 264 NBC1_DEFAULT, /* BIOSConfig1 */ 265 0, /* BIOSConfig2 */ 266 0, /* HAConfig1 */ 267 0, /* HAConfig2 */ 268 /* SCSI channel 0 and target Structure */ 269 7, /* SCSIid */ 270 NCC1_DEFAULT, /* SCSIconfig1 */ 271 0, /* SCSIconfig2 */ 272 0x10, /* NumSCSItarget */ 273 274 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, 275 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, 276 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, 277 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, 278 279 /* SCSI channel 1 and target Structure */ 280 7, /* SCSIid */ 281 NCC1_DEFAULT, /* SCSIconfig1 */ 282 0, /* SCSIconfig2 */ 283 0x10, /* NumSCSItarget */ 284 285 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, 286 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, 287 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, 288 NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, NTC_DEFAULT, 289 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 290 0, 0}; /* - CheckSum - */ 291 292 293 static UCHAR tul_rate_tbl[8] = /* fast 20 */ 294 { 295 /* nanosecond devide by 4 */ 296 12, /* 50ns, 20M */ 297 18, /* 75ns, 13.3M */ 298 25, /* 100ns, 10M */ 299 31, /* 125ns, 8M */ 300 37, /* 150ns, 6.6M */ 301 43, /* 175ns, 5.7M */ 302 50, /* 200ns, 5M */ 303 62 /* 250ns, 4M */ 304 }; 305 306 static void tul_do_pause(unsigned amount) 307 { /* Pause for amount jiffies */ 308 unsigned long the_time = jiffies + amount; 309 310 while (time_before_eq(jiffies, the_time)); 311 } 312 313 /*-- forward reference --*/ 314 315 /******************************************************************* 316 Use memeory refresh time ~ 15us * 2 317 ********************************************************************/ 318 void tul_se2_wait(void) 319 { 320 #if 1 321 udelay(30); 322 #else 323 UCHAR readByte; 324 325 readByte = TUL_RD(0, 0x61); 326 if ((readByte & 0x10) == 0x10) { 327 for (;;) { 328 readByte = TUL_RD(0, 0x61); 329 if ((readByte & 0x10) == 0x10) 330 break; 331 } 332 for (;;) { 333 readByte = TUL_RD(0, 0x61); 334 if ((readByte & 0x10) != 0x10) 335 break; 336 } 337 } else { 338 for (;;) { 339 readByte = TUL_RD(0, 0x61); 340 if ((readByte & 0x10) == 0x10) 341 break; 342 } 343 for (;;) { 344 readByte = TUL_RD(0, 0x61); 345 if ((readByte & 0x10) != 0x10) 346 break; 347 } 348 } 349 #endif 350 } 351 352 353 /****************************************************************** 354 Input: instruction for Serial E2PROM 355 356 EX: se2_rd(0 call se2_instr() to send address and read command 357 358 StartBit OP_Code Address Data 359 --------- -------- ------------------ ------- 360 1 1 , 0 A5,A4,A3,A2,A1,A0 D15-D0 361 362 +----------------------------------------------------- 363 | 364 CS -----+ 365 +--+ +--+ +--+ +--+ +--+ 366 ^ | ^ | ^ | ^ | ^ | 367 | | | | | | | | | | 368 CLK -------+ +--+ +--+ +--+ +--+ +-- 369 (leading edge trigger) 370 371 +--1-----1--+ 372 | SB OP | OP A5 A4 373 DI ----+ +--0------------------ 374 (address and cmd sent to nvram) 375 376 -------------------------------------------+ 377 | 378 DO +--- 379 (data sent from nvram) 380 381 382 ******************************************************************/ 383 static void tul_se2_instr(WORD CurBase, UCHAR instr) 384 { 385 int i; 386 UCHAR b; 387 388 TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2DO); /* cs+start bit */ 389 tul_se2_wait(); 390 TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK | SE2DO); /* +CLK */ 391 tul_se2_wait(); 392 393 for (i = 0; i < 8; i++) { 394 if (instr & 0x80) 395 b = SE2CS | SE2DO; /* -CLK+dataBit */ 396 else 397 b = SE2CS; /* -CLK */ 398 TUL_WR(CurBase + TUL_NVRAM, b); 399 tul_se2_wait(); 400 TUL_WR(CurBase + TUL_NVRAM, b | SE2CLK); /* +CLK */ 401 tul_se2_wait(); 402 instr <<= 1; 403 } 404 TUL_WR(CurBase + TUL_NVRAM, SE2CS); /* -CLK */ 405 tul_se2_wait(); 406 return; 407 } 408 409 410 /****************************************************************** 411 Function name : tul_se2_ew_en 412 Description : Enable erase/write state of serial EEPROM 413 ******************************************************************/ 414 void tul_se2_ew_en(WORD CurBase) 415 { 416 tul_se2_instr(CurBase, 0x30); /* EWEN */ 417 TUL_WR(CurBase + TUL_NVRAM, 0); /* -CS */ 418 tul_se2_wait(); 419 return; 420 } 421 422 423 /************************************************************************ 424 Disable erase/write state of serial EEPROM 425 *************************************************************************/ 426 void tul_se2_ew_ds(WORD CurBase) 427 { 428 tul_se2_instr(CurBase, 0); /* EWDS */ 429 TUL_WR(CurBase + TUL_NVRAM, 0); /* -CS */ 430 tul_se2_wait(); 431 return; 432 } 433 434 435 /****************************************************************** 436 Input :address of Serial E2PROM 437 Output :value stored in Serial E2PROM 438 *******************************************************************/ 439 static USHORT tul_se2_rd(WORD CurBase, ULONG adr) 440 { 441 UCHAR instr, readByte; 442 USHORT readWord; 443 int i; 444 445 instr = (UCHAR) (adr | 0x80); 446 tul_se2_instr(CurBase, instr); /* READ INSTR */ 447 readWord = 0; 448 449 for (i = 15; i >= 0; i--) { 450 TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK); /* +CLK */ 451 tul_se2_wait(); 452 TUL_WR(CurBase + TUL_NVRAM, SE2CS); /* -CLK */ 453 454 /* sample data after the following edge of clock */ 455 readByte = TUL_RD(CurBase, TUL_NVRAM); 456 readByte &= SE2DI; 457 readWord += (readByte << i); 458 tul_se2_wait(); /* 6/20/95 */ 459 } 460 461 TUL_WR(CurBase + TUL_NVRAM, 0); /* no chip select */ 462 tul_se2_wait(); 463 return readWord; 464 } 465 466 467 /****************************************************************** 468 Input: new value in Serial E2PROM, address of Serial E2PROM 469 *******************************************************************/ 470 static void tul_se2_wr(WORD CurBase, UCHAR adr, USHORT writeWord) 471 { 472 UCHAR readByte; 473 UCHAR instr; 474 int i; 475 476 instr = (UCHAR) (adr | 0x40); 477 tul_se2_instr(CurBase, instr); /* WRITE INSTR */ 478 for (i = 15; i >= 0; i--) { 479 if (writeWord & 0x8000) 480 TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2DO); /* -CLK+dataBit 1 */ 481 else 482 TUL_WR(CurBase + TUL_NVRAM, SE2CS); /* -CLK+dataBit 0 */ 483 tul_se2_wait(); 484 TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK); /* +CLK */ 485 tul_se2_wait(); 486 writeWord <<= 1; 487 } 488 TUL_WR(CurBase + TUL_NVRAM, SE2CS); /* -CLK */ 489 tul_se2_wait(); 490 TUL_WR(CurBase + TUL_NVRAM, 0); /* -CS */ 491 tul_se2_wait(); 492 493 TUL_WR(CurBase + TUL_NVRAM, SE2CS); /* +CS */ 494 tul_se2_wait(); 495 496 for (;;) { 497 TUL_WR(CurBase + TUL_NVRAM, SE2CS | SE2CLK); /* +CLK */ 498 tul_se2_wait(); 499 TUL_WR(CurBase + TUL_NVRAM, SE2CS); /* -CLK */ 500 tul_se2_wait(); 501 if ((readByte = TUL_RD(CurBase, TUL_NVRAM)) & SE2DI) 502 break; /* write complete */ 503 } 504 TUL_WR(CurBase + TUL_NVRAM, 0); /* -CS */ 505 return; 506 } 507 508 509 /*********************************************************************** 510 Read SCSI H/A configuration parameters from serial EEPROM 511 ************************************************************************/ 512 int tul_se2_rd_all(WORD CurBase) 513 { 514 int i; 515 ULONG chksum = 0; 516 USHORT *np; 517 518 i91unvramp = &i91unvram; 519 np = (USHORT *) i91unvramp; 520 for (i = 0; i < 32; i++) { 521 *np++ = tul_se2_rd(CurBase, i); 522 } 523 524 /*--------------------Is signature "ini" ok ? ----------------*/ 525 if (i91unvramp->NVM_Signature != INI_SIGNATURE) 526 return -1; 527 /*---------------------- Is ckecksum ok ? ----------------------*/ 528 np = (USHORT *) i91unvramp; 529 for (i = 0; i < 31; i++) 530 chksum += *np++; 531 if (i91unvramp->NVM_CheckSum != (USHORT) chksum) 532 return -1; 533 return 1; 534 } 535 536 537 /*********************************************************************** 538 Update SCSI H/A configuration parameters from serial EEPROM 539 ************************************************************************/ 540 void tul_se2_update_all(WORD CurBase) 541 { /* setup default pattern */ 542 int i; 543 ULONG chksum = 0; 544 USHORT *np, *np1; 545 546 i91unvramp = &i91unvram; 547 /* Calculate checksum first */ 548 np = (USHORT *) i91udftNvRam; 549 for (i = 0; i < 31; i++) 550 chksum += *np++; 551 *np = (USHORT) chksum; 552 tul_se2_ew_en(CurBase); /* Enable write */ 553 554 np = (USHORT *) i91udftNvRam; 555 np1 = (USHORT *) i91unvramp; 556 for (i = 0; i < 32; i++, np++, np1++) { 557 if (*np != *np1) { 558 tul_se2_wr(CurBase, i, *np); 559 } 560 } 561 562 tul_se2_ew_ds(CurBase); /* Disable write */ 563 return; 564 } 565 566 /************************************************************************* 567 Function name : read_eeprom 568 **************************************************************************/ 569 void tul_read_eeprom(WORD CurBase) 570 { 571 UCHAR gctrl; 572 573 i91unvramp = &i91unvram; 574 /*------Enable EEProm programming ---*/ 575 gctrl = TUL_RD(CurBase, TUL_GCTRL); 576 TUL_WR(CurBase + TUL_GCTRL, gctrl | TUL_GCTRL_EEPROM_BIT); 577 if (tul_se2_rd_all(CurBase) != 1) { 578 tul_se2_update_all(CurBase); /* setup default pattern */ 579 tul_se2_rd_all(CurBase); /* load again */ 580 } 581 /*------ Disable EEProm programming ---*/ 582 gctrl = TUL_RD(CurBase, TUL_GCTRL); 583 TUL_WR(CurBase + TUL_GCTRL, gctrl & ~TUL_GCTRL_EEPROM_BIT); 584 } /* read_eeprom */ 585 586 static int Addi91u_into_Adapter_table(WORD wBIOS, WORD wBASE, BYTE bInterrupt, 587 BYTE bBus, BYTE bDevice) 588 { 589 int i, j; 590 591 for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) { 592 if (i91u_adpt[i].ADPT_BIOS < wBIOS) 593 continue; 594 if (i91u_adpt[i].ADPT_BIOS == wBIOS) { 595 if (i91u_adpt[i].ADPT_BASE == wBASE) { 596 if (i91u_adpt[i].ADPT_Bus != 0xFF) 597 return 1; 598 } else if (i91u_adpt[i].ADPT_BASE < wBASE) 599 continue; 600 } 601 for (j = MAX_SUPPORTED_ADAPTERS - 1; j > i; j--) { 602 i91u_adpt[j].ADPT_BASE = i91u_adpt[j - 1].ADPT_BASE; 603 i91u_adpt[j].ADPT_INTR = i91u_adpt[j - 1].ADPT_INTR; 604 i91u_adpt[j].ADPT_BIOS = i91u_adpt[j - 1].ADPT_BIOS; 605 i91u_adpt[j].ADPT_Bus = i91u_adpt[j - 1].ADPT_Bus; 606 i91u_adpt[j].ADPT_Device = i91u_adpt[j - 1].ADPT_Device; 607 } 608 i91u_adpt[i].ADPT_BASE = wBASE; 609 i91u_adpt[i].ADPT_INTR = bInterrupt; 610 i91u_adpt[i].ADPT_BIOS = wBIOS; 611 i91u_adpt[i].ADPT_Bus = bBus; 612 i91u_adpt[i].ADPT_Device = bDevice; 613 return 0; 614 } 615 return 1; 616 } 617 618 static void init_i91uAdapter_table(void) 619 { 620 int i; 621 622 for (i = 0; i < MAX_SUPPORTED_ADAPTERS; i++) { /* Initialize adapter structure */ 623 i91u_adpt[i].ADPT_BIOS = 0xffff; 624 i91u_adpt[i].ADPT_BASE = 0xffff; 625 i91u_adpt[i].ADPT_INTR = 0xff; 626 i91u_adpt[i].ADPT_Bus = 0xff; 627 i91u_adpt[i].ADPT_Device = 0xff; 628 } 629 return; 630 } 631 632 static void tul_stop_bm(HCS * pCurHcb) 633 { 634 635 if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) { /* if DMA xfer is pending, abort DMA xfer */ 636 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT | TAX_X_CLR_FIFO); 637 /* wait Abort DMA xfer done */ 638 while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & XABT) == 0); 639 } 640 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 641 } 642 643 /***************************************************************************/ 644 static void get_tulipPCIConfig(HCS * pCurHcb, int ch_idx) 645 { 646 pCurHcb->HCS_Base = i91u_adpt[ch_idx].ADPT_BASE; /* Supply base address */ 647 pCurHcb->HCS_BIOS = i91u_adpt[ch_idx].ADPT_BIOS; /* Supply BIOS address */ 648 pCurHcb->HCS_Intr = i91u_adpt[ch_idx].ADPT_INTR; /* Supply interrupt line */ 649 return; 650 } 651 652 /***************************************************************************/ 653 static int tul_reset_scsi(HCS * pCurHcb, int seconds) 654 { 655 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_BUS); 656 657 while (!((pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt)) & TSS_SCSIRST_INT)); 658 /* reset tulip chip */ 659 660 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, 0); 661 662 /* Stall for a while, wait for target's firmware ready,make it 2 sec ! */ 663 /* SONY 5200 tape drive won't work if only stall for 1 sec */ 664 tul_do_pause(seconds * HZ); 665 666 TUL_RD(pCurHcb->HCS_Base, TUL_SInt); 667 668 return (SCSI_RESET_SUCCESS); 669 } 670 671 /***************************************************************************/ 672 static int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb, 673 BYTE * pbBiosAdr, int seconds) 674 { 675 int i; 676 BYTE *pwFlags; 677 BYTE *pbHeads; 678 SCB *pTmpScb, *pPrevScb = NULL; 679 680 pCurHcb->HCS_NumScbs = tul_num_scb; 681 pCurHcb->HCS_Semaph = 1; 682 spin_lock_init(&pCurHcb->HCS_SemaphLock); 683 pCurHcb->HCS_JSStatus0 = 0; 684 pCurHcb->HCS_Scb = scbp; 685 pCurHcb->HCS_NxtPend = scbp; 686 pCurHcb->HCS_NxtAvail = scbp; 687 for (i = 0, pTmpScb = scbp; i < tul_num_scb; i++, pTmpScb++) { 688 pTmpScb->SCB_TagId = i; 689 if (i != 0) 690 pPrevScb->SCB_NxtScb = pTmpScb; 691 pPrevScb = pTmpScb; 692 } 693 pPrevScb->SCB_NxtScb = NULL; 694 pCurHcb->HCS_ScbEnd = pTmpScb; 695 pCurHcb->HCS_FirstAvail = scbp; 696 pCurHcb->HCS_LastAvail = pPrevScb; 697 spin_lock_init(&pCurHcb->HCS_AvailLock); 698 pCurHcb->HCS_FirstPend = NULL; 699 pCurHcb->HCS_LastPend = NULL; 700 pCurHcb->HCS_FirstBusy = NULL; 701 pCurHcb->HCS_LastBusy = NULL; 702 pCurHcb->HCS_FirstDone = NULL; 703 pCurHcb->HCS_LastDone = NULL; 704 pCurHcb->HCS_ActScb = NULL; 705 pCurHcb->HCS_ActTcs = NULL; 706 707 tul_read_eeprom(pCurHcb->HCS_Base); 708 /*---------- get H/A configuration -------------*/ 709 if (i91unvramp->NVM_SCSIInfo[0].NVM_NumOfTarg == 8) 710 pCurHcb->HCS_MaxTar = 8; 711 else 712 pCurHcb->HCS_MaxTar = 16; 713 714 pCurHcb->HCS_Config = i91unvramp->NVM_SCSIInfo[0].NVM_ChConfig1; 715 716 pCurHcb->HCS_SCSI_ID = i91unvramp->NVM_SCSIInfo[0].NVM_ChSCSIID; 717 pCurHcb->HCS_IdMask = ~(1 << pCurHcb->HCS_SCSI_ID); 718 719 #ifdef CHK_PARITY 720 /* Enable parity error response */ 721 TUL_WR(pCurHcb->HCS_Base + TUL_PCMD, TUL_RD(pCurHcb->HCS_Base, TUL_PCMD) | 0x40); 722 #endif 723 724 /* Mask all the interrupt */ 725 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 726 727 tul_stop_bm(pCurHcb); 728 /* --- Initialize the tulip --- */ 729 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_CHIP); 730 731 /* program HBA's SCSI ID */ 732 TUL_WR(pCurHcb->HCS_Base + TUL_SScsiId, pCurHcb->HCS_SCSI_ID << 4); 733 734 /* Enable Initiator Mode ,phase latch,alternate sync period mode, 735 disable SCSI reset */ 736 if (pCurHcb->HCS_Config & HCC_EN_PAR) 737 pCurHcb->HCS_SConf1 = (TSC_INITDEFAULT | TSC_EN_SCSI_PAR); 738 else 739 pCurHcb->HCS_SConf1 = (TSC_INITDEFAULT); 740 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_SConf1); 741 742 /* Enable HW reselect */ 743 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); 744 745 TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, 0); 746 747 /* selection time out = 250 ms */ 748 TUL_WR(pCurHcb->HCS_Base + TUL_STimeOut, 153); 749 750 /*--------- Enable SCSI terminator -----*/ 751 TUL_WR(pCurHcb->HCS_Base + TUL_XCtrl, (pCurHcb->HCS_Config & (HCC_ACT_TERM1 | HCC_ACT_TERM2))); 752 TUL_WR(pCurHcb->HCS_Base + TUL_GCTRL1, 753 ((pCurHcb->HCS_Config & HCC_AUTO_TERM) >> 4) | (TUL_RD(pCurHcb->HCS_Base, TUL_GCTRL1) & 0xFE)); 754 755 for (i = 0, 756 pwFlags = & (i91unvramp->NVM_SCSIInfo[0].NVM_Targ0Config), 757 pbHeads = pbBiosAdr + 0x180; 758 i < pCurHcb->HCS_MaxTar; 759 i++, pwFlags++) { 760 pCurHcb->HCS_Tcs[i].TCS_Flags = *pwFlags & ~(TCF_SYNC_DONE | TCF_WDTR_DONE); 761 if (pCurHcb->HCS_Tcs[i].TCS_Flags & TCF_EN_255) 762 pCurHcb->HCS_Tcs[i].TCS_DrvFlags = TCF_DRV_255_63; 763 else 764 pCurHcb->HCS_Tcs[i].TCS_DrvFlags = 0; 765 pCurHcb->HCS_Tcs[i].TCS_JS_Period = 0; 766 pCurHcb->HCS_Tcs[i].TCS_SConfig0 = pCurHcb->HCS_SConf1; 767 pCurHcb->HCS_Tcs[i].TCS_DrvHead = *pbHeads++; 768 if (pCurHcb->HCS_Tcs[i].TCS_DrvHead == 255) 769 pCurHcb->HCS_Tcs[i].TCS_DrvFlags = TCF_DRV_255_63; 770 else 771 pCurHcb->HCS_Tcs[i].TCS_DrvFlags = 0; 772 pCurHcb->HCS_Tcs[i].TCS_DrvSector = *pbHeads++; 773 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~TCF_BUSY; 774 pCurHcb->HCS_ActTags[i] = 0; 775 pCurHcb->HCS_MaxTags[i] = 0xFF; 776 } /* for */ 777 printk("i91u: PCI Base=0x%04X, IRQ=%d, BIOS=0x%04X0, SCSI ID=%d\n", 778 pCurHcb->HCS_Base, pCurHcb->HCS_Intr, 779 pCurHcb->HCS_BIOS, pCurHcb->HCS_SCSI_ID); 780 /*------------------- reset SCSI Bus ---------------------------*/ 781 if (pCurHcb->HCS_Config & HCC_SCSI_RESET) { 782 printk("i91u: Reset SCSI Bus ... \n"); 783 tul_reset_scsi(pCurHcb, seconds); 784 } 785 TUL_WR(pCurHcb->HCS_Base + TUL_SCFG1, 0x17); 786 TUL_WR(pCurHcb->HCS_Base + TUL_SIntEnable, 0xE9); 787 return (0); 788 } 789 790 /***************************************************************************/ 791 static SCB *tul_alloc_scb(HCS * hcsp) 792 { 793 SCB *pTmpScb; 794 ULONG flags; 795 spin_lock_irqsave(&(hcsp->HCS_AvailLock), flags); 796 if ((pTmpScb = hcsp->HCS_FirstAvail) != NULL) { 797 #if DEBUG_QUEUE 798 printk("find scb at %08lx\n", (ULONG) pTmpScb); 799 #endif 800 if ((hcsp->HCS_FirstAvail = pTmpScb->SCB_NxtScb) == NULL) 801 hcsp->HCS_LastAvail = NULL; 802 pTmpScb->SCB_NxtScb = NULL; 803 pTmpScb->SCB_Status = SCB_RENT; 804 } 805 spin_unlock_irqrestore(&(hcsp->HCS_AvailLock), flags); 806 return (pTmpScb); 807 } 808 809 /***************************************************************************/ 810 static void tul_release_scb(HCS * hcsp, SCB * scbp) 811 { 812 ULONG flags; 813 814 #if DEBUG_QUEUE 815 printk("Release SCB %lx; ", (ULONG) scbp); 816 #endif 817 spin_lock_irqsave(&(hcsp->HCS_AvailLock), flags); 818 scbp->SCB_Srb = NULL; 819 scbp->SCB_Status = 0; 820 scbp->SCB_NxtScb = NULL; 821 if (hcsp->HCS_LastAvail != NULL) { 822 hcsp->HCS_LastAvail->SCB_NxtScb = scbp; 823 hcsp->HCS_LastAvail = scbp; 824 } else { 825 hcsp->HCS_FirstAvail = scbp; 826 hcsp->HCS_LastAvail = scbp; 827 } 828 spin_unlock_irqrestore(&(hcsp->HCS_AvailLock), flags); 829 } 830 831 /***************************************************************************/ 832 static void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp) 833 { 834 835 #if DEBUG_QUEUE 836 printk("Append pend SCB %lx; ", (ULONG) scbp); 837 #endif 838 scbp->SCB_Status = SCB_PEND; 839 scbp->SCB_NxtScb = NULL; 840 if (pCurHcb->HCS_LastPend != NULL) { 841 pCurHcb->HCS_LastPend->SCB_NxtScb = scbp; 842 pCurHcb->HCS_LastPend = scbp; 843 } else { 844 pCurHcb->HCS_FirstPend = scbp; 845 pCurHcb->HCS_LastPend = scbp; 846 } 847 } 848 849 /***************************************************************************/ 850 static void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp) 851 { 852 853 #if DEBUG_QUEUE 854 printk("Push pend SCB %lx; ", (ULONG) scbp); 855 #endif 856 scbp->SCB_Status = SCB_PEND; 857 if ((scbp->SCB_NxtScb = pCurHcb->HCS_FirstPend) != NULL) { 858 pCurHcb->HCS_FirstPend = scbp; 859 } else { 860 pCurHcb->HCS_FirstPend = scbp; 861 pCurHcb->HCS_LastPend = scbp; 862 } 863 } 864 865 /***************************************************************************/ 866 static SCB *tul_find_first_pend_scb(HCS * pCurHcb) 867 { 868 SCB *pFirstPend; 869 870 871 pFirstPend = pCurHcb->HCS_FirstPend; 872 while (pFirstPend != NULL) { 873 if (pFirstPend->SCB_Opcode != ExecSCSI) { 874 return (pFirstPend); 875 } 876 if (pFirstPend->SCB_TagMsg == 0) { 877 if ((pCurHcb->HCS_ActTags[pFirstPend->SCB_Target] == 0) && 878 !(pCurHcb->HCS_Tcs[pFirstPend->SCB_Target].TCS_Flags & TCF_BUSY)) { 879 return (pFirstPend); 880 } 881 } else { 882 if ((pCurHcb->HCS_ActTags[pFirstPend->SCB_Target] >= 883 pCurHcb->HCS_MaxTags[pFirstPend->SCB_Target]) | 884 (pCurHcb->HCS_Tcs[pFirstPend->SCB_Target].TCS_Flags & TCF_BUSY)) { 885 pFirstPend = pFirstPend->SCB_NxtScb; 886 continue; 887 } 888 return (pFirstPend); 889 } 890 pFirstPend = pFirstPend->SCB_NxtScb; 891 } 892 893 894 return (pFirstPend); 895 } 896 /***************************************************************************/ 897 static void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb) 898 { 899 SCB *pTmpScb, *pPrevScb; 900 901 #if DEBUG_QUEUE 902 printk("unlink pend SCB %lx; ", (ULONG) pCurScb); 903 #endif 904 905 pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend; 906 while (pTmpScb != NULL) { 907 if (pCurScb == pTmpScb) { /* Unlink this SCB */ 908 if (pTmpScb == pCurHcb->HCS_FirstPend) { 909 if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL) 910 pCurHcb->HCS_LastPend = NULL; 911 } else { 912 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; 913 if (pTmpScb == pCurHcb->HCS_LastPend) 914 pCurHcb->HCS_LastPend = pPrevScb; 915 } 916 pTmpScb->SCB_NxtScb = NULL; 917 break; 918 } 919 pPrevScb = pTmpScb; 920 pTmpScb = pTmpScb->SCB_NxtScb; 921 } 922 return; 923 } 924 /***************************************************************************/ 925 static void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp) 926 { 927 928 #if DEBUG_QUEUE 929 printk("append busy SCB %lx; ", (ULONG) scbp); 930 #endif 931 if (scbp->SCB_TagMsg) 932 pCurHcb->HCS_ActTags[scbp->SCB_Target]++; 933 else 934 pCurHcb->HCS_Tcs[scbp->SCB_Target].TCS_Flags |= TCF_BUSY; 935 scbp->SCB_Status = SCB_BUSY; 936 scbp->SCB_NxtScb = NULL; 937 if (pCurHcb->HCS_LastBusy != NULL) { 938 pCurHcb->HCS_LastBusy->SCB_NxtScb = scbp; 939 pCurHcb->HCS_LastBusy = scbp; 940 } else { 941 pCurHcb->HCS_FirstBusy = scbp; 942 pCurHcb->HCS_LastBusy = scbp; 943 } 944 } 945 946 /***************************************************************************/ 947 static SCB *tul_pop_busy_scb(HCS * pCurHcb) 948 { 949 SCB *pTmpScb; 950 951 952 if ((pTmpScb = pCurHcb->HCS_FirstBusy) != NULL) { 953 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL) 954 pCurHcb->HCS_LastBusy = NULL; 955 pTmpScb->SCB_NxtScb = NULL; 956 if (pTmpScb->SCB_TagMsg) 957 pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--; 958 else 959 pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY; 960 } 961 #if DEBUG_QUEUE 962 printk("Pop busy SCB %lx; ", (ULONG) pTmpScb); 963 #endif 964 return (pTmpScb); 965 } 966 967 /***************************************************************************/ 968 static void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb) 969 { 970 SCB *pTmpScb, *pPrevScb; 971 972 #if DEBUG_QUEUE 973 printk("unlink busy SCB %lx; ", (ULONG) pCurScb); 974 #endif 975 976 pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; 977 while (pTmpScb != NULL) { 978 if (pCurScb == pTmpScb) { /* Unlink this SCB */ 979 if (pTmpScb == pCurHcb->HCS_FirstBusy) { 980 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL) 981 pCurHcb->HCS_LastBusy = NULL; 982 } else { 983 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; 984 if (pTmpScb == pCurHcb->HCS_LastBusy) 985 pCurHcb->HCS_LastBusy = pPrevScb; 986 } 987 pTmpScb->SCB_NxtScb = NULL; 988 if (pTmpScb->SCB_TagMsg) 989 pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--; 990 else 991 pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY; 992 break; 993 } 994 pPrevScb = pTmpScb; 995 pTmpScb = pTmpScb->SCB_NxtScb; 996 } 997 return; 998 } 999 1000 /***************************************************************************/ 1001 SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun) 1002 { 1003 SCB *pTmpScb, *pPrevScb; 1004 WORD scbp_tarlun; 1005 1006 1007 pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; 1008 while (pTmpScb != NULL) { 1009 scbp_tarlun = (pTmpScb->SCB_Lun << 8) | (pTmpScb->SCB_Target); 1010 if (scbp_tarlun == tarlun) { /* Unlink this SCB */ 1011 break; 1012 } 1013 pPrevScb = pTmpScb; 1014 pTmpScb = pTmpScb->SCB_NxtScb; 1015 } 1016 #if DEBUG_QUEUE 1017 printk("find busy SCB %lx; ", (ULONG) pTmpScb); 1018 #endif 1019 return (pTmpScb); 1020 } 1021 1022 /***************************************************************************/ 1023 static void tul_append_done_scb(HCS * pCurHcb, SCB * scbp) 1024 { 1025 1026 #if DEBUG_QUEUE 1027 printk("append done SCB %lx; ", (ULONG) scbp); 1028 #endif 1029 1030 scbp->SCB_Status = SCB_DONE; 1031 scbp->SCB_NxtScb = NULL; 1032 if (pCurHcb->HCS_LastDone != NULL) { 1033 pCurHcb->HCS_LastDone->SCB_NxtScb = scbp; 1034 pCurHcb->HCS_LastDone = scbp; 1035 } else { 1036 pCurHcb->HCS_FirstDone = scbp; 1037 pCurHcb->HCS_LastDone = scbp; 1038 } 1039 } 1040 1041 /***************************************************************************/ 1042 SCB *tul_find_done_scb(HCS * pCurHcb) 1043 { 1044 SCB *pTmpScb; 1045 1046 1047 if ((pTmpScb = pCurHcb->HCS_FirstDone) != NULL) { 1048 if ((pCurHcb->HCS_FirstDone = pTmpScb->SCB_NxtScb) == NULL) 1049 pCurHcb->HCS_LastDone = NULL; 1050 pTmpScb->SCB_NxtScb = NULL; 1051 } 1052 #if DEBUG_QUEUE 1053 printk("find done SCB %lx; ", (ULONG) pTmpScb); 1054 #endif 1055 return (pTmpScb); 1056 } 1057 1058 /***************************************************************************/ 1059 static int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp) 1060 { 1061 ULONG flags; 1062 SCB *pTmpScb, *pPrevScb; 1063 1064 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1065 1066 if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) { 1067 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 1068 /* disable Jasmin SCSI Int */ 1069 1070 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1071 1072 tulip_main(pCurHcb); 1073 1074 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1075 1076 pCurHcb->HCS_Semaph = 1; 1077 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); 1078 1079 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1080 1081 return SCSI_ABORT_SNOOZE; 1082 } 1083 pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend; /* Check Pend queue */ 1084 while (pTmpScb != NULL) { 1085 /* 07/27/98 */ 1086 if (pTmpScb->SCB_Srb == srbp) { 1087 if (pTmpScb == pCurHcb->HCS_ActScb) { 1088 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1089 return SCSI_ABORT_BUSY; 1090 } else if (pTmpScb == pCurHcb->HCS_FirstPend) { 1091 if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL) 1092 pCurHcb->HCS_LastPend = NULL; 1093 } else { 1094 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; 1095 if (pTmpScb == pCurHcb->HCS_LastPend) 1096 pCurHcb->HCS_LastPend = pPrevScb; 1097 } 1098 pTmpScb->SCB_HaStat = HOST_ABORTED; 1099 pTmpScb->SCB_Flags |= SCF_DONE; 1100 if (pTmpScb->SCB_Flags & SCF_POST) 1101 (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb); 1102 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1103 return SCSI_ABORT_SUCCESS; 1104 } 1105 pPrevScb = pTmpScb; 1106 pTmpScb = pTmpScb->SCB_NxtScb; 1107 } 1108 1109 pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */ 1110 while (pTmpScb != NULL) { 1111 1112 if (pTmpScb->SCB_Srb == srbp) { 1113 1114 if (pTmpScb == pCurHcb->HCS_ActScb) { 1115 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1116 return SCSI_ABORT_BUSY; 1117 } else if (pTmpScb->SCB_TagMsg == 0) { 1118 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1119 return SCSI_ABORT_BUSY; 1120 } else { 1121 pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--; 1122 if (pTmpScb == pCurHcb->HCS_FirstBusy) { 1123 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL) 1124 pCurHcb->HCS_LastBusy = NULL; 1125 } else { 1126 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; 1127 if (pTmpScb == pCurHcb->HCS_LastBusy) 1128 pCurHcb->HCS_LastBusy = pPrevScb; 1129 } 1130 pTmpScb->SCB_NxtScb = NULL; 1131 1132 1133 pTmpScb->SCB_HaStat = HOST_ABORTED; 1134 pTmpScb->SCB_Flags |= SCF_DONE; 1135 if (pTmpScb->SCB_Flags & SCF_POST) 1136 (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb); 1137 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1138 return SCSI_ABORT_SUCCESS; 1139 } 1140 } 1141 pPrevScb = pTmpScb; 1142 pTmpScb = pTmpScb->SCB_NxtScb; 1143 } 1144 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1145 return (SCSI_ABORT_NOT_RUNNING); 1146 } 1147 1148 /***************************************************************************/ 1149 static int tul_bad_seq(HCS * pCurHcb) 1150 { 1151 SCB *pCurScb; 1152 1153 printk("tul_bad_seg c=%d\n", pCurHcb->HCS_Index); 1154 1155 if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) { 1156 tul_unlink_busy_scb(pCurHcb, pCurScb); 1157 pCurScb->SCB_HaStat = HOST_BAD_PHAS; 1158 pCurScb->SCB_TaStat = 0; 1159 tul_append_done_scb(pCurHcb, pCurScb); 1160 } 1161 tul_stop_bm(pCurHcb); 1162 1163 tul_reset_scsi(pCurHcb, 8); /* 7/29/98 */ 1164 1165 return (tul_post_scsi_rst(pCurHcb)); 1166 } 1167 1168 #if 0 1169 1170 /************************************************************************/ 1171 static int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb, 1172 unsigned int target, unsigned int ResetFlags) 1173 { 1174 ULONG flags; 1175 SCB *pScb; 1176 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1177 1178 if (ResetFlags & SCSI_RESET_ASYNCHRONOUS) { 1179 1180 if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) { 1181 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 1182 /* disable Jasmin SCSI Int */ 1183 1184 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1185 1186 tulip_main(pCurHcb); 1187 1188 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1189 1190 pCurHcb->HCS_Semaph = 1; 1191 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); 1192 1193 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1194 1195 return SCSI_RESET_SNOOZE; 1196 } 1197 pScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */ 1198 while (pScb != NULL) { 1199 if (pScb->SCB_Srb == pSrb) 1200 break; 1201 pScb = pScb->SCB_NxtScb; 1202 } 1203 if (pScb == NULL) { 1204 printk("Unable to Reset - No SCB Found\n"); 1205 1206 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1207 return SCSI_RESET_NOT_RUNNING; 1208 } 1209 } 1210 if ((pScb = tul_alloc_scb(pCurHcb)) == NULL) { 1211 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1212 return SCSI_RESET_NOT_RUNNING; 1213 } 1214 pScb->SCB_Opcode = BusDevRst; 1215 pScb->SCB_Flags = SCF_POST; 1216 pScb->SCB_Target = target; 1217 pScb->SCB_Mode = 0; 1218 1219 pScb->SCB_Srb = NULL; 1220 if (ResetFlags & SCSI_RESET_SYNCHRONOUS) { 1221 pScb->SCB_Srb = pSrb; 1222 } 1223 tul_push_pend_scb(pCurHcb, pScb); /* push this SCB to Pending queue */ 1224 1225 if (pCurHcb->HCS_Semaph == 1) { 1226 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 1227 /* disable Jasmin SCSI Int */ 1228 pCurHcb->HCS_Semaph = 0; 1229 1230 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1231 1232 tulip_main(pCurHcb); 1233 1234 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1235 1236 pCurHcb->HCS_Semaph = 1; 1237 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); 1238 } 1239 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1240 return SCSI_RESET_PENDING; 1241 } 1242 1243 static int tul_reset_scsi_bus(HCS * pCurHcb) 1244 { 1245 ULONG flags; 1246 1247 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1248 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 1249 pCurHcb->HCS_Semaph = 0; 1250 1251 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1252 1253 tul_stop_bm(pCurHcb); 1254 1255 tul_reset_scsi(pCurHcb, 2); /* 7/29/98 */ 1256 1257 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1258 tul_post_scsi_rst(pCurHcb); 1259 1260 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1261 1262 tulip_main(pCurHcb); 1263 1264 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1265 1266 pCurHcb->HCS_Semaph = 1; 1267 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); 1268 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1269 return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET); 1270 } 1271 1272 #endif /* 0 */ 1273 1274 /************************************************************************/ 1275 static void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb) 1276 { 1277 ULONG flags; 1278 1279 pCurScb->SCB_Mode = 0; 1280 1281 pCurScb->SCB_SGIdx = 0; 1282 pCurScb->SCB_SGMax = pCurScb->SCB_SGLen; 1283 1284 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1285 1286 tul_append_pend_scb(pCurHcb, pCurScb); /* Append this SCB to Pending queue */ 1287 1288 /* VVVVV 07/21/98 */ 1289 if (pCurHcb->HCS_Semaph == 1) { 1290 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 1291 /* disable Jasmin SCSI Int */ 1292 pCurHcb->HCS_Semaph = 0; 1293 1294 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1295 1296 tulip_main(pCurHcb); 1297 1298 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1299 1300 pCurHcb->HCS_Semaph = 1; 1301 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); 1302 } 1303 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1304 return; 1305 } 1306 1307 /***************************************************************************/ 1308 static int tul_isr(HCS * pCurHcb) 1309 { 1310 /* Enter critical section */ 1311 1312 if (TUL_RD(pCurHcb->HCS_Base, TUL_Int) & TSS_INT_PENDING) { 1313 if (pCurHcb->HCS_Semaph == 1) { 1314 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 1315 /* Disable Tulip SCSI Int */ 1316 pCurHcb->HCS_Semaph = 0; 1317 1318 tulip_main(pCurHcb); 1319 1320 pCurHcb->HCS_Semaph = 1; 1321 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); 1322 return (1); 1323 } 1324 } 1325 return (0); 1326 } 1327 1328 /***************************************************************************/ 1329 int tulip_main(HCS * pCurHcb) 1330 { 1331 SCB *pCurScb; 1332 1333 for (;;) { 1334 1335 tulip_scsi(pCurHcb); /* Call tulip_scsi */ 1336 1337 while ((pCurScb = tul_find_done_scb(pCurHcb)) != NULL) { /* find done entry */ 1338 if (pCurScb->SCB_TaStat == INI_QUEUE_FULL) { 1339 pCurHcb->HCS_MaxTags[pCurScb->SCB_Target] = 1340 pCurHcb->HCS_ActTags[pCurScb->SCB_Target] - 1; 1341 pCurScb->SCB_TaStat = 0; 1342 tul_append_pend_scb(pCurHcb, pCurScb); 1343 continue; 1344 } 1345 if (!(pCurScb->SCB_Mode & SCM_RSENS)) { /* not in auto req. sense mode */ 1346 if (pCurScb->SCB_TaStat == 2) { 1347 1348 /* clr sync. nego flag */ 1349 1350 if (pCurScb->SCB_Flags & SCF_SENSE) { 1351 BYTE len; 1352 len = pCurScb->SCB_SenseLen; 1353 if (len == 0) 1354 len = 1; 1355 pCurScb->SCB_BufLen = pCurScb->SCB_SenseLen; 1356 pCurScb->SCB_BufPtr = pCurScb->SCB_SensePtr; 1357 pCurScb->SCB_Flags &= ~(SCF_SG | SCF_DIR); /* for xfer_data_in */ 1358 /* pCurScb->SCB_Flags |= SCF_NO_DCHK; */ 1359 /* so, we won't report worng direction in xfer_data_in, 1360 and won't report HOST_DO_DU in state_6 */ 1361 pCurScb->SCB_Mode = SCM_RSENS; 1362 pCurScb->SCB_Ident &= 0xBF; /* Disable Disconnect */ 1363 pCurScb->SCB_TagMsg = 0; 1364 pCurScb->SCB_TaStat = 0; 1365 pCurScb->SCB_CDBLen = 6; 1366 pCurScb->SCB_CDB[0] = SCSICMD_RequestSense; 1367 pCurScb->SCB_CDB[1] = 0; 1368 pCurScb->SCB_CDB[2] = 0; 1369 pCurScb->SCB_CDB[3] = 0; 1370 pCurScb->SCB_CDB[4] = len; 1371 pCurScb->SCB_CDB[5] = 0; 1372 tul_push_pend_scb(pCurHcb, pCurScb); 1373 break; 1374 } 1375 } 1376 } else { /* in request sense mode */ 1377 1378 if (pCurScb->SCB_TaStat == 2) { /* check contition status again after sending 1379 requset sense cmd 0x3 */ 1380 pCurScb->SCB_HaStat = HOST_BAD_PHAS; 1381 } 1382 pCurScb->SCB_TaStat = 2; 1383 } 1384 pCurScb->SCB_Flags |= SCF_DONE; 1385 if (pCurScb->SCB_Flags & SCF_POST) { 1386 (*pCurScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pCurScb); 1387 } 1388 } /* while */ 1389 1390 /* find_active: */ 1391 if (TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0) & TSS_INT_PENDING) 1392 continue; 1393 1394 if (pCurHcb->HCS_ActScb) { /* return to OS and wait for xfer_done_ISR/Selected_ISR */ 1395 return 1; /* return to OS, enable interrupt */ 1396 } 1397 /* Check pending SCB */ 1398 if (tul_find_first_pend_scb(pCurHcb) == NULL) { 1399 return 1; /* return to OS, enable interrupt */ 1400 } 1401 } /* End of for loop */ 1402 /* statement won't reach here */ 1403 } 1404 1405 1406 1407 1408 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 1409 /***************************************************************************/ 1410 /***************************************************************************/ 1411 /***************************************************************************/ 1412 /***************************************************************************/ 1413 1414 /***************************************************************************/ 1415 void tulip_scsi(HCS * pCurHcb) 1416 { 1417 SCB *pCurScb; 1418 TCS *pCurTcb; 1419 1420 /* make sure to service interrupt asap */ 1421 1422 if ((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0)) & TSS_INT_PENDING) { 1423 1424 pCurHcb->HCS_Phase = pCurHcb->HCS_JSStatus0 & TSS_PH_MASK; 1425 pCurHcb->HCS_JSStatus1 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1); 1426 pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt); 1427 if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) { /* SCSI bus reset detected */ 1428 int_tul_scsi_rst(pCurHcb); 1429 return; 1430 } 1431 if (pCurHcb->HCS_JSInt & TSS_RESEL_INT) { /* if selected/reselected interrupt */ 1432 if (int_tul_resel(pCurHcb) == 0) 1433 tul_next_state(pCurHcb); 1434 return; 1435 } 1436 if (pCurHcb->HCS_JSInt & TSS_SEL_TIMEOUT) { 1437 int_tul_busfree(pCurHcb); 1438 return; 1439 } 1440 if (pCurHcb->HCS_JSInt & TSS_DISC_INT) { /* BUS disconnection */ 1441 int_tul_busfree(pCurHcb); /* unexpected bus free or sel timeout */ 1442 return; 1443 } 1444 if (pCurHcb->HCS_JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) { /* func complete or Bus service */ 1445 if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) 1446 tul_next_state(pCurHcb); 1447 return; 1448 } 1449 } 1450 if (pCurHcb->HCS_ActScb != NULL) 1451 return; 1452 1453 if ((pCurScb = tul_find_first_pend_scb(pCurHcb)) == NULL) 1454 return; 1455 1456 /* program HBA's SCSI ID & target SCSI ID */ 1457 TUL_WR(pCurHcb->HCS_Base + TUL_SScsiId, 1458 (pCurHcb->HCS_SCSI_ID << 4) | (pCurScb->SCB_Target & 0x0F)); 1459 if (pCurScb->SCB_Opcode == ExecSCSI) { 1460 pCurTcb = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target]; 1461 1462 if (pCurScb->SCB_TagMsg) 1463 pCurTcb->TCS_DrvFlags |= TCF_DRV_EN_TAG; 1464 else 1465 pCurTcb->TCS_DrvFlags &= ~TCF_DRV_EN_TAG; 1466 1467 TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurTcb->TCS_JS_Period); 1468 if ((pCurTcb->TCS_Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) { /* do wdtr negotiation */ 1469 tul_select_atn_stop(pCurHcb, pCurScb); 1470 } else { 1471 if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) { /* do sync negotiation */ 1472 tul_select_atn_stop(pCurHcb, pCurScb); 1473 } else { 1474 if (pCurScb->SCB_TagMsg) 1475 tul_select_atn3(pCurHcb, pCurScb); 1476 else 1477 tul_select_atn(pCurHcb, pCurScb); 1478 } 1479 } 1480 if (pCurScb->SCB_Flags & SCF_POLL) { 1481 while (wait_tulip(pCurHcb) != -1) { 1482 if (tul_next_state(pCurHcb) == -1) 1483 break; 1484 } 1485 } 1486 } else if (pCurScb->SCB_Opcode == BusDevRst) { 1487 tul_select_atn_stop(pCurHcb, pCurScb); 1488 pCurScb->SCB_NxtStat = 8; 1489 if (pCurScb->SCB_Flags & SCF_POLL) { 1490 while (wait_tulip(pCurHcb) != -1) { 1491 if (tul_next_state(pCurHcb) == -1) 1492 break; 1493 } 1494 } 1495 } else if (pCurScb->SCB_Opcode == AbortCmd) { 1496 if (tul_abort_srb(pCurHcb, pCurScb->SCB_Srb) != 0) { 1497 1498 1499 tul_unlink_pend_scb(pCurHcb, pCurScb); 1500 1501 tul_release_scb(pCurHcb, pCurScb); 1502 } else { 1503 pCurScb->SCB_Opcode = BusDevRst; 1504 tul_select_atn_stop(pCurHcb, pCurScb); 1505 pCurScb->SCB_NxtStat = 8; 1506 } 1507 1508 /* 08/03/98 */ 1509 } else { 1510 tul_unlink_pend_scb(pCurHcb, pCurScb); 1511 pCurScb->SCB_HaStat = 0x16; /* bad command */ 1512 tul_append_done_scb(pCurHcb, pCurScb); 1513 } 1514 return; 1515 } 1516 1517 1518 /***************************************************************************/ 1519 int tul_next_state(HCS * pCurHcb) 1520 { 1521 int next; 1522 1523 next = pCurHcb->HCS_ActScb->SCB_NxtStat; 1524 for (;;) { 1525 switch (next) { 1526 case 1: 1527 next = tul_state_1(pCurHcb); 1528 break; 1529 case 2: 1530 next = tul_state_2(pCurHcb); 1531 break; 1532 case 3: 1533 next = tul_state_3(pCurHcb); 1534 break; 1535 case 4: 1536 next = tul_state_4(pCurHcb); 1537 break; 1538 case 5: 1539 next = tul_state_5(pCurHcb); 1540 break; 1541 case 6: 1542 next = tul_state_6(pCurHcb); 1543 break; 1544 case 7: 1545 next = tul_state_7(pCurHcb); 1546 break; 1547 case 8: 1548 return (tul_bus_device_reset(pCurHcb)); 1549 default: 1550 return (tul_bad_seq(pCurHcb)); 1551 } 1552 if (next <= 0) 1553 return next; 1554 } 1555 } 1556 1557 1558 /***************************************************************************/ 1559 /* sTate after selection with attention & stop */ 1560 int tul_state_1(HCS * pCurHcb) 1561 { 1562 SCB *pCurScb = pCurHcb->HCS_ActScb; 1563 TCS *pCurTcb = pCurHcb->HCS_ActTcs; 1564 #if DEBUG_STATE 1565 printk("-s1-"); 1566 #endif 1567 1568 tul_unlink_pend_scb(pCurHcb, pCurScb); 1569 tul_append_busy_scb(pCurHcb, pCurScb); 1570 1571 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0); 1572 /* ATN on */ 1573 if (pCurHcb->HCS_Phase == MSG_OUT) { 1574 1575 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, (TSC_EN_BUS_IN | TSC_HW_RESELECT)); 1576 1577 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident); 1578 1579 if (pCurScb->SCB_TagMsg) { 1580 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagMsg); 1581 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagId); 1582 } 1583 if ((pCurTcb->TCS_Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) { 1584 1585 pCurTcb->TCS_Flags |= TCF_WDTR_DONE; 1586 1587 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND); 1588 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 2); /* Extended msg length */ 1589 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); /* Sync request */ 1590 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1); /* Start from 16 bits */ 1591 } else if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) { 1592 1593 pCurTcb->TCS_Flags |= TCF_SYNC_DONE; 1594 1595 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND); 1596 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); /* extended msg length */ 1597 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1); /* sync request */ 1598 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, tul_rate_tbl[pCurTcb->TCS_Flags & TCF_SCSI_RATE]); 1599 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MAX_OFFSET); /* REQ/ACK offset */ 1600 } 1601 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1602 if (wait_tulip(pCurHcb) == -1) 1603 return (-1); 1604 } 1605 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 1606 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7))); 1607 return (3); 1608 } 1609 1610 1611 /***************************************************************************/ 1612 /* state after selection with attention */ 1613 /* state after selection with attention3 */ 1614 int tul_state_2(HCS * pCurHcb) 1615 { 1616 SCB *pCurScb = pCurHcb->HCS_ActScb; 1617 TCS *pCurTcb = pCurHcb->HCS_ActTcs; 1618 #if DEBUG_STATE 1619 printk("-s2-"); 1620 #endif 1621 1622 tul_unlink_pend_scb(pCurHcb, pCurScb); 1623 tul_append_busy_scb(pCurHcb, pCurScb); 1624 1625 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0); 1626 1627 if (pCurHcb->HCS_JSStatus1 & TSS_CMD_PH_CMP) { 1628 return (4); 1629 } 1630 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 1631 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7))); 1632 return (3); 1633 } 1634 1635 /***************************************************************************/ 1636 /* state before CDB xfer is done */ 1637 int tul_state_3(HCS * pCurHcb) 1638 { 1639 SCB *pCurScb = pCurHcb->HCS_ActScb; 1640 TCS *pCurTcb = pCurHcb->HCS_ActTcs; 1641 int i; 1642 1643 #if DEBUG_STATE 1644 printk("-s3-"); 1645 #endif 1646 for (;;) { 1647 switch (pCurHcb->HCS_Phase) { 1648 case CMD_OUT: /* Command out phase */ 1649 for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++) 1650 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]); 1651 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1652 if (wait_tulip(pCurHcb) == -1) 1653 return (-1); 1654 if (pCurHcb->HCS_Phase == CMD_OUT) { 1655 return (tul_bad_seq(pCurHcb)); 1656 } 1657 return (4); 1658 1659 case MSG_IN: /* Message in phase */ 1660 pCurScb->SCB_NxtStat = 3; 1661 if (tul_msgin(pCurHcb) == -1) 1662 return (-1); 1663 break; 1664 1665 case STATUS_IN: /* Status phase */ 1666 if (tul_status_msg(pCurHcb) == -1) 1667 return (-1); 1668 break; 1669 1670 case MSG_OUT: /* Message out phase */ 1671 if (pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) { 1672 1673 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP); /* msg nop */ 1674 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1675 if (wait_tulip(pCurHcb) == -1) 1676 return (-1); 1677 1678 } else { 1679 pCurTcb->TCS_Flags |= TCF_SYNC_DONE; 1680 1681 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND); 1682 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); /* ext. msg len */ 1683 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1); /* sync request */ 1684 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, tul_rate_tbl[pCurTcb->TCS_Flags & TCF_SCSI_RATE]); 1685 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MAX_OFFSET); /* REQ/ACK offset */ 1686 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1687 if (wait_tulip(pCurHcb) == -1) 1688 return (-1); 1689 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 1690 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)); 1691 1692 } 1693 break; 1694 1695 default: 1696 return (tul_bad_seq(pCurHcb)); 1697 } 1698 } 1699 } 1700 1701 1702 /***************************************************************************/ 1703 int tul_state_4(HCS * pCurHcb) 1704 { 1705 SCB *pCurScb = pCurHcb->HCS_ActScb; 1706 1707 #if DEBUG_STATE 1708 printk("-s4-"); 1709 #endif 1710 if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_NO_XF) { 1711 return (6); /* Go to state 6 */ 1712 } 1713 for (;;) { 1714 if (pCurScb->SCB_BufLen == 0) 1715 return (6); /* Go to state 6 */ 1716 1717 switch (pCurHcb->HCS_Phase) { 1718 1719 case STATUS_IN: /* Status phase */ 1720 if ((pCurScb->SCB_Flags & SCF_DIR) != 0) { /* if direction bit set then report data underrun */ 1721 pCurScb->SCB_HaStat = HOST_DO_DU; 1722 } 1723 if ((tul_status_msg(pCurHcb)) == -1) 1724 return (-1); 1725 break; 1726 1727 case MSG_IN: /* Message in phase */ 1728 pCurScb->SCB_NxtStat = 0x4; 1729 if (tul_msgin(pCurHcb) == -1) 1730 return (-1); 1731 break; 1732 1733 case MSG_OUT: /* Message out phase */ 1734 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) { 1735 pCurScb->SCB_BufLen = 0; 1736 pCurScb->SCB_HaStat = HOST_DO_DU; 1737 if (tul_msgout_ide(pCurHcb) == -1) 1738 return (-1); 1739 return (6); /* Go to state 6 */ 1740 } else { 1741 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP); /* msg nop */ 1742 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1743 if (wait_tulip(pCurHcb) == -1) 1744 return (-1); 1745 } 1746 break; 1747 1748 case DATA_IN: /* Data in phase */ 1749 return (tul_xfer_data_in(pCurHcb)); 1750 1751 case DATA_OUT: /* Data out phase */ 1752 return (tul_xfer_data_out(pCurHcb)); 1753 1754 default: 1755 return (tul_bad_seq(pCurHcb)); 1756 } 1757 } 1758 } 1759 1760 1761 /***************************************************************************/ 1762 /* state after dma xfer done or phase change before xfer done */ 1763 int tul_state_5(HCS * pCurHcb) 1764 { 1765 SCB *pCurScb = pCurHcb->HCS_ActScb; 1766 long cnt, xcnt; /* cannot use unsigned !! code: if (xcnt < 0) */ 1767 1768 #if DEBUG_STATE 1769 printk("-s5-"); 1770 #endif 1771 /*------ get remaining count -------*/ 1772 1773 cnt = TUL_RDLONG(pCurHcb->HCS_Base, TUL_SCnt0) & 0x0FFFFFF; 1774 1775 if (TUL_RD(pCurHcb->HCS_Base, TUL_XCmd) & 0x20) { 1776 /* ----------------------- DATA_IN ----------------------------- */ 1777 /* check scsi parity error */ 1778 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) { 1779 pCurScb->SCB_HaStat = HOST_DO_DU; 1780 } 1781 if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) { /* DMA xfer pending, Send STOP */ 1782 /* tell Hardware scsi xfer has been terminated */ 1783 TUL_WR(pCurHcb->HCS_Base + TUL_XCtrl, TUL_RD(pCurHcb->HCS_Base, TUL_XCtrl) | 0x80); 1784 /* wait until DMA xfer not pending */ 1785 while (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND); 1786 } 1787 } else { 1788 /*-------- DATA OUT -----------*/ 1789 if ((TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1) & TSS_XFER_CMP) == 0) { 1790 if (pCurHcb->HCS_ActTcs->TCS_JS_Period & TSC_WIDE_SCSI) 1791 cnt += (TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F) << 1; 1792 else 1793 cnt += (TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F); 1794 } 1795 if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) { /* if DMA xfer is pending, abort DMA xfer */ 1796 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT); 1797 /* wait Abort DMA xfer done */ 1798 while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & XABT) == 0); 1799 } 1800 if ((cnt == 1) && (pCurHcb->HCS_Phase == DATA_OUT)) { 1801 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1802 if (wait_tulip(pCurHcb) == -1) { 1803 return (-1); 1804 } 1805 cnt = 0; 1806 } else { 1807 if ((TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1) & TSS_XFER_CMP) == 0) 1808 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 1809 } 1810 } 1811 1812 if (cnt == 0) { 1813 pCurScb->SCB_BufLen = 0; 1814 return (6); /* Go to state 6 */ 1815 } 1816 /* Update active data pointer */ 1817 xcnt = (long) pCurScb->SCB_BufLen - cnt; /* xcnt== bytes already xferred */ 1818 pCurScb->SCB_BufLen = (U32) cnt; /* cnt == bytes left to be xferred */ 1819 if (pCurScb->SCB_Flags & SCF_SG) { 1820 register SG *sgp; 1821 ULONG i; 1822 1823 sgp = &pCurScb->SCB_SGList[pCurScb->SCB_SGIdx]; 1824 for (i = pCurScb->SCB_SGIdx; i < pCurScb->SCB_SGMax; sgp++, i++) { 1825 xcnt -= (long) sgp->SG_Len; 1826 if (xcnt < 0) { /* this sgp xfer half done */ 1827 xcnt += (long) sgp->SG_Len; /* xcnt == bytes xferred in this sgp */ 1828 sgp->SG_Ptr += (U32) xcnt; /* new ptr to be xfer */ 1829 sgp->SG_Len -= (U32) xcnt; /* new len to be xfer */ 1830 pCurScb->SCB_BufPtr += ((U32) (i - pCurScb->SCB_SGIdx) << 3); 1831 /* new SG table ptr */ 1832 pCurScb->SCB_SGLen = (BYTE) (pCurScb->SCB_SGMax - i); 1833 /* new SG table len */ 1834 pCurScb->SCB_SGIdx = (WORD) i; 1835 /* for next disc and come in this loop */ 1836 return (4); /* Go to state 4 */ 1837 } 1838 /* else (xcnt >= 0 , i.e. this sgp already xferred */ 1839 } /* for */ 1840 return (6); /* Go to state 6 */ 1841 } else { 1842 pCurScb->SCB_BufPtr += (U32) xcnt; 1843 } 1844 return (4); /* Go to state 4 */ 1845 } 1846 1847 /***************************************************************************/ 1848 /* state after Data phase */ 1849 int tul_state_6(HCS * pCurHcb) 1850 { 1851 SCB *pCurScb = pCurHcb->HCS_ActScb; 1852 1853 #if DEBUG_STATE 1854 printk("-s6-"); 1855 #endif 1856 for (;;) { 1857 switch (pCurHcb->HCS_Phase) { 1858 case STATUS_IN: /* Status phase */ 1859 if ((tul_status_msg(pCurHcb)) == -1) 1860 return (-1); 1861 break; 1862 1863 case MSG_IN: /* Message in phase */ 1864 pCurScb->SCB_NxtStat = 6; 1865 if ((tul_msgin(pCurHcb)) == -1) 1866 return (-1); 1867 break; 1868 1869 case MSG_OUT: /* Message out phase */ 1870 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP); /* msg nop */ 1871 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1872 if (wait_tulip(pCurHcb) == -1) 1873 return (-1); 1874 break; 1875 1876 case DATA_IN: /* Data in phase */ 1877 return (tul_xpad_in(pCurHcb)); 1878 1879 case DATA_OUT: /* Data out phase */ 1880 return (tul_xpad_out(pCurHcb)); 1881 1882 default: 1883 return (tul_bad_seq(pCurHcb)); 1884 } 1885 } 1886 } 1887 1888 /***************************************************************************/ 1889 int tul_state_7(HCS * pCurHcb) 1890 { 1891 int cnt, i; 1892 1893 #if DEBUG_STATE 1894 printk("-s7-"); 1895 #endif 1896 /* flush SCSI FIFO */ 1897 cnt = TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F; 1898 if (cnt) { 1899 for (i = 0; i < cnt; i++) 1900 TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); 1901 } 1902 switch (pCurHcb->HCS_Phase) { 1903 case DATA_IN: /* Data in phase */ 1904 case DATA_OUT: /* Data out phase */ 1905 return (tul_bad_seq(pCurHcb)); 1906 default: 1907 return (6); /* Go to state 6 */ 1908 } 1909 } 1910 1911 /***************************************************************************/ 1912 int tul_xfer_data_in(HCS * pCurHcb) 1913 { 1914 SCB *pCurScb = pCurHcb->HCS_ActScb; 1915 1916 if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_DOUT) { 1917 return (6); /* wrong direction */ 1918 } 1919 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, pCurScb->SCB_BufLen); 1920 1921 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_DMA_IN); /* 7/25/95 */ 1922 1923 if (pCurScb->SCB_Flags & SCF_SG) { /* S/G xfer */ 1924 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, ((ULONG) pCurScb->SCB_SGLen) << 3); 1925 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr); 1926 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_SG_IN); 1927 } else { 1928 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, pCurScb->SCB_BufLen); 1929 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr); 1930 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_IN); 1931 } 1932 pCurScb->SCB_NxtStat = 0x5; 1933 return (0); /* return to OS, wait xfer done , let jas_isr come in */ 1934 } 1935 1936 1937 /***************************************************************************/ 1938 int tul_xfer_data_out(HCS * pCurHcb) 1939 { 1940 SCB *pCurScb = pCurHcb->HCS_ActScb; 1941 1942 if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_DIN) { 1943 return (6); /* wrong direction */ 1944 } 1945 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, pCurScb->SCB_BufLen); 1946 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_DMA_OUT); 1947 1948 if (pCurScb->SCB_Flags & SCF_SG) { /* S/G xfer */ 1949 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, ((ULONG) pCurScb->SCB_SGLen) << 3); 1950 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr); 1951 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_SG_OUT); 1952 } else { 1953 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, pCurScb->SCB_BufLen); 1954 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr); 1955 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_OUT); 1956 } 1957 1958 pCurScb->SCB_NxtStat = 0x5; 1959 return (0); /* return to OS, wait xfer done , let jas_isr come in */ 1960 } 1961 1962 1963 /***************************************************************************/ 1964 int tul_xpad_in(HCS * pCurHcb) 1965 { 1966 SCB *pCurScb = pCurHcb->HCS_ActScb; 1967 TCS *pCurTcb = pCurHcb->HCS_ActTcs; 1968 1969 if ((pCurScb->SCB_Flags & SCF_DIR) != SCF_NO_DCHK) { 1970 pCurScb->SCB_HaStat = HOST_DO_DU; /* over run */ 1971 } 1972 for (;;) { 1973 if (pCurTcb->TCS_JS_Period & TSC_WIDE_SCSI) 1974 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 2); 1975 else 1976 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 1977 1978 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 1979 if ((wait_tulip(pCurHcb)) == -1) { 1980 return (-1); 1981 } 1982 if (pCurHcb->HCS_Phase != DATA_IN) { 1983 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 1984 return (6); 1985 } 1986 TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); 1987 } 1988 } 1989 1990 int tul_xpad_out(HCS * pCurHcb) 1991 { 1992 SCB *pCurScb = pCurHcb->HCS_ActScb; 1993 TCS *pCurTcb = pCurHcb->HCS_ActTcs; 1994 1995 if ((pCurScb->SCB_Flags & SCF_DIR) != SCF_NO_DCHK) { 1996 pCurScb->SCB_HaStat = HOST_DO_DU; /* over run */ 1997 } 1998 for (;;) { 1999 if (pCurTcb->TCS_JS_Period & TSC_WIDE_SCSI) 2000 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 2); 2001 else 2002 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 2003 2004 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 0); 2005 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2006 if ((wait_tulip(pCurHcb)) == -1) { 2007 return (-1); 2008 } 2009 if (pCurHcb->HCS_Phase != DATA_OUT) { /* Disable wide CPU to allow read 16 bits */ 2010 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); 2011 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 2012 return (6); 2013 } 2014 } 2015 } 2016 2017 2018 /***************************************************************************/ 2019 int tul_status_msg(HCS * pCurHcb) 2020 { /* status & MSG_IN */ 2021 SCB *pCurScb = pCurHcb->HCS_ActScb; 2022 BYTE msg; 2023 2024 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_CMD_COMP); 2025 if ((wait_tulip(pCurHcb)) == -1) { 2026 return (-1); 2027 } 2028 /* get status */ 2029 pCurScb->SCB_TaStat = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); 2030 2031 if (pCurHcb->HCS_Phase == MSG_OUT) { 2032 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) { 2033 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_PARITY); 2034 } else { 2035 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP); 2036 } 2037 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2038 return (wait_tulip(pCurHcb)); 2039 } 2040 if (pCurHcb->HCS_Phase == MSG_IN) { 2041 msg = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); 2042 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) { /* Parity error */ 2043 if ((tul_msgin_accept(pCurHcb)) == -1) 2044 return (-1); 2045 if (pCurHcb->HCS_Phase != MSG_OUT) 2046 return (tul_bad_seq(pCurHcb)); 2047 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_PARITY); 2048 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2049 return (wait_tulip(pCurHcb)); 2050 } 2051 if (msg == 0) { /* Command complete */ 2052 2053 if ((pCurScb->SCB_TaStat & 0x18) == 0x10) { /* No link support */ 2054 return (tul_bad_seq(pCurHcb)); 2055 } 2056 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 2057 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT); 2058 return tul_wait_done_disc(pCurHcb); 2059 2060 } 2061 if ((msg == MSG_LINK_COMP) || (msg == MSG_LINK_FLAG)) { 2062 if ((pCurScb->SCB_TaStat & 0x18) == 0x10) 2063 return (tul_msgin_accept(pCurHcb)); 2064 } 2065 } 2066 return (tul_bad_seq(pCurHcb)); 2067 } 2068 2069 2070 /***************************************************************************/ 2071 /* scsi bus free */ 2072 int int_tul_busfree(HCS * pCurHcb) 2073 { 2074 SCB *pCurScb = pCurHcb->HCS_ActScb; 2075 2076 if (pCurScb != NULL) { 2077 if (pCurScb->SCB_Status & SCB_SELECT) { /* selection timeout */ 2078 tul_unlink_pend_scb(pCurHcb, pCurScb); 2079 pCurScb->SCB_HaStat = HOST_SEL_TOUT; 2080 tul_append_done_scb(pCurHcb, pCurScb); 2081 } else { /* Unexpected bus free */ 2082 tul_unlink_busy_scb(pCurHcb, pCurScb); 2083 pCurScb->SCB_HaStat = HOST_BUS_FREE; 2084 tul_append_done_scb(pCurHcb, pCurScb); 2085 } 2086 pCurHcb->HCS_ActScb = NULL; 2087 pCurHcb->HCS_ActTcs = NULL; 2088 } 2089 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */ 2090 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT); 2091 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */ 2092 return (-1); 2093 } 2094 2095 2096 /***************************************************************************/ 2097 /* scsi bus reset */ 2098 static int int_tul_scsi_rst(HCS * pCurHcb) 2099 { 2100 SCB *pCurScb; 2101 int i; 2102 2103 /* if DMA xfer is pending, abort DMA xfer */ 2104 if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & 0x01) { 2105 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT | TAX_X_CLR_FIFO); 2106 /* wait Abort DMA xfer done */ 2107 while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & 0x04) == 0); 2108 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 2109 } 2110 /* Abort all active & disconnected scb */ 2111 while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) { 2112 pCurScb->SCB_HaStat = HOST_BAD_PHAS; 2113 tul_append_done_scb(pCurHcb, pCurScb); 2114 } 2115 pCurHcb->HCS_ActScb = NULL; 2116 pCurHcb->HCS_ActTcs = NULL; 2117 2118 /* clr sync nego. done flag */ 2119 for (i = 0; i < pCurHcb->HCS_MaxTar; i++) { 2120 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE); 2121 } 2122 return (-1); 2123 } 2124 2125 2126 /***************************************************************************/ 2127 /* scsi reselection */ 2128 int int_tul_resel(HCS * pCurHcb) 2129 { 2130 SCB *pCurScb; 2131 TCS *pCurTcb; 2132 BYTE tag, msg = 0; 2133 BYTE tar, lun; 2134 2135 if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) { 2136 if (pCurScb->SCB_Status & SCB_SELECT) { /* if waiting for selection complete */ 2137 pCurScb->SCB_Status &= ~SCB_SELECT; 2138 } 2139 pCurHcb->HCS_ActScb = NULL; 2140 } 2141 /* --------- get target id---------------------- */ 2142 tar = TUL_RD(pCurHcb->HCS_Base, TUL_SBusId); 2143 /* ------ get LUN from Identify message----------- */ 2144 lun = TUL_RD(pCurHcb->HCS_Base, TUL_SIdent) & 0x0F; 2145 /* 07/22/98 from 0x1F -> 0x0F */ 2146 pCurTcb = &pCurHcb->HCS_Tcs[tar]; 2147 pCurHcb->HCS_ActTcs = pCurTcb; 2148 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0); 2149 TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurTcb->TCS_JS_Period); 2150 2151 2152 /* ------------- tag queueing ? ------------------- */ 2153 if (pCurTcb->TCS_DrvFlags & TCF_DRV_EN_TAG) { 2154 if ((tul_msgin_accept(pCurHcb)) == -1) 2155 return (-1); 2156 if (pCurHcb->HCS_Phase != MSG_IN) 2157 goto no_tag; 2158 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 2159 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 2160 if ((wait_tulip(pCurHcb)) == -1) 2161 return (-1); 2162 msg = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); /* Read Tag Message */ 2163 2164 if ((msg < MSG_STAG) || (msg > MSG_OTAG)) /* Is simple Tag */ 2165 goto no_tag; 2166 2167 if ((tul_msgin_accept(pCurHcb)) == -1) 2168 return (-1); 2169 2170 if (pCurHcb->HCS_Phase != MSG_IN) 2171 goto no_tag; 2172 2173 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 2174 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 2175 if ((wait_tulip(pCurHcb)) == -1) 2176 return (-1); 2177 tag = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); /* Read Tag ID */ 2178 pCurScb = pCurHcb->HCS_Scb + tag; 2179 if ((pCurScb->SCB_Target != tar) || (pCurScb->SCB_Lun != lun)) { 2180 return tul_msgout_abort_tag(pCurHcb); 2181 } 2182 if (pCurScb->SCB_Status != SCB_BUSY) { /* 03/24/95 */ 2183 return tul_msgout_abort_tag(pCurHcb); 2184 } 2185 pCurHcb->HCS_ActScb = pCurScb; 2186 if ((tul_msgin_accept(pCurHcb)) == -1) 2187 return (-1); 2188 } else { /* No tag */ 2189 no_tag: 2190 if ((pCurScb = tul_find_busy_scb(pCurHcb, tar | (lun << 8))) == NULL) { 2191 return tul_msgout_abort_targ(pCurHcb); 2192 } 2193 pCurHcb->HCS_ActScb = pCurScb; 2194 if (!(pCurTcb->TCS_DrvFlags & TCF_DRV_EN_TAG)) { 2195 if ((tul_msgin_accept(pCurHcb)) == -1) 2196 return (-1); 2197 } 2198 } 2199 return 0; 2200 } 2201 2202 2203 /***************************************************************************/ 2204 static int int_tul_bad_seq(HCS * pCurHcb) 2205 { /* target wrong phase */ 2206 SCB *pCurScb; 2207 int i; 2208 2209 tul_reset_scsi(pCurHcb, 10); 2210 2211 while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) { 2212 pCurScb->SCB_HaStat = HOST_BAD_PHAS; 2213 tul_append_done_scb(pCurHcb, pCurScb); 2214 } 2215 for (i = 0; i < pCurHcb->HCS_MaxTar; i++) { 2216 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE); 2217 } 2218 return (-1); 2219 } 2220 2221 2222 /***************************************************************************/ 2223 int tul_msgout_abort_targ(HCS * pCurHcb) 2224 { 2225 2226 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2227 if (tul_msgin_accept(pCurHcb) == -1) 2228 return (-1); 2229 if (pCurHcb->HCS_Phase != MSG_OUT) 2230 return (tul_bad_seq(pCurHcb)); 2231 2232 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_ABORT); 2233 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2234 2235 return tul_wait_disc(pCurHcb); 2236 } 2237 2238 /***************************************************************************/ 2239 int tul_msgout_abort_tag(HCS * pCurHcb) 2240 { 2241 2242 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2243 if (tul_msgin_accept(pCurHcb) == -1) 2244 return (-1); 2245 if (pCurHcb->HCS_Phase != MSG_OUT) 2246 return (tul_bad_seq(pCurHcb)); 2247 2248 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_ABORT_TAG); 2249 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2250 2251 return tul_wait_disc(pCurHcb); 2252 2253 } 2254 2255 /***************************************************************************/ 2256 int tul_msgin(HCS * pCurHcb) 2257 { 2258 TCS *pCurTcb; 2259 2260 for (;;) { 2261 2262 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 2263 2264 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 2265 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 2266 if ((wait_tulip(pCurHcb)) == -1) 2267 return (-1); 2268 2269 switch (TUL_RD(pCurHcb->HCS_Base, TUL_SFifo)) { 2270 case MSG_DISC: /* Disconnect msg */ 2271 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT); 2272 2273 return tul_wait_disc(pCurHcb); 2274 2275 case MSG_SDP: 2276 case MSG_RESTORE: 2277 case MSG_NOP: 2278 tul_msgin_accept(pCurHcb); 2279 break; 2280 2281 case MSG_REJ: /* Clear ATN first */ 2282 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, 2283 (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7))); 2284 pCurTcb = pCurHcb->HCS_ActTcs; 2285 if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) { /* do sync nego */ 2286 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2287 } 2288 tul_msgin_accept(pCurHcb); 2289 break; 2290 2291 case MSG_EXTEND: /* extended msg */ 2292 tul_msgin_extend(pCurHcb); 2293 break; 2294 2295 case MSG_IGNOREWIDE: 2296 tul_msgin_accept(pCurHcb); 2297 break; 2298 2299 /* get */ 2300 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 2301 if (wait_tulip(pCurHcb) == -1) 2302 return -1; 2303 2304 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 0); /* put pad */ 2305 TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); /* get IGNORE field */ 2306 TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); /* get pad */ 2307 2308 tul_msgin_accept(pCurHcb); 2309 break; 2310 2311 case MSG_COMP: 2312 { 2313 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 2314 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT); 2315 return tul_wait_done_disc(pCurHcb); 2316 } 2317 default: 2318 tul_msgout_reject(pCurHcb); 2319 break; 2320 } 2321 if (pCurHcb->HCS_Phase != MSG_IN) 2322 return (pCurHcb->HCS_Phase); 2323 } 2324 /* statement won't reach here */ 2325 } 2326 2327 2328 2329 2330 /***************************************************************************/ 2331 int tul_msgout_reject(HCS * pCurHcb) 2332 { 2333 2334 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2335 2336 if ((tul_msgin_accept(pCurHcb)) == -1) 2337 return (-1); 2338 2339 if (pCurHcb->HCS_Phase == MSG_OUT) { 2340 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_REJ); /* Msg reject */ 2341 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2342 return (wait_tulip(pCurHcb)); 2343 } 2344 return (pCurHcb->HCS_Phase); 2345 } 2346 2347 2348 2349 /***************************************************************************/ 2350 int tul_msgout_ide(HCS * pCurHcb) 2351 { 2352 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_IDE); /* Initiator Detected Error */ 2353 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2354 return (wait_tulip(pCurHcb)); 2355 } 2356 2357 2358 /***************************************************************************/ 2359 int tul_msgin_extend(HCS * pCurHcb) 2360 { 2361 BYTE len, idx; 2362 2363 if (tul_msgin_accept(pCurHcb) != MSG_IN) 2364 return (pCurHcb->HCS_Phase); 2365 2366 /* Get extended msg length */ 2367 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 2368 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 2369 if (wait_tulip(pCurHcb) == -1) 2370 return (-1); 2371 2372 len = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); 2373 pCurHcb->HCS_Msg[0] = len; 2374 for (idx = 1; len != 0; len--) { 2375 2376 if ((tul_msgin_accept(pCurHcb)) != MSG_IN) 2377 return (pCurHcb->HCS_Phase); 2378 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 2379 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 2380 if (wait_tulip(pCurHcb) == -1) 2381 return (-1); 2382 pCurHcb->HCS_Msg[idx++] = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); 2383 } 2384 if (pCurHcb->HCS_Msg[1] == 1) { /* if it's synchronous data transfer request */ 2385 if (pCurHcb->HCS_Msg[0] != 3) /* if length is not right */ 2386 return (tul_msgout_reject(pCurHcb)); 2387 if (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_SYNC_NEGO) { /* Set OFFSET=0 to do async, nego back */ 2388 pCurHcb->HCS_Msg[3] = 0; 2389 } else { 2390 if ((tul_msgin_sync(pCurHcb) == 0) && 2391 (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_SYNC_DONE)) { 2392 tul_sync_done(pCurHcb); 2393 return (tul_msgin_accept(pCurHcb)); 2394 } 2395 } 2396 2397 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2398 if ((tul_msgin_accept(pCurHcb)) != MSG_OUT) 2399 return (pCurHcb->HCS_Phase); 2400 /* sync msg out */ 2401 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 2402 2403 tul_sync_done(pCurHcb); 2404 2405 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND); 2406 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); 2407 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1); 2408 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[2]); 2409 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[3]); 2410 2411 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2412 return (wait_tulip(pCurHcb)); 2413 } 2414 if ((pCurHcb->HCS_Msg[0] != 2) || (pCurHcb->HCS_Msg[1] != 3)) 2415 return (tul_msgout_reject(pCurHcb)); 2416 /* if it's WIDE DATA XFER REQ */ 2417 if (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_WDTR) { 2418 pCurHcb->HCS_Msg[2] = 0; 2419 } else { 2420 if (pCurHcb->HCS_Msg[2] > 2) /* > 32 bits */ 2421 return (tul_msgout_reject(pCurHcb)); 2422 if (pCurHcb->HCS_Msg[2] == 2) { /* == 32 */ 2423 pCurHcb->HCS_Msg[2] = 1; 2424 } else { 2425 if ((pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_WDTR) == 0) { 2426 wdtr_done(pCurHcb); 2427 if ((pCurHcb->HCS_ActTcs->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) 2428 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2429 return (tul_msgin_accept(pCurHcb)); 2430 } 2431 } 2432 } 2433 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2434 2435 if (tul_msgin_accept(pCurHcb) != MSG_OUT) 2436 return (pCurHcb->HCS_Phase); 2437 /* WDTR msg out */ 2438 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND); 2439 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 2); 2440 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); 2441 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[2]); 2442 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2443 return (wait_tulip(pCurHcb)); 2444 } 2445 2446 /***************************************************************************/ 2447 int tul_msgin_sync(HCS * pCurHcb) 2448 { 2449 char default_period; 2450 2451 default_period = tul_rate_tbl[pCurHcb->HCS_ActTcs->TCS_Flags & TCF_SCSI_RATE]; 2452 if (pCurHcb->HCS_Msg[3] > MAX_OFFSET) { 2453 pCurHcb->HCS_Msg[3] = MAX_OFFSET; 2454 if (pCurHcb->HCS_Msg[2] < default_period) { 2455 pCurHcb->HCS_Msg[2] = default_period; 2456 return 1; 2457 } 2458 if (pCurHcb->HCS_Msg[2] >= 59) { /* Change to async */ 2459 pCurHcb->HCS_Msg[3] = 0; 2460 } 2461 return 1; 2462 } 2463 /* offset requests asynchronous transfers ? */ 2464 if (pCurHcb->HCS_Msg[3] == 0) { 2465 return 0; 2466 } 2467 if (pCurHcb->HCS_Msg[2] < default_period) { 2468 pCurHcb->HCS_Msg[2] = default_period; 2469 return 1; 2470 } 2471 if (pCurHcb->HCS_Msg[2] >= 59) { 2472 pCurHcb->HCS_Msg[3] = 0; 2473 return 1; 2474 } 2475 return 0; 2476 } 2477 2478 2479 /***************************************************************************/ 2480 int wdtr_done(HCS * pCurHcb) 2481 { 2482 pCurHcb->HCS_ActTcs->TCS_Flags &= ~TCF_SYNC_DONE; 2483 pCurHcb->HCS_ActTcs->TCS_Flags |= TCF_WDTR_DONE; 2484 2485 pCurHcb->HCS_ActTcs->TCS_JS_Period = 0; 2486 if (pCurHcb->HCS_Msg[2]) { /* if 16 bit */ 2487 pCurHcb->HCS_ActTcs->TCS_JS_Period |= TSC_WIDE_SCSI; 2488 } 2489 pCurHcb->HCS_ActTcs->TCS_SConfig0 &= ~TSC_ALT_PERIOD; 2490 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_ActTcs->TCS_SConfig0); 2491 TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurHcb->HCS_ActTcs->TCS_JS_Period); 2492 2493 return 1; 2494 } 2495 2496 /***************************************************************************/ 2497 int tul_sync_done(HCS * pCurHcb) 2498 { 2499 int i; 2500 2501 pCurHcb->HCS_ActTcs->TCS_Flags |= TCF_SYNC_DONE; 2502 2503 if (pCurHcb->HCS_Msg[3]) { 2504 pCurHcb->HCS_ActTcs->TCS_JS_Period |= pCurHcb->HCS_Msg[3]; 2505 for (i = 0; i < 8; i++) { 2506 if (tul_rate_tbl[i] >= pCurHcb->HCS_Msg[2]) /* pick the big one */ 2507 break; 2508 } 2509 pCurHcb->HCS_ActTcs->TCS_JS_Period |= (i << 4); 2510 pCurHcb->HCS_ActTcs->TCS_SConfig0 |= TSC_ALT_PERIOD; 2511 } 2512 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_ActTcs->TCS_SConfig0); 2513 TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurHcb->HCS_ActTcs->TCS_JS_Period); 2514 2515 return (-1); 2516 } 2517 2518 2519 int tul_post_scsi_rst(HCS * pCurHcb) 2520 { 2521 SCB *pCurScb; 2522 TCS *pCurTcb; 2523 int i; 2524 2525 pCurHcb->HCS_ActScb = NULL; 2526 pCurHcb->HCS_ActTcs = NULL; 2527 pCurHcb->HCS_Flags = 0; 2528 2529 while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) { 2530 pCurScb->SCB_HaStat = HOST_BAD_PHAS; 2531 tul_append_done_scb(pCurHcb, pCurScb); 2532 } 2533 /* clear sync done flag */ 2534 pCurTcb = &pCurHcb->HCS_Tcs[0]; 2535 for (i = 0; i < pCurHcb->HCS_MaxTar; pCurTcb++, i++) { 2536 pCurTcb->TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE); 2537 /* Initialize the sync. xfer register values to an asyn xfer */ 2538 pCurTcb->TCS_JS_Period = 0; 2539 pCurTcb->TCS_SConfig0 = pCurHcb->HCS_SConf1; 2540 pCurHcb->HCS_ActTags[0] = 0; /* 07/22/98 */ 2541 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~TCF_BUSY; /* 07/22/98 */ 2542 } /* for */ 2543 2544 return (-1); 2545 } 2546 2547 /***************************************************************************/ 2548 void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb) 2549 { 2550 pCurScb->SCB_Status |= SCB_SELECT; 2551 pCurScb->SCB_NxtStat = 0x1; 2552 pCurHcb->HCS_ActScb = pCurScb; 2553 pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target]; 2554 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SELATNSTOP); 2555 return; 2556 } 2557 2558 2559 /***************************************************************************/ 2560 void tul_select_atn(HCS * pCurHcb, SCB * pCurScb) 2561 { 2562 int i; 2563 2564 pCurScb->SCB_Status |= SCB_SELECT; 2565 pCurScb->SCB_NxtStat = 0x2; 2566 2567 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident); 2568 for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++) 2569 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]); 2570 pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target]; 2571 pCurHcb->HCS_ActScb = pCurScb; 2572 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SEL_ATN); 2573 return; 2574 } 2575 2576 /***************************************************************************/ 2577 void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb) 2578 { 2579 int i; 2580 2581 pCurScb->SCB_Status |= SCB_SELECT; 2582 pCurScb->SCB_NxtStat = 0x2; 2583 2584 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident); 2585 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagMsg); 2586 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagId); 2587 for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++) 2588 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]); 2589 pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target]; 2590 pCurHcb->HCS_ActScb = pCurScb; 2591 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SEL_ATN3); 2592 return; 2593 } 2594 2595 /***************************************************************************/ 2596 /* SCSI Bus Device Reset */ 2597 int tul_bus_device_reset(HCS * pCurHcb) 2598 { 2599 SCB *pCurScb = pCurHcb->HCS_ActScb; 2600 TCS *pCurTcb = pCurHcb->HCS_ActTcs; 2601 SCB *pTmpScb, *pPrevScb; 2602 BYTE tar; 2603 2604 if (pCurHcb->HCS_Phase != MSG_OUT) { 2605 return (int_tul_bad_seq(pCurHcb)); /* Unexpected phase */ 2606 } 2607 tul_unlink_pend_scb(pCurHcb, pCurScb); 2608 tul_release_scb(pCurHcb, pCurScb); 2609 2610 2611 tar = pCurScb->SCB_Target; /* target */ 2612 pCurTcb->TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE | TCF_BUSY); 2613 /* clr sync. nego & WDTR flags 07/22/98 */ 2614 2615 /* abort all SCB with same target */ 2616 pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */ 2617 while (pTmpScb != NULL) { 2618 2619 if (pTmpScb->SCB_Target == tar) { 2620 /* unlink it */ 2621 if (pTmpScb == pCurHcb->HCS_FirstBusy) { 2622 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL) 2623 pCurHcb->HCS_LastBusy = NULL; 2624 } else { 2625 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; 2626 if (pTmpScb == pCurHcb->HCS_LastBusy) 2627 pCurHcb->HCS_LastBusy = pPrevScb; 2628 } 2629 pTmpScb->SCB_HaStat = HOST_ABORTED; 2630 tul_append_done_scb(pCurHcb, pTmpScb); 2631 } 2632 /* Previous haven't change */ 2633 else { 2634 pPrevScb = pTmpScb; 2635 } 2636 pTmpScb = pTmpScb->SCB_NxtScb; 2637 } 2638 2639 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_DEVRST); 2640 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2641 2642 return tul_wait_disc(pCurHcb); 2643 2644 } 2645 2646 /***************************************************************************/ 2647 int tul_msgin_accept(HCS * pCurHcb) 2648 { 2649 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT); 2650 return (wait_tulip(pCurHcb)); 2651 } 2652 2653 /***************************************************************************/ 2654 int wait_tulip(HCS * pCurHcb) 2655 { 2656 2657 while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0)) 2658 & TSS_INT_PENDING)); 2659 2660 pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt); 2661 pCurHcb->HCS_Phase = pCurHcb->HCS_JSStatus0 & TSS_PH_MASK; 2662 pCurHcb->HCS_JSStatus1 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1); 2663 2664 if (pCurHcb->HCS_JSInt & TSS_RESEL_INT) { /* if SCSI bus reset detected */ 2665 return (int_tul_resel(pCurHcb)); 2666 } 2667 if (pCurHcb->HCS_JSInt & TSS_SEL_TIMEOUT) { /* if selected/reselected timeout interrupt */ 2668 return (int_tul_busfree(pCurHcb)); 2669 } 2670 if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) { /* if SCSI bus reset detected */ 2671 return (int_tul_scsi_rst(pCurHcb)); 2672 } 2673 if (pCurHcb->HCS_JSInt & TSS_DISC_INT) { /* BUS disconnection */ 2674 if (pCurHcb->HCS_Flags & HCF_EXPECT_DONE_DISC) { 2675 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */ 2676 tul_unlink_busy_scb(pCurHcb, pCurHcb->HCS_ActScb); 2677 pCurHcb->HCS_ActScb->SCB_HaStat = 0; 2678 tul_append_done_scb(pCurHcb, pCurHcb->HCS_ActScb); 2679 pCurHcb->HCS_ActScb = NULL; 2680 pCurHcb->HCS_ActTcs = NULL; 2681 pCurHcb->HCS_Flags &= ~HCF_EXPECT_DONE_DISC; 2682 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT); 2683 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */ 2684 return (-1); 2685 } 2686 if (pCurHcb->HCS_Flags & HCF_EXPECT_DISC) { 2687 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */ 2688 pCurHcb->HCS_ActScb = NULL; 2689 pCurHcb->HCS_ActTcs = NULL; 2690 pCurHcb->HCS_Flags &= ~HCF_EXPECT_DISC; 2691 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT); 2692 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */ 2693 return (-1); 2694 } 2695 return (int_tul_busfree(pCurHcb)); 2696 } 2697 if (pCurHcb->HCS_JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) { 2698 return (pCurHcb->HCS_Phase); 2699 } 2700 return (pCurHcb->HCS_Phase); 2701 } 2702 /***************************************************************************/ 2703 int tul_wait_disc(HCS * pCurHcb) 2704 { 2705 2706 while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0)) 2707 & TSS_INT_PENDING)); 2708 2709 2710 pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt); 2711 2712 if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) { /* if SCSI bus reset detected */ 2713 return (int_tul_scsi_rst(pCurHcb)); 2714 } 2715 if (pCurHcb->HCS_JSInt & TSS_DISC_INT) { /* BUS disconnection */ 2716 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */ 2717 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT); 2718 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */ 2719 pCurHcb->HCS_ActScb = NULL; 2720 return (-1); 2721 } 2722 return (tul_bad_seq(pCurHcb)); 2723 } 2724 2725 /***************************************************************************/ 2726 int tul_wait_done_disc(HCS * pCurHcb) 2727 { 2728 2729 2730 while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0)) 2731 & TSS_INT_PENDING)); 2732 2733 pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt); 2734 2735 2736 if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) { /* if SCSI bus reset detected */ 2737 return (int_tul_scsi_rst(pCurHcb)); 2738 } 2739 if (pCurHcb->HCS_JSInt & TSS_DISC_INT) { /* BUS disconnection */ 2740 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */ 2741 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT); 2742 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */ 2743 tul_unlink_busy_scb(pCurHcb, pCurHcb->HCS_ActScb); 2744 2745 tul_append_done_scb(pCurHcb, pCurHcb->HCS_ActScb); 2746 pCurHcb->HCS_ActScb = NULL; 2747 return (-1); 2748 } 2749 return (tul_bad_seq(pCurHcb)); 2750 } 2751 2752 static irqreturn_t i91u_intr(int irqno, void *dev_id, struct pt_regs *regs) 2753 { 2754 struct Scsi_Host *dev = dev_id; 2755 unsigned long flags; 2756 2757 spin_lock_irqsave(dev->host_lock, flags); 2758 tul_isr((HCS *)dev->base); 2759 spin_unlock_irqrestore(dev->host_lock, flags); 2760 return IRQ_HANDLED; 2761 } 2762 2763 static int tul_NewReturnNumberOfAdapters(void) 2764 { 2765 struct pci_dev *pDev = NULL; /* Start from none */ 2766 int iAdapters = 0; 2767 long dRegValue; 2768 WORD wBIOS; 2769 int i = 0; 2770 2771 init_i91uAdapter_table(); 2772 2773 for (i = 0; i < TULSZ(i91u_pci_devices); i++) 2774 { 2775 while ((pDev = pci_find_device(i91u_pci_devices[i].vendor_id, i91u_pci_devices[i].device_id, pDev)) != NULL) { 2776 if (pci_enable_device(pDev)) 2777 continue; 2778 pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue); 2779 wBIOS = (UWORD) (dRegValue & 0xFF); 2780 if (((dRegValue & 0xFF00) >> 8) == 0xFF) 2781 dRegValue = 0; 2782 wBIOS = (wBIOS << 8) + ((UWORD) ((dRegValue & 0xFF00) >> 8)); 2783 if (pci_set_dma_mask(pDev, 0xffffffff)) { 2784 printk(KERN_WARNING 2785 "i91u: Could not set 32 bit DMA mask\n"); 2786 continue; 2787 } 2788 2789 if (Addi91u_into_Adapter_table(wBIOS, 2790 (pDev->resource[0].start), 2791 pDev->irq, 2792 pDev->bus->number, 2793 (pDev->devfn >> 3) 2794 ) == 0) 2795 iAdapters++; 2796 } 2797 } 2798 2799 return (iAdapters); 2800 } 2801 2802 static int i91u_detect(struct scsi_host_template * tpnt) 2803 { 2804 HCS *pHCB; 2805 struct Scsi_Host *hreg; 2806 unsigned long i; /* 01/14/98 */ 2807 int ok = 0, iAdapters; 2808 ULONG dBiosAdr; 2809 BYTE *pbBiosAdr; 2810 2811 /* Get total number of adapters in the motherboard */ 2812 iAdapters = tul_NewReturnNumberOfAdapters(); 2813 if (iAdapters == 0) /* If no tulip founded, return */ 2814 return (0); 2815 2816 tul_num_ch = (iAdapters > tul_num_ch) ? tul_num_ch : iAdapters; 2817 /* Update actually channel number */ 2818 if (tul_tag_enable) { /* 1.01i */ 2819 tul_num_scb = MAX_TARGETS * i91u_MAXQUEUE; 2820 } else { 2821 tul_num_scb = MAX_TARGETS + 3; /* 1-tape, 1-CD_ROM, 1- extra */ 2822 } /* Update actually SCBs per adapter */ 2823 2824 /* Get total memory needed for HCS */ 2825 i = tul_num_ch * sizeof(HCS); 2826 memset((unsigned char *) &tul_hcs[0], 0, i); /* Initialize tul_hcs 0 */ 2827 /* Get total memory needed for SCB */ 2828 2829 for (; tul_num_scb >= MAX_TARGETS + 3; tul_num_scb--) { 2830 i = tul_num_ch * tul_num_scb * sizeof(SCB); 2831 if ((tul_scb = (SCB *) kmalloc(i, GFP_ATOMIC | GFP_DMA)) != NULL) 2832 break; 2833 } 2834 if (tul_scb == NULL) { 2835 printk("i91u: SCB memory allocation error\n"); 2836 return (0); 2837 } 2838 memset((unsigned char *) tul_scb, 0, i); 2839 2840 for (i = 0, pHCB = &tul_hcs[0]; /* Get pointer for control block */ 2841 i < tul_num_ch; 2842 i++, pHCB++) { 2843 get_tulipPCIConfig(pHCB, i); 2844 2845 dBiosAdr = pHCB->HCS_BIOS; 2846 dBiosAdr = (dBiosAdr << 4); 2847 2848 pbBiosAdr = phys_to_virt(dBiosAdr); 2849 2850 init_tulip(pHCB, tul_scb + (i * tul_num_scb), tul_num_scb, pbBiosAdr, 10); 2851 request_region(pHCB->HCS_Base, 256, "i91u"); /* Register */ 2852 2853 pHCB->HCS_Index = i; /* 7/29/98 */ 2854 hreg = scsi_register(tpnt, sizeof(HCS)); 2855 if(hreg == NULL) { 2856 release_region(pHCB->HCS_Base, 256); 2857 return 0; 2858 } 2859 hreg->io_port = pHCB->HCS_Base; 2860 hreg->n_io_port = 0xff; 2861 hreg->can_queue = tul_num_scb; /* 03/05/98 */ 2862 hreg->unique_id = pHCB->HCS_Base; 2863 hreg->max_id = pHCB->HCS_MaxTar; 2864 hreg->max_lun = 32; /* 10/21/97 */ 2865 hreg->irq = pHCB->HCS_Intr; 2866 hreg->this_id = pHCB->HCS_SCSI_ID; /* Assign HCS index */ 2867 hreg->base = (unsigned long)pHCB; 2868 hreg->sg_tablesize = TOTAL_SG_ENTRY; /* Maximun support is 32 */ 2869 2870 /* Initial tulip chip */ 2871 ok = request_irq(pHCB->HCS_Intr, i91u_intr, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg); 2872 if (ok < 0) { 2873 printk(KERN_WARNING "i91u: unable to request IRQ %d\n\n", pHCB->HCS_Intr); 2874 return 0; 2875 } 2876 } 2877 2878 tpnt->this_id = -1; 2879 tpnt->can_queue = 1; 2880 2881 return 1; 2882 } 2883 2884 static void i91uBuildSCB(HCS * pHCB, SCB * pSCB, struct scsi_cmnd * SCpnt) 2885 { /* Create corresponding SCB */ 2886 struct scatterlist *pSrbSG; 2887 SG *pSG; /* Pointer to SG list */ 2888 int i; 2889 long TotalLen; 2890 dma_addr_t dma_addr; 2891 2892 pSCB->SCB_Post = i91uSCBPost; /* i91u's callback routine */ 2893 pSCB->SCB_Srb = SCpnt; 2894 pSCB->SCB_Opcode = ExecSCSI; 2895 pSCB->SCB_Flags = SCF_POST; /* After SCSI done, call post routine */ 2896 pSCB->SCB_Target = SCpnt->device->id; 2897 pSCB->SCB_Lun = SCpnt->device->lun; 2898 pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW; 2899 2900 pSCB->SCB_Flags |= SCF_SENSE; /* Turn on auto request sense */ 2901 dma_addr = dma_map_single(&pHCB->pci_dev->dev, SCpnt->sense_buffer, 2902 SENSE_SIZE, DMA_FROM_DEVICE); 2903 pSCB->SCB_SensePtr = cpu_to_le32((u32)dma_addr); 2904 pSCB->SCB_SenseLen = cpu_to_le32(SENSE_SIZE); 2905 SCpnt->SCp.ptr = (char *)(unsigned long)dma_addr; 2906 2907 pSCB->SCB_CDBLen = SCpnt->cmd_len; 2908 pSCB->SCB_HaStat = 0; 2909 pSCB->SCB_TaStat = 0; 2910 memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, SCpnt->cmd_len); 2911 2912 if (SCpnt->device->tagged_supported) { /* Tag Support */ 2913 pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG; /* Do simple tag only */ 2914 } else { 2915 pSCB->SCB_TagMsg = 0; /* No tag support */ 2916 } 2917 /* todo handle map_sg error */ 2918 if (SCpnt->use_sg) { 2919 dma_addr = dma_map_single(&pHCB->pci_dev->dev, &pSCB->SCB_SGList[0], 2920 sizeof(struct SG_Struc) * TOTAL_SG_ENTRY, 2921 DMA_BIDIRECTIONAL); 2922 pSCB->SCB_BufPtr = cpu_to_le32((u32)dma_addr); 2923 SCpnt->SCp.dma_handle = dma_addr; 2924 2925 pSrbSG = (struct scatterlist *) SCpnt->request_buffer; 2926 pSCB->SCB_SGLen = dma_map_sg(&pHCB->pci_dev->dev, pSrbSG, 2927 SCpnt->use_sg, SCpnt->sc_data_direction); 2928 2929 pSCB->SCB_Flags |= SCF_SG; /* Turn on SG list flag */ 2930 for (i = 0, TotalLen = 0, pSG = &pSCB->SCB_SGList[0]; /* 1.01g */ 2931 i < pSCB->SCB_SGLen; i++, pSG++, pSrbSG++) { 2932 pSG->SG_Ptr = cpu_to_le32((u32)sg_dma_address(pSrbSG)); 2933 TotalLen += pSG->SG_Len = cpu_to_le32((u32)sg_dma_len(pSrbSG)); 2934 } 2935 2936 pSCB->SCB_BufLen = (SCpnt->request_bufflen > TotalLen) ? 2937 TotalLen : SCpnt->request_bufflen; 2938 } else if (SCpnt->request_bufflen) { /* Non SG */ 2939 dma_addr = dma_map_single(&pHCB->pci_dev->dev, SCpnt->request_buffer, 2940 SCpnt->request_bufflen, 2941 SCpnt->sc_data_direction); 2942 SCpnt->SCp.dma_handle = dma_addr; 2943 pSCB->SCB_BufPtr = cpu_to_le32((u32)dma_addr); 2944 pSCB->SCB_BufLen = cpu_to_le32((u32)SCpnt->request_bufflen); 2945 pSCB->SCB_SGLen = 0; 2946 } else { 2947 pSCB->SCB_BufLen = 0; 2948 pSCB->SCB_SGLen = 0; 2949 } 2950 } 2951 2952 static int i91u_queuecommand(struct scsi_cmnd *cmd, 2953 void (*done)(struct scsi_cmnd *)) 2954 { 2955 HCS *pHCB = (HCS *) cmd->device->host->base; 2956 register SCB *pSCB; 2957 2958 cmd->scsi_done = done; 2959 2960 pSCB = tul_alloc_scb(pHCB); 2961 if (!pSCB) 2962 return SCSI_MLQUEUE_HOST_BUSY; 2963 2964 i91uBuildSCB(pHCB, pSCB, cmd); 2965 tul_exec_scb(pHCB, pSCB); 2966 return 0; 2967 } 2968 2969 #if 0 /* no new EH yet */ 2970 /* 2971 * Abort a queued command 2972 * (commands that are on the bus can't be aborted easily) 2973 */ 2974 static int i91u_abort(struct scsi_cmnd * SCpnt) 2975 { 2976 HCS *pHCB; 2977 2978 pHCB = (HCS *) SCpnt->device->host->base; 2979 return tul_abort_srb(pHCB, SCpnt); 2980 } 2981 2982 /* 2983 * Reset registers, reset a hanging bus and 2984 * kill active and disconnected commands for target w/o soft reset 2985 */ 2986 static int i91u_reset(struct scsi_cmnd * SCpnt, unsigned int reset_flags) 2987 { /* I need Host Control Block Information */ 2988 HCS *pHCB; 2989 2990 pHCB = (HCS *) SCpnt->device->host->base; 2991 2992 if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET)) 2993 return tul_reset_scsi_bus(pHCB); 2994 else 2995 return tul_device_reset(pHCB, SCpnt, SCpnt->device->id, reset_flags); 2996 } 2997 #endif 2998 2999 static int i91u_bus_reset(struct scsi_cmnd * SCpnt) 3000 { 3001 HCS *pHCB; 3002 3003 pHCB = (HCS *) SCpnt->device->host->base; 3004 3005 spin_lock_irq(SCpnt->device->host->host_lock); 3006 tul_reset_scsi(pHCB, 0); 3007 spin_unlock_irq(SCpnt->device->host->host_lock); 3008 3009 return SUCCESS; 3010 } 3011 3012 /* 3013 * Return the "logical geometry" 3014 */ 3015 static int i91u_biosparam(struct scsi_device *sdev, struct block_device *dev, 3016 sector_t capacity, int *info_array) 3017 { 3018 HCS *pHcb; /* Point to Host adapter control block */ 3019 TCS *pTcb; 3020 3021 pHcb = (HCS *) sdev->host->base; 3022 pTcb = &pHcb->HCS_Tcs[sdev->id]; 3023 3024 if (pTcb->TCS_DrvHead) { 3025 info_array[0] = pTcb->TCS_DrvHead; 3026 info_array[1] = pTcb->TCS_DrvSector; 3027 info_array[2] = (unsigned long)capacity / pTcb->TCS_DrvHead / pTcb->TCS_DrvSector; 3028 } else { 3029 if (pTcb->TCS_DrvFlags & TCF_DRV_255_63) { 3030 info_array[0] = 255; 3031 info_array[1] = 63; 3032 info_array[2] = (unsigned long)capacity / 255 / 63; 3033 } else { 3034 info_array[0] = 64; 3035 info_array[1] = 32; 3036 info_array[2] = (unsigned long)capacity >> 11; 3037 } 3038 } 3039 3040 #if defined(DEBUG_BIOSPARAM) 3041 if (i91u_debug & debug_biosparam) { 3042 printk("bios geometry: head=%d, sec=%d, cyl=%d\n", 3043 info_array[0], info_array[1], info_array[2]); 3044 printk("WARNING: check, if the bios geometry is correct.\n"); 3045 } 3046 #endif 3047 3048 return 0; 3049 } 3050 3051 static void i91u_unmap_cmnd(struct pci_dev *pci_dev, struct scsi_cmnd *cmnd) 3052 { 3053 /* auto sense buffer */ 3054 if (cmnd->SCp.ptr) { 3055 dma_unmap_single(&pci_dev->dev, 3056 (dma_addr_t)((unsigned long)cmnd->SCp.ptr), 3057 SENSE_SIZE, DMA_FROM_DEVICE); 3058 cmnd->SCp.ptr = NULL; 3059 } 3060 3061 /* request buffer */ 3062 if (cmnd->use_sg) { 3063 dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle, 3064 sizeof(struct SG_Struc) * TOTAL_SG_ENTRY, 3065 DMA_BIDIRECTIONAL); 3066 3067 dma_unmap_sg(&pci_dev->dev, cmnd->request_buffer, 3068 cmnd->use_sg, 3069 cmnd->sc_data_direction); 3070 } else if (cmnd->request_bufflen) { 3071 dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle, 3072 cmnd->request_bufflen, 3073 cmnd->sc_data_direction); 3074 } 3075 } 3076 3077 /***************************************************************************** 3078 Function name : i91uSCBPost 3079 Description : This is callback routine be called when tulip finish one 3080 SCSI command. 3081 Input : pHCB - Pointer to host adapter control block. 3082 pSCB - Pointer to SCSI control block. 3083 Output : None. 3084 Return : None. 3085 *****************************************************************************/ 3086 static void i91uSCBPost(BYTE * pHcb, BYTE * pScb) 3087 { 3088 struct scsi_cmnd *pSRB; /* Pointer to SCSI request block */ 3089 HCS *pHCB; 3090 SCB *pSCB; 3091 3092 pHCB = (HCS *) pHcb; 3093 pSCB = (SCB *) pScb; 3094 if ((pSRB = pSCB->SCB_Srb) == 0) { 3095 printk("i91uSCBPost: SRB pointer is empty\n"); 3096 3097 tul_release_scb(pHCB, pSCB); /* Release SCB for current channel */ 3098 return; 3099 } 3100 switch (pSCB->SCB_HaStat) { 3101 case 0x0: 3102 case 0xa: /* Linked command complete without error and linked normally */ 3103 case 0xb: /* Linked command complete without error interrupt generated */ 3104 pSCB->SCB_HaStat = 0; 3105 break; 3106 3107 case 0x11: /* Selection time out-The initiator selection or target 3108 reselection was not complete within the SCSI Time out period */ 3109 pSCB->SCB_HaStat = DID_TIME_OUT; 3110 break; 3111 3112 case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus 3113 phase sequence was requested by the target. The host adapter 3114 will generate a SCSI Reset Condition, notifying the host with 3115 a SCRD interrupt */ 3116 pSCB->SCB_HaStat = DID_RESET; 3117 break; 3118 3119 case 0x1a: /* SCB Aborted. 07/21/98 */ 3120 pSCB->SCB_HaStat = DID_ABORT; 3121 break; 3122 3123 case 0x12: /* Data overrun/underrun-The target attempted to transfer more data 3124 than was allocated by the Data Length field or the sum of the 3125 Scatter / Gather Data Length fields. */ 3126 case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */ 3127 case 0x16: /* Invalid SCB Operation Code. */ 3128 3129 default: 3130 printk("ini9100u: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat); 3131 pSCB->SCB_HaStat = DID_ERROR; /* Couldn't find any better */ 3132 break; 3133 } 3134 3135 pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16); 3136 3137 if (pSRB == NULL) { 3138 printk("pSRB is NULL\n"); 3139 } 3140 3141 i91u_unmap_cmnd(pHCB->pci_dev, pSRB); 3142 pSRB->scsi_done(pSRB); /* Notify system DONE */ 3143 3144 tul_release_scb(pHCB, pSCB); /* Release SCB for current channel */ 3145 } 3146 3147 /* 3148 * Release ressources 3149 */ 3150 static int i91u_release(struct Scsi_Host *hreg) 3151 { 3152 free_irq(hreg->irq, hreg); 3153 release_region(hreg->io_port, 256); 3154 return 0; 3155 } 3156 MODULE_LICENSE("Dual BSD/GPL"); 3157 3158 static struct scsi_host_template driver_template = { 3159 .proc_name = "INI9100U", 3160 .name = i91u_REVID, 3161 .detect = i91u_detect, 3162 .release = i91u_release, 3163 .queuecommand = i91u_queuecommand, 3164 // .abort = i91u_abort, 3165 // .reset = i91u_reset, 3166 .eh_bus_reset_handler = i91u_bus_reset, 3167 .bios_param = i91u_biosparam, 3168 .can_queue = 1, 3169 .this_id = 1, 3170 .sg_tablesize = SG_ALL, 3171 .cmd_per_lun = 1, 3172 .use_clustering = ENABLE_CLUSTERING, 3173 }; 3174 #include "scsi_module.c" 3175 3176