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