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 <linux/dma-mapping.h> 131 #include <asm/io.h> 132 133 #include <scsi/scsi.h> 134 #include <scsi/scsi_cmnd.h> 135 #include <scsi/scsi_device.h> 136 #include <scsi/scsi_host.h> 137 #include <scsi/scsi_tcq.h> 138 139 #include "initio.h" 140 141 #define SENSE_SIZE 14 142 143 #define i91u_MAXQUEUE 2 144 #define i91u_REVID "Initio INI-9X00U/UW SCSI device driver; Revision: 1.04a" 145 146 #define INI_VENDOR_ID 0x1101 /* Initio's PCI vendor ID */ 147 #define DMX_VENDOR_ID 0x134a /* Domex's PCI vendor ID */ 148 #define I950_DEVICE_ID 0x9500 /* Initio's inic-950 product ID */ 149 #define I940_DEVICE_ID 0x9400 /* Initio's inic-940 product ID */ 150 #define I935_DEVICE_ID 0x9401 /* Initio's inic-935 product ID */ 151 #define I920_DEVICE_ID 0x0002 /* Initio's other product ID */ 152 153 #ifdef DEBUG_i91u 154 static unsigned int i91u_debug = DEBUG_DEFAULT; 155 #endif 156 157 #define TULSZ(sz) (sizeof(sz) / sizeof(sz[0])) 158 #define TUL_RDWORD(x,y) (short)(inl((int)((ULONG)((ULONG)x+(UCHAR)y)) )) 159 160 typedef struct PCI_ID_Struc { 161 unsigned short vendor_id; 162 unsigned short device_id; 163 } PCI_ID; 164 165 static int tul_num_ch = 4; /* Maximum 4 adapters */ 166 static int tul_num_scb; 167 static int tul_tag_enable = 1; 168 static SCB *tul_scb; 169 170 #ifdef DEBUG_i91u 171 static int setup_debug = 0; 172 #endif 173 174 static void i91uSCBPost(BYTE * pHcb, BYTE * pScb); 175 176 static const PCI_ID i91u_pci_devices[] = { 177 { INI_VENDOR_ID, I950_DEVICE_ID }, 178 { INI_VENDOR_ID, I940_DEVICE_ID }, 179 { INI_VENDOR_ID, I935_DEVICE_ID }, 180 { INI_VENDOR_ID, I920_DEVICE_ID }, 181 { DMX_VENDOR_ID, I920_DEVICE_ID }, 182 }; 183 184 #define DEBUG_INTERRUPT 0 185 #define DEBUG_QUEUE 0 186 #define DEBUG_STATE 0 187 #define INT_DISC 0 188 189 /*--- external functions --*/ 190 static void tul_se2_wait(void); 191 192 /*--- forward refrence ---*/ 193 static SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun); 194 static SCB *tul_find_done_scb(HCS * pCurHcb); 195 196 static int tulip_main(HCS * pCurHcb); 197 198 static int tul_next_state(HCS * pCurHcb); 199 static int tul_state_1(HCS * pCurHcb); 200 static int tul_state_2(HCS * pCurHcb); 201 static int tul_state_3(HCS * pCurHcb); 202 static int tul_state_4(HCS * pCurHcb); 203 static int tul_state_5(HCS * pCurHcb); 204 static int tul_state_6(HCS * pCurHcb); 205 static int tul_state_7(HCS * pCurHcb); 206 static int tul_xfer_data_in(HCS * pCurHcb); 207 static int tul_xfer_data_out(HCS * pCurHcb); 208 static int tul_xpad_in(HCS * pCurHcb); 209 static int tul_xpad_out(HCS * pCurHcb); 210 static int tul_status_msg(HCS * pCurHcb); 211 212 static int tul_msgin(HCS * pCurHcb); 213 static int tul_msgin_sync(HCS * pCurHcb); 214 static int tul_msgin_accept(HCS * pCurHcb); 215 static int tul_msgout_reject(HCS * pCurHcb); 216 static int tul_msgin_extend(HCS * pCurHcb); 217 218 static int tul_msgout_ide(HCS * pCurHcb); 219 static int tul_msgout_abort_targ(HCS * pCurHcb); 220 static int tul_msgout_abort_tag(HCS * pCurHcb); 221 222 static int tul_bus_device_reset(HCS * pCurHcb); 223 static void tul_select_atn(HCS * pCurHcb, SCB * pCurScb); 224 static void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb); 225 static void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb); 226 static int int_tul_busfree(HCS * pCurHcb); 227 static int int_tul_scsi_rst(HCS * pCurHcb); 228 static int int_tul_bad_seq(HCS * pCurHcb); 229 static int int_tul_resel(HCS * pCurHcb); 230 static int tul_sync_done(HCS * pCurHcb); 231 static int wdtr_done(HCS * pCurHcb); 232 static int wait_tulip(HCS * pCurHcb); 233 static int tul_wait_done_disc(HCS * pCurHcb); 234 static int tul_wait_disc(HCS * pCurHcb); 235 static void tulip_scsi(HCS * pCurHcb); 236 static int tul_post_scsi_rst(HCS * pCurHcb); 237 238 static void tul_se2_ew_en(WORD CurBase); 239 static void tul_se2_ew_ds(WORD CurBase); 240 static int tul_se2_rd_all(WORD CurBase); 241 static void tul_se2_update_all(WORD CurBase); /* setup default pattern */ 242 static void tul_read_eeprom(WORD CurBase); 243 244 /* ---- INTERNAL VARIABLES ---- */ 245 static HCS tul_hcs[MAX_SUPPORTED_ADAPTERS]; 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 static 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 static 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 static 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 static 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 static 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 static 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 static 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 static 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 static int init_tulip(HCS * pCurHcb, SCB * scbp, int tul_num_scb, 674 BYTE * pbBiosAdr, int seconds) 675 { 676 int i; 677 BYTE *pwFlags; 678 BYTE *pbHeads; 679 SCB *pTmpScb, *pPrevScb = NULL; 680 681 pCurHcb->HCS_NumScbs = tul_num_scb; 682 pCurHcb->HCS_Semaph = 1; 683 spin_lock_init(&pCurHcb->HCS_SemaphLock); 684 pCurHcb->HCS_JSStatus0 = 0; 685 pCurHcb->HCS_Scb = scbp; 686 pCurHcb->HCS_NxtPend = scbp; 687 pCurHcb->HCS_NxtAvail = scbp; 688 for (i = 0, pTmpScb = scbp; i < tul_num_scb; i++, pTmpScb++) { 689 pTmpScb->SCB_TagId = i; 690 if (i != 0) 691 pPrevScb->SCB_NxtScb = pTmpScb; 692 pPrevScb = pTmpScb; 693 } 694 pPrevScb->SCB_NxtScb = NULL; 695 pCurHcb->HCS_ScbEnd = pTmpScb; 696 pCurHcb->HCS_FirstAvail = scbp; 697 pCurHcb->HCS_LastAvail = pPrevScb; 698 spin_lock_init(&pCurHcb->HCS_AvailLock); 699 pCurHcb->HCS_FirstPend = NULL; 700 pCurHcb->HCS_LastPend = NULL; 701 pCurHcb->HCS_FirstBusy = NULL; 702 pCurHcb->HCS_LastBusy = NULL; 703 pCurHcb->HCS_FirstDone = NULL; 704 pCurHcb->HCS_LastDone = NULL; 705 pCurHcb->HCS_ActScb = NULL; 706 pCurHcb->HCS_ActTcs = NULL; 707 708 tul_read_eeprom(pCurHcb->HCS_Base); 709 /*---------- get H/A configuration -------------*/ 710 if (i91unvramp->NVM_SCSIInfo[0].NVM_NumOfTarg == 8) 711 pCurHcb->HCS_MaxTar = 8; 712 else 713 pCurHcb->HCS_MaxTar = 16; 714 715 pCurHcb->HCS_Config = i91unvramp->NVM_SCSIInfo[0].NVM_ChConfig1; 716 717 pCurHcb->HCS_SCSI_ID = i91unvramp->NVM_SCSIInfo[0].NVM_ChSCSIID; 718 pCurHcb->HCS_IdMask = ~(1 << pCurHcb->HCS_SCSI_ID); 719 720 #ifdef CHK_PARITY 721 /* Enable parity error response */ 722 TUL_WR(pCurHcb->HCS_Base + TUL_PCMD, TUL_RD(pCurHcb->HCS_Base, TUL_PCMD) | 0x40); 723 #endif 724 725 /* Mask all the interrupt */ 726 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 727 728 tul_stop_bm(pCurHcb); 729 /* --- Initialize the tulip --- */ 730 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_RST_CHIP); 731 732 /* program HBA's SCSI ID */ 733 TUL_WR(pCurHcb->HCS_Base + TUL_SScsiId, pCurHcb->HCS_SCSI_ID << 4); 734 735 /* Enable Initiator Mode ,phase latch,alternate sync period mode, 736 disable SCSI reset */ 737 if (pCurHcb->HCS_Config & HCC_EN_PAR) 738 pCurHcb->HCS_SConf1 = (TSC_INITDEFAULT | TSC_EN_SCSI_PAR); 739 else 740 pCurHcb->HCS_SConf1 = (TSC_INITDEFAULT); 741 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_SConf1); 742 743 /* Enable HW reselect */ 744 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); 745 746 TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, 0); 747 748 /* selection time out = 250 ms */ 749 TUL_WR(pCurHcb->HCS_Base + TUL_STimeOut, 153); 750 751 /*--------- Enable SCSI terminator -----*/ 752 TUL_WR(pCurHcb->HCS_Base + TUL_XCtrl, (pCurHcb->HCS_Config & (HCC_ACT_TERM1 | HCC_ACT_TERM2))); 753 TUL_WR(pCurHcb->HCS_Base + TUL_GCTRL1, 754 ((pCurHcb->HCS_Config & HCC_AUTO_TERM) >> 4) | (TUL_RD(pCurHcb->HCS_Base, TUL_GCTRL1) & 0xFE)); 755 756 for (i = 0, 757 pwFlags = & (i91unvramp->NVM_SCSIInfo[0].NVM_Targ0Config), 758 pbHeads = pbBiosAdr + 0x180; 759 i < pCurHcb->HCS_MaxTar; 760 i++, pwFlags++) { 761 pCurHcb->HCS_Tcs[i].TCS_Flags = *pwFlags & ~(TCF_SYNC_DONE | TCF_WDTR_DONE); 762 if (pCurHcb->HCS_Tcs[i].TCS_Flags & TCF_EN_255) 763 pCurHcb->HCS_Tcs[i].TCS_DrvFlags = TCF_DRV_255_63; 764 else 765 pCurHcb->HCS_Tcs[i].TCS_DrvFlags = 0; 766 pCurHcb->HCS_Tcs[i].TCS_JS_Period = 0; 767 pCurHcb->HCS_Tcs[i].TCS_SConfig0 = pCurHcb->HCS_SConf1; 768 pCurHcb->HCS_Tcs[i].TCS_DrvHead = *pbHeads++; 769 if (pCurHcb->HCS_Tcs[i].TCS_DrvHead == 255) 770 pCurHcb->HCS_Tcs[i].TCS_DrvFlags = TCF_DRV_255_63; 771 else 772 pCurHcb->HCS_Tcs[i].TCS_DrvFlags = 0; 773 pCurHcb->HCS_Tcs[i].TCS_DrvSector = *pbHeads++; 774 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~TCF_BUSY; 775 pCurHcb->HCS_ActTags[i] = 0; 776 pCurHcb->HCS_MaxTags[i] = 0xFF; 777 } /* for */ 778 printk("i91u: PCI Base=0x%04X, IRQ=%d, BIOS=0x%04X0, SCSI ID=%d\n", 779 pCurHcb->HCS_Base, pCurHcb->HCS_Intr, 780 pCurHcb->HCS_BIOS, pCurHcb->HCS_SCSI_ID); 781 /*------------------- reset SCSI Bus ---------------------------*/ 782 if (pCurHcb->HCS_Config & HCC_SCSI_RESET) { 783 printk("i91u: Reset SCSI Bus ... \n"); 784 tul_reset_scsi(pCurHcb, seconds); 785 } 786 TUL_WR(pCurHcb->HCS_Base + TUL_SCFG1, 0x17); 787 TUL_WR(pCurHcb->HCS_Base + TUL_SIntEnable, 0xE9); 788 return (0); 789 } 790 791 /***************************************************************************/ 792 static SCB *tul_alloc_scb(HCS * hcsp) 793 { 794 SCB *pTmpScb; 795 ULONG flags; 796 spin_lock_irqsave(&(hcsp->HCS_AvailLock), flags); 797 if ((pTmpScb = hcsp->HCS_FirstAvail) != NULL) { 798 #if DEBUG_QUEUE 799 printk("find scb at %08lx\n", (ULONG) pTmpScb); 800 #endif 801 if ((hcsp->HCS_FirstAvail = pTmpScb->SCB_NxtScb) == NULL) 802 hcsp->HCS_LastAvail = NULL; 803 pTmpScb->SCB_NxtScb = NULL; 804 pTmpScb->SCB_Status = SCB_RENT; 805 } 806 spin_unlock_irqrestore(&(hcsp->HCS_AvailLock), flags); 807 return (pTmpScb); 808 } 809 810 /***************************************************************************/ 811 static void tul_release_scb(HCS * hcsp, SCB * scbp) 812 { 813 ULONG flags; 814 815 #if DEBUG_QUEUE 816 printk("Release SCB %lx; ", (ULONG) scbp); 817 #endif 818 spin_lock_irqsave(&(hcsp->HCS_AvailLock), flags); 819 scbp->SCB_Srb = NULL; 820 scbp->SCB_Status = 0; 821 scbp->SCB_NxtScb = NULL; 822 if (hcsp->HCS_LastAvail != NULL) { 823 hcsp->HCS_LastAvail->SCB_NxtScb = scbp; 824 hcsp->HCS_LastAvail = scbp; 825 } else { 826 hcsp->HCS_FirstAvail = scbp; 827 hcsp->HCS_LastAvail = scbp; 828 } 829 spin_unlock_irqrestore(&(hcsp->HCS_AvailLock), flags); 830 } 831 832 /***************************************************************************/ 833 static void tul_append_pend_scb(HCS * pCurHcb, SCB * scbp) 834 { 835 836 #if DEBUG_QUEUE 837 printk("Append pend SCB %lx; ", (ULONG) scbp); 838 #endif 839 scbp->SCB_Status = SCB_PEND; 840 scbp->SCB_NxtScb = NULL; 841 if (pCurHcb->HCS_LastPend != NULL) { 842 pCurHcb->HCS_LastPend->SCB_NxtScb = scbp; 843 pCurHcb->HCS_LastPend = scbp; 844 } else { 845 pCurHcb->HCS_FirstPend = scbp; 846 pCurHcb->HCS_LastPend = scbp; 847 } 848 } 849 850 /***************************************************************************/ 851 static void tul_push_pend_scb(HCS * pCurHcb, SCB * scbp) 852 { 853 854 #if DEBUG_QUEUE 855 printk("Push pend SCB %lx; ", (ULONG) scbp); 856 #endif 857 scbp->SCB_Status = SCB_PEND; 858 if ((scbp->SCB_NxtScb = pCurHcb->HCS_FirstPend) != NULL) { 859 pCurHcb->HCS_FirstPend = scbp; 860 } else { 861 pCurHcb->HCS_FirstPend = scbp; 862 pCurHcb->HCS_LastPend = scbp; 863 } 864 } 865 866 /***************************************************************************/ 867 static SCB *tul_find_first_pend_scb(HCS * pCurHcb) 868 { 869 SCB *pFirstPend; 870 871 872 pFirstPend = pCurHcb->HCS_FirstPend; 873 while (pFirstPend != NULL) { 874 if (pFirstPend->SCB_Opcode != ExecSCSI) { 875 return (pFirstPend); 876 } 877 if (pFirstPend->SCB_TagMsg == 0) { 878 if ((pCurHcb->HCS_ActTags[pFirstPend->SCB_Target] == 0) && 879 !(pCurHcb->HCS_Tcs[pFirstPend->SCB_Target].TCS_Flags & TCF_BUSY)) { 880 return (pFirstPend); 881 } 882 } else { 883 if ((pCurHcb->HCS_ActTags[pFirstPend->SCB_Target] >= 884 pCurHcb->HCS_MaxTags[pFirstPend->SCB_Target]) | 885 (pCurHcb->HCS_Tcs[pFirstPend->SCB_Target].TCS_Flags & TCF_BUSY)) { 886 pFirstPend = pFirstPend->SCB_NxtScb; 887 continue; 888 } 889 return (pFirstPend); 890 } 891 pFirstPend = pFirstPend->SCB_NxtScb; 892 } 893 894 895 return (pFirstPend); 896 } 897 /***************************************************************************/ 898 static void tul_unlink_pend_scb(HCS * pCurHcb, SCB * pCurScb) 899 { 900 SCB *pTmpScb, *pPrevScb; 901 902 #if DEBUG_QUEUE 903 printk("unlink pend SCB %lx; ", (ULONG) pCurScb); 904 #endif 905 906 pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend; 907 while (pTmpScb != NULL) { 908 if (pCurScb == pTmpScb) { /* Unlink this SCB */ 909 if (pTmpScb == pCurHcb->HCS_FirstPend) { 910 if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL) 911 pCurHcb->HCS_LastPend = NULL; 912 } else { 913 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; 914 if (pTmpScb == pCurHcb->HCS_LastPend) 915 pCurHcb->HCS_LastPend = pPrevScb; 916 } 917 pTmpScb->SCB_NxtScb = NULL; 918 break; 919 } 920 pPrevScb = pTmpScb; 921 pTmpScb = pTmpScb->SCB_NxtScb; 922 } 923 return; 924 } 925 /***************************************************************************/ 926 static void tul_append_busy_scb(HCS * pCurHcb, SCB * scbp) 927 { 928 929 #if DEBUG_QUEUE 930 printk("append busy SCB %lx; ", (ULONG) scbp); 931 #endif 932 if (scbp->SCB_TagMsg) 933 pCurHcb->HCS_ActTags[scbp->SCB_Target]++; 934 else 935 pCurHcb->HCS_Tcs[scbp->SCB_Target].TCS_Flags |= TCF_BUSY; 936 scbp->SCB_Status = SCB_BUSY; 937 scbp->SCB_NxtScb = NULL; 938 if (pCurHcb->HCS_LastBusy != NULL) { 939 pCurHcb->HCS_LastBusy->SCB_NxtScb = scbp; 940 pCurHcb->HCS_LastBusy = scbp; 941 } else { 942 pCurHcb->HCS_FirstBusy = scbp; 943 pCurHcb->HCS_LastBusy = scbp; 944 } 945 } 946 947 /***************************************************************************/ 948 static SCB *tul_pop_busy_scb(HCS * pCurHcb) 949 { 950 SCB *pTmpScb; 951 952 953 if ((pTmpScb = pCurHcb->HCS_FirstBusy) != NULL) { 954 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL) 955 pCurHcb->HCS_LastBusy = NULL; 956 pTmpScb->SCB_NxtScb = NULL; 957 if (pTmpScb->SCB_TagMsg) 958 pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--; 959 else 960 pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY; 961 } 962 #if DEBUG_QUEUE 963 printk("Pop busy SCB %lx; ", (ULONG) pTmpScb); 964 #endif 965 return (pTmpScb); 966 } 967 968 /***************************************************************************/ 969 static void tul_unlink_busy_scb(HCS * pCurHcb, SCB * pCurScb) 970 { 971 SCB *pTmpScb, *pPrevScb; 972 973 #if DEBUG_QUEUE 974 printk("unlink busy SCB %lx; ", (ULONG) pCurScb); 975 #endif 976 977 pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; 978 while (pTmpScb != NULL) { 979 if (pCurScb == pTmpScb) { /* Unlink this SCB */ 980 if (pTmpScb == pCurHcb->HCS_FirstBusy) { 981 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL) 982 pCurHcb->HCS_LastBusy = NULL; 983 } else { 984 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; 985 if (pTmpScb == pCurHcb->HCS_LastBusy) 986 pCurHcb->HCS_LastBusy = pPrevScb; 987 } 988 pTmpScb->SCB_NxtScb = NULL; 989 if (pTmpScb->SCB_TagMsg) 990 pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--; 991 else 992 pCurHcb->HCS_Tcs[pTmpScb->SCB_Target].TCS_Flags &= ~TCF_BUSY; 993 break; 994 } 995 pPrevScb = pTmpScb; 996 pTmpScb = pTmpScb->SCB_NxtScb; 997 } 998 return; 999 } 1000 1001 /***************************************************************************/ 1002 SCB *tul_find_busy_scb(HCS * pCurHcb, WORD tarlun) 1003 { 1004 SCB *pTmpScb, *pPrevScb; 1005 WORD scbp_tarlun; 1006 1007 1008 pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; 1009 while (pTmpScb != NULL) { 1010 scbp_tarlun = (pTmpScb->SCB_Lun << 8) | (pTmpScb->SCB_Target); 1011 if (scbp_tarlun == tarlun) { /* Unlink this SCB */ 1012 break; 1013 } 1014 pPrevScb = pTmpScb; 1015 pTmpScb = pTmpScb->SCB_NxtScb; 1016 } 1017 #if DEBUG_QUEUE 1018 printk("find busy SCB %lx; ", (ULONG) pTmpScb); 1019 #endif 1020 return (pTmpScb); 1021 } 1022 1023 /***************************************************************************/ 1024 static void tul_append_done_scb(HCS * pCurHcb, SCB * scbp) 1025 { 1026 1027 #if DEBUG_QUEUE 1028 printk("append done SCB %lx; ", (ULONG) scbp); 1029 #endif 1030 1031 scbp->SCB_Status = SCB_DONE; 1032 scbp->SCB_NxtScb = NULL; 1033 if (pCurHcb->HCS_LastDone != NULL) { 1034 pCurHcb->HCS_LastDone->SCB_NxtScb = scbp; 1035 pCurHcb->HCS_LastDone = scbp; 1036 } else { 1037 pCurHcb->HCS_FirstDone = scbp; 1038 pCurHcb->HCS_LastDone = scbp; 1039 } 1040 } 1041 1042 /***************************************************************************/ 1043 SCB *tul_find_done_scb(HCS * pCurHcb) 1044 { 1045 SCB *pTmpScb; 1046 1047 1048 if ((pTmpScb = pCurHcb->HCS_FirstDone) != NULL) { 1049 if ((pCurHcb->HCS_FirstDone = pTmpScb->SCB_NxtScb) == NULL) 1050 pCurHcb->HCS_LastDone = NULL; 1051 pTmpScb->SCB_NxtScb = NULL; 1052 } 1053 #if DEBUG_QUEUE 1054 printk("find done SCB %lx; ", (ULONG) pTmpScb); 1055 #endif 1056 return (pTmpScb); 1057 } 1058 1059 /***************************************************************************/ 1060 static int tul_abort_srb(HCS * pCurHcb, struct scsi_cmnd *srbp) 1061 { 1062 ULONG flags; 1063 SCB *pTmpScb, *pPrevScb; 1064 1065 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1066 1067 if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) { 1068 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 1069 /* disable Jasmin SCSI Int */ 1070 1071 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1072 1073 tulip_main(pCurHcb); 1074 1075 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1076 1077 pCurHcb->HCS_Semaph = 1; 1078 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); 1079 1080 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1081 1082 return SCSI_ABORT_SNOOZE; 1083 } 1084 pPrevScb = pTmpScb = pCurHcb->HCS_FirstPend; /* Check Pend queue */ 1085 while (pTmpScb != NULL) { 1086 /* 07/27/98 */ 1087 if (pTmpScb->SCB_Srb == srbp) { 1088 if (pTmpScb == pCurHcb->HCS_ActScb) { 1089 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1090 return SCSI_ABORT_BUSY; 1091 } else if (pTmpScb == pCurHcb->HCS_FirstPend) { 1092 if ((pCurHcb->HCS_FirstPend = pTmpScb->SCB_NxtScb) == NULL) 1093 pCurHcb->HCS_LastPend = NULL; 1094 } else { 1095 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; 1096 if (pTmpScb == pCurHcb->HCS_LastPend) 1097 pCurHcb->HCS_LastPend = pPrevScb; 1098 } 1099 pTmpScb->SCB_HaStat = HOST_ABORTED; 1100 pTmpScb->SCB_Flags |= SCF_DONE; 1101 if (pTmpScb->SCB_Flags & SCF_POST) 1102 (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb); 1103 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1104 return SCSI_ABORT_SUCCESS; 1105 } 1106 pPrevScb = pTmpScb; 1107 pTmpScb = pTmpScb->SCB_NxtScb; 1108 } 1109 1110 pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */ 1111 while (pTmpScb != NULL) { 1112 1113 if (pTmpScb->SCB_Srb == srbp) { 1114 1115 if (pTmpScb == pCurHcb->HCS_ActScb) { 1116 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1117 return SCSI_ABORT_BUSY; 1118 } else if (pTmpScb->SCB_TagMsg == 0) { 1119 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1120 return SCSI_ABORT_BUSY; 1121 } else { 1122 pCurHcb->HCS_ActTags[pTmpScb->SCB_Target]--; 1123 if (pTmpScb == pCurHcb->HCS_FirstBusy) { 1124 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL) 1125 pCurHcb->HCS_LastBusy = NULL; 1126 } else { 1127 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; 1128 if (pTmpScb == pCurHcb->HCS_LastBusy) 1129 pCurHcb->HCS_LastBusy = pPrevScb; 1130 } 1131 pTmpScb->SCB_NxtScb = NULL; 1132 1133 1134 pTmpScb->SCB_HaStat = HOST_ABORTED; 1135 pTmpScb->SCB_Flags |= SCF_DONE; 1136 if (pTmpScb->SCB_Flags & SCF_POST) 1137 (*pTmpScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pTmpScb); 1138 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1139 return SCSI_ABORT_SUCCESS; 1140 } 1141 } 1142 pPrevScb = pTmpScb; 1143 pTmpScb = pTmpScb->SCB_NxtScb; 1144 } 1145 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1146 return (SCSI_ABORT_NOT_RUNNING); 1147 } 1148 1149 /***************************************************************************/ 1150 static int tul_bad_seq(HCS * pCurHcb) 1151 { 1152 SCB *pCurScb; 1153 1154 printk("tul_bad_seg c=%d\n", pCurHcb->HCS_Index); 1155 1156 if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) { 1157 tul_unlink_busy_scb(pCurHcb, pCurScb); 1158 pCurScb->SCB_HaStat = HOST_BAD_PHAS; 1159 pCurScb->SCB_TaStat = 0; 1160 tul_append_done_scb(pCurHcb, pCurScb); 1161 } 1162 tul_stop_bm(pCurHcb); 1163 1164 tul_reset_scsi(pCurHcb, 8); /* 7/29/98 */ 1165 1166 return (tul_post_scsi_rst(pCurHcb)); 1167 } 1168 1169 #if 0 1170 1171 /************************************************************************/ 1172 static int tul_device_reset(HCS * pCurHcb, struct scsi_cmnd *pSrb, 1173 unsigned int target, unsigned int ResetFlags) 1174 { 1175 ULONG flags; 1176 SCB *pScb; 1177 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1178 1179 if (ResetFlags & SCSI_RESET_ASYNCHRONOUS) { 1180 1181 if ((pCurHcb->HCS_Semaph == 0) && (pCurHcb->HCS_ActScb == NULL)) { 1182 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 1183 /* disable Jasmin SCSI Int */ 1184 1185 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1186 1187 tulip_main(pCurHcb); 1188 1189 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1190 1191 pCurHcb->HCS_Semaph = 1; 1192 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); 1193 1194 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1195 1196 return SCSI_RESET_SNOOZE; 1197 } 1198 pScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */ 1199 while (pScb != NULL) { 1200 if (pScb->SCB_Srb == pSrb) 1201 break; 1202 pScb = pScb->SCB_NxtScb; 1203 } 1204 if (pScb == NULL) { 1205 printk("Unable to Reset - No SCB Found\n"); 1206 1207 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1208 return SCSI_RESET_NOT_RUNNING; 1209 } 1210 } 1211 if ((pScb = tul_alloc_scb(pCurHcb)) == NULL) { 1212 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1213 return SCSI_RESET_NOT_RUNNING; 1214 } 1215 pScb->SCB_Opcode = BusDevRst; 1216 pScb->SCB_Flags = SCF_POST; 1217 pScb->SCB_Target = target; 1218 pScb->SCB_Mode = 0; 1219 1220 pScb->SCB_Srb = NULL; 1221 if (ResetFlags & SCSI_RESET_SYNCHRONOUS) { 1222 pScb->SCB_Srb = pSrb; 1223 } 1224 tul_push_pend_scb(pCurHcb, pScb); /* push this SCB to Pending queue */ 1225 1226 if (pCurHcb->HCS_Semaph == 1) { 1227 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 1228 /* disable Jasmin SCSI Int */ 1229 pCurHcb->HCS_Semaph = 0; 1230 1231 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1232 1233 tulip_main(pCurHcb); 1234 1235 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1236 1237 pCurHcb->HCS_Semaph = 1; 1238 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); 1239 } 1240 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1241 return SCSI_RESET_PENDING; 1242 } 1243 1244 static int tul_reset_scsi_bus(HCS * pCurHcb) 1245 { 1246 ULONG flags; 1247 1248 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1249 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 1250 pCurHcb->HCS_Semaph = 0; 1251 1252 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1253 1254 tul_stop_bm(pCurHcb); 1255 1256 tul_reset_scsi(pCurHcb, 2); /* 7/29/98 */ 1257 1258 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1259 tul_post_scsi_rst(pCurHcb); 1260 1261 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1262 1263 tulip_main(pCurHcb); 1264 1265 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1266 1267 pCurHcb->HCS_Semaph = 1; 1268 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); 1269 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1270 return (SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET); 1271 } 1272 1273 #endif /* 0 */ 1274 1275 /************************************************************************/ 1276 static void tul_exec_scb(HCS * pCurHcb, SCB * pCurScb) 1277 { 1278 ULONG flags; 1279 1280 pCurScb->SCB_Mode = 0; 1281 1282 pCurScb->SCB_SGIdx = 0; 1283 pCurScb->SCB_SGMax = pCurScb->SCB_SGLen; 1284 1285 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1286 1287 tul_append_pend_scb(pCurHcb, pCurScb); /* Append this SCB to Pending queue */ 1288 1289 /* VVVVV 07/21/98 */ 1290 if (pCurHcb->HCS_Semaph == 1) { 1291 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 1292 /* disable Jasmin SCSI Int */ 1293 pCurHcb->HCS_Semaph = 0; 1294 1295 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1296 1297 tulip_main(pCurHcb); 1298 1299 spin_lock_irqsave(&(pCurHcb->HCS_SemaphLock), flags); 1300 1301 pCurHcb->HCS_Semaph = 1; 1302 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); 1303 } 1304 spin_unlock_irqrestore(&(pCurHcb->HCS_SemaphLock), flags); 1305 return; 1306 } 1307 1308 /***************************************************************************/ 1309 static int tul_isr(HCS * pCurHcb) 1310 { 1311 /* Enter critical section */ 1312 1313 if (TUL_RD(pCurHcb->HCS_Base, TUL_Int) & TSS_INT_PENDING) { 1314 if (pCurHcb->HCS_Semaph == 1) { 1315 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x1F); 1316 /* Disable Tulip SCSI Int */ 1317 pCurHcb->HCS_Semaph = 0; 1318 1319 tulip_main(pCurHcb); 1320 1321 pCurHcb->HCS_Semaph = 1; 1322 TUL_WR(pCurHcb->HCS_Base + TUL_Mask, 0x0F); 1323 return (1); 1324 } 1325 } 1326 return (0); 1327 } 1328 1329 /***************************************************************************/ 1330 int tulip_main(HCS * pCurHcb) 1331 { 1332 SCB *pCurScb; 1333 1334 for (;;) { 1335 1336 tulip_scsi(pCurHcb); /* Call tulip_scsi */ 1337 1338 while ((pCurScb = tul_find_done_scb(pCurHcb)) != NULL) { /* find done entry */ 1339 if (pCurScb->SCB_TaStat == INI_QUEUE_FULL) { 1340 pCurHcb->HCS_MaxTags[pCurScb->SCB_Target] = 1341 pCurHcb->HCS_ActTags[pCurScb->SCB_Target] - 1; 1342 pCurScb->SCB_TaStat = 0; 1343 tul_append_pend_scb(pCurHcb, pCurScb); 1344 continue; 1345 } 1346 if (!(pCurScb->SCB_Mode & SCM_RSENS)) { /* not in auto req. sense mode */ 1347 if (pCurScb->SCB_TaStat == 2) { 1348 1349 /* clr sync. nego flag */ 1350 1351 if (pCurScb->SCB_Flags & SCF_SENSE) { 1352 BYTE len; 1353 len = pCurScb->SCB_SenseLen; 1354 if (len == 0) 1355 len = 1; 1356 pCurScb->SCB_BufLen = pCurScb->SCB_SenseLen; 1357 pCurScb->SCB_BufPtr = pCurScb->SCB_SensePtr; 1358 pCurScb->SCB_Flags &= ~(SCF_SG | SCF_DIR); /* for xfer_data_in */ 1359 /* pCurScb->SCB_Flags |= SCF_NO_DCHK; */ 1360 /* so, we won't report worng direction in xfer_data_in, 1361 and won't report HOST_DO_DU in state_6 */ 1362 pCurScb->SCB_Mode = SCM_RSENS; 1363 pCurScb->SCB_Ident &= 0xBF; /* Disable Disconnect */ 1364 pCurScb->SCB_TagMsg = 0; 1365 pCurScb->SCB_TaStat = 0; 1366 pCurScb->SCB_CDBLen = 6; 1367 pCurScb->SCB_CDB[0] = SCSICMD_RequestSense; 1368 pCurScb->SCB_CDB[1] = 0; 1369 pCurScb->SCB_CDB[2] = 0; 1370 pCurScb->SCB_CDB[3] = 0; 1371 pCurScb->SCB_CDB[4] = len; 1372 pCurScb->SCB_CDB[5] = 0; 1373 tul_push_pend_scb(pCurHcb, pCurScb); 1374 break; 1375 } 1376 } 1377 } else { /* in request sense mode */ 1378 1379 if (pCurScb->SCB_TaStat == 2) { /* check contition status again after sending 1380 requset sense cmd 0x3 */ 1381 pCurScb->SCB_HaStat = HOST_BAD_PHAS; 1382 } 1383 pCurScb->SCB_TaStat = 2; 1384 } 1385 pCurScb->SCB_Flags |= SCF_DONE; 1386 if (pCurScb->SCB_Flags & SCF_POST) { 1387 (*pCurScb->SCB_Post) ((BYTE *) pCurHcb, (BYTE *) pCurScb); 1388 } 1389 } /* while */ 1390 1391 /* find_active: */ 1392 if (TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0) & TSS_INT_PENDING) 1393 continue; 1394 1395 if (pCurHcb->HCS_ActScb) { /* return to OS and wait for xfer_done_ISR/Selected_ISR */ 1396 return 1; /* return to OS, enable interrupt */ 1397 } 1398 /* Check pending SCB */ 1399 if (tul_find_first_pend_scb(pCurHcb) == NULL) { 1400 return 1; /* return to OS, enable interrupt */ 1401 } 1402 } /* End of for loop */ 1403 /* statement won't reach here */ 1404 } 1405 1406 1407 1408 1409 /*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */ 1410 /***************************************************************************/ 1411 /***************************************************************************/ 1412 /***************************************************************************/ 1413 /***************************************************************************/ 1414 1415 /***************************************************************************/ 1416 void tulip_scsi(HCS * pCurHcb) 1417 { 1418 SCB *pCurScb; 1419 TCS *pCurTcb; 1420 1421 /* make sure to service interrupt asap */ 1422 1423 if ((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0)) & TSS_INT_PENDING) { 1424 1425 pCurHcb->HCS_Phase = pCurHcb->HCS_JSStatus0 & TSS_PH_MASK; 1426 pCurHcb->HCS_JSStatus1 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1); 1427 pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt); 1428 if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) { /* SCSI bus reset detected */ 1429 int_tul_scsi_rst(pCurHcb); 1430 return; 1431 } 1432 if (pCurHcb->HCS_JSInt & TSS_RESEL_INT) { /* if selected/reselected interrupt */ 1433 if (int_tul_resel(pCurHcb) == 0) 1434 tul_next_state(pCurHcb); 1435 return; 1436 } 1437 if (pCurHcb->HCS_JSInt & TSS_SEL_TIMEOUT) { 1438 int_tul_busfree(pCurHcb); 1439 return; 1440 } 1441 if (pCurHcb->HCS_JSInt & TSS_DISC_INT) { /* BUS disconnection */ 1442 int_tul_busfree(pCurHcb); /* unexpected bus free or sel timeout */ 1443 return; 1444 } 1445 if (pCurHcb->HCS_JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) { /* func complete or Bus service */ 1446 if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) 1447 tul_next_state(pCurHcb); 1448 return; 1449 } 1450 } 1451 if (pCurHcb->HCS_ActScb != NULL) 1452 return; 1453 1454 if ((pCurScb = tul_find_first_pend_scb(pCurHcb)) == NULL) 1455 return; 1456 1457 /* program HBA's SCSI ID & target SCSI ID */ 1458 TUL_WR(pCurHcb->HCS_Base + TUL_SScsiId, 1459 (pCurHcb->HCS_SCSI_ID << 4) | (pCurScb->SCB_Target & 0x0F)); 1460 if (pCurScb->SCB_Opcode == ExecSCSI) { 1461 pCurTcb = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target]; 1462 1463 if (pCurScb->SCB_TagMsg) 1464 pCurTcb->TCS_DrvFlags |= TCF_DRV_EN_TAG; 1465 else 1466 pCurTcb->TCS_DrvFlags &= ~TCF_DRV_EN_TAG; 1467 1468 TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurTcb->TCS_JS_Period); 1469 if ((pCurTcb->TCS_Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) { /* do wdtr negotiation */ 1470 tul_select_atn_stop(pCurHcb, pCurScb); 1471 } else { 1472 if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) { /* do sync negotiation */ 1473 tul_select_atn_stop(pCurHcb, pCurScb); 1474 } else { 1475 if (pCurScb->SCB_TagMsg) 1476 tul_select_atn3(pCurHcb, pCurScb); 1477 else 1478 tul_select_atn(pCurHcb, pCurScb); 1479 } 1480 } 1481 if (pCurScb->SCB_Flags & SCF_POLL) { 1482 while (wait_tulip(pCurHcb) != -1) { 1483 if (tul_next_state(pCurHcb) == -1) 1484 break; 1485 } 1486 } 1487 } else if (pCurScb->SCB_Opcode == BusDevRst) { 1488 tul_select_atn_stop(pCurHcb, pCurScb); 1489 pCurScb->SCB_NxtStat = 8; 1490 if (pCurScb->SCB_Flags & SCF_POLL) { 1491 while (wait_tulip(pCurHcb) != -1) { 1492 if (tul_next_state(pCurHcb) == -1) 1493 break; 1494 } 1495 } 1496 } else if (pCurScb->SCB_Opcode == AbortCmd) { 1497 if (tul_abort_srb(pCurHcb, pCurScb->SCB_Srb) != 0) { 1498 1499 1500 tul_unlink_pend_scb(pCurHcb, pCurScb); 1501 1502 tul_release_scb(pCurHcb, pCurScb); 1503 } else { 1504 pCurScb->SCB_Opcode = BusDevRst; 1505 tul_select_atn_stop(pCurHcb, pCurScb); 1506 pCurScb->SCB_NxtStat = 8; 1507 } 1508 1509 /* 08/03/98 */ 1510 } else { 1511 tul_unlink_pend_scb(pCurHcb, pCurScb); 1512 pCurScb->SCB_HaStat = 0x16; /* bad command */ 1513 tul_append_done_scb(pCurHcb, pCurScb); 1514 } 1515 return; 1516 } 1517 1518 1519 /***************************************************************************/ 1520 int tul_next_state(HCS * pCurHcb) 1521 { 1522 int next; 1523 1524 next = pCurHcb->HCS_ActScb->SCB_NxtStat; 1525 for (;;) { 1526 switch (next) { 1527 case 1: 1528 next = tul_state_1(pCurHcb); 1529 break; 1530 case 2: 1531 next = tul_state_2(pCurHcb); 1532 break; 1533 case 3: 1534 next = tul_state_3(pCurHcb); 1535 break; 1536 case 4: 1537 next = tul_state_4(pCurHcb); 1538 break; 1539 case 5: 1540 next = tul_state_5(pCurHcb); 1541 break; 1542 case 6: 1543 next = tul_state_6(pCurHcb); 1544 break; 1545 case 7: 1546 next = tul_state_7(pCurHcb); 1547 break; 1548 case 8: 1549 return (tul_bus_device_reset(pCurHcb)); 1550 default: 1551 return (tul_bad_seq(pCurHcb)); 1552 } 1553 if (next <= 0) 1554 return next; 1555 } 1556 } 1557 1558 1559 /***************************************************************************/ 1560 /* sTate after selection with attention & stop */ 1561 int tul_state_1(HCS * pCurHcb) 1562 { 1563 SCB *pCurScb = pCurHcb->HCS_ActScb; 1564 TCS *pCurTcb = pCurHcb->HCS_ActTcs; 1565 #if DEBUG_STATE 1566 printk("-s1-"); 1567 #endif 1568 1569 tul_unlink_pend_scb(pCurHcb, pCurScb); 1570 tul_append_busy_scb(pCurHcb, pCurScb); 1571 1572 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0); 1573 /* ATN on */ 1574 if (pCurHcb->HCS_Phase == MSG_OUT) { 1575 1576 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, (TSC_EN_BUS_IN | TSC_HW_RESELECT)); 1577 1578 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident); 1579 1580 if (pCurScb->SCB_TagMsg) { 1581 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagMsg); 1582 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagId); 1583 } 1584 if ((pCurTcb->TCS_Flags & (TCF_WDTR_DONE | TCF_NO_WDTR)) == 0) { 1585 1586 pCurTcb->TCS_Flags |= TCF_WDTR_DONE; 1587 1588 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND); 1589 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 2); /* Extended msg length */ 1590 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); /* Sync request */ 1591 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1); /* Start from 16 bits */ 1592 } else if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) { 1593 1594 pCurTcb->TCS_Flags |= TCF_SYNC_DONE; 1595 1596 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND); 1597 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); /* extended msg length */ 1598 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1); /* sync request */ 1599 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, tul_rate_tbl[pCurTcb->TCS_Flags & TCF_SCSI_RATE]); 1600 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MAX_OFFSET); /* REQ/ACK offset */ 1601 } 1602 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1603 if (wait_tulip(pCurHcb) == -1) 1604 return (-1); 1605 } 1606 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 1607 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7))); 1608 return (3); 1609 } 1610 1611 1612 /***************************************************************************/ 1613 /* state after selection with attention */ 1614 /* state after selection with attention3 */ 1615 int tul_state_2(HCS * pCurHcb) 1616 { 1617 SCB *pCurScb = pCurHcb->HCS_ActScb; 1618 TCS *pCurTcb = pCurHcb->HCS_ActTcs; 1619 #if DEBUG_STATE 1620 printk("-s2-"); 1621 #endif 1622 1623 tul_unlink_pend_scb(pCurHcb, pCurScb); 1624 tul_append_busy_scb(pCurHcb, pCurScb); 1625 1626 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0); 1627 1628 if (pCurHcb->HCS_JSStatus1 & TSS_CMD_PH_CMP) { 1629 return (4); 1630 } 1631 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 1632 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7))); 1633 return (3); 1634 } 1635 1636 /***************************************************************************/ 1637 /* state before CDB xfer is done */ 1638 int tul_state_3(HCS * pCurHcb) 1639 { 1640 SCB *pCurScb = pCurHcb->HCS_ActScb; 1641 TCS *pCurTcb = pCurHcb->HCS_ActTcs; 1642 int i; 1643 1644 #if DEBUG_STATE 1645 printk("-s3-"); 1646 #endif 1647 for (;;) { 1648 switch (pCurHcb->HCS_Phase) { 1649 case CMD_OUT: /* Command out phase */ 1650 for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++) 1651 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]); 1652 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1653 if (wait_tulip(pCurHcb) == -1) 1654 return (-1); 1655 if (pCurHcb->HCS_Phase == CMD_OUT) { 1656 return (tul_bad_seq(pCurHcb)); 1657 } 1658 return (4); 1659 1660 case MSG_IN: /* Message in phase */ 1661 pCurScb->SCB_NxtStat = 3; 1662 if (tul_msgin(pCurHcb) == -1) 1663 return (-1); 1664 break; 1665 1666 case STATUS_IN: /* Status phase */ 1667 if (tul_status_msg(pCurHcb) == -1) 1668 return (-1); 1669 break; 1670 1671 case MSG_OUT: /* Message out phase */ 1672 if (pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) { 1673 1674 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP); /* msg nop */ 1675 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1676 if (wait_tulip(pCurHcb) == -1) 1677 return (-1); 1678 1679 } else { 1680 pCurTcb->TCS_Flags |= TCF_SYNC_DONE; 1681 1682 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND); 1683 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); /* ext. msg len */ 1684 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1); /* sync request */ 1685 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, tul_rate_tbl[pCurTcb->TCS_Flags & TCF_SCSI_RATE]); 1686 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MAX_OFFSET); /* REQ/ACK offset */ 1687 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1688 if (wait_tulip(pCurHcb) == -1) 1689 return (-1); 1690 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 1691 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)); 1692 1693 } 1694 break; 1695 1696 default: 1697 return (tul_bad_seq(pCurHcb)); 1698 } 1699 } 1700 } 1701 1702 1703 /***************************************************************************/ 1704 int tul_state_4(HCS * pCurHcb) 1705 { 1706 SCB *pCurScb = pCurHcb->HCS_ActScb; 1707 1708 #if DEBUG_STATE 1709 printk("-s4-"); 1710 #endif 1711 if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_NO_XF) { 1712 return (6); /* Go to state 6 */ 1713 } 1714 for (;;) { 1715 if (pCurScb->SCB_BufLen == 0) 1716 return (6); /* Go to state 6 */ 1717 1718 switch (pCurHcb->HCS_Phase) { 1719 1720 case STATUS_IN: /* Status phase */ 1721 if ((pCurScb->SCB_Flags & SCF_DIR) != 0) { /* if direction bit set then report data underrun */ 1722 pCurScb->SCB_HaStat = HOST_DO_DU; 1723 } 1724 if ((tul_status_msg(pCurHcb)) == -1) 1725 return (-1); 1726 break; 1727 1728 case MSG_IN: /* Message in phase */ 1729 pCurScb->SCB_NxtStat = 0x4; 1730 if (tul_msgin(pCurHcb) == -1) 1731 return (-1); 1732 break; 1733 1734 case MSG_OUT: /* Message out phase */ 1735 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) { 1736 pCurScb->SCB_BufLen = 0; 1737 pCurScb->SCB_HaStat = HOST_DO_DU; 1738 if (tul_msgout_ide(pCurHcb) == -1) 1739 return (-1); 1740 return (6); /* Go to state 6 */ 1741 } else { 1742 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP); /* msg nop */ 1743 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1744 if (wait_tulip(pCurHcb) == -1) 1745 return (-1); 1746 } 1747 break; 1748 1749 case DATA_IN: /* Data in phase */ 1750 return (tul_xfer_data_in(pCurHcb)); 1751 1752 case DATA_OUT: /* Data out phase */ 1753 return (tul_xfer_data_out(pCurHcb)); 1754 1755 default: 1756 return (tul_bad_seq(pCurHcb)); 1757 } 1758 } 1759 } 1760 1761 1762 /***************************************************************************/ 1763 /* state after dma xfer done or phase change before xfer done */ 1764 int tul_state_5(HCS * pCurHcb) 1765 { 1766 SCB *pCurScb = pCurHcb->HCS_ActScb; 1767 long cnt, xcnt; /* cannot use unsigned !! code: if (xcnt < 0) */ 1768 1769 #if DEBUG_STATE 1770 printk("-s5-"); 1771 #endif 1772 /*------ get remaining count -------*/ 1773 1774 cnt = TUL_RDLONG(pCurHcb->HCS_Base, TUL_SCnt0) & 0x0FFFFFF; 1775 1776 if (TUL_RD(pCurHcb->HCS_Base, TUL_XCmd) & 0x20) { 1777 /* ----------------------- DATA_IN ----------------------------- */ 1778 /* check scsi parity error */ 1779 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) { 1780 pCurScb->SCB_HaStat = HOST_DO_DU; 1781 } 1782 if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) { /* DMA xfer pending, Send STOP */ 1783 /* tell Hardware scsi xfer has been terminated */ 1784 TUL_WR(pCurHcb->HCS_Base + TUL_XCtrl, TUL_RD(pCurHcb->HCS_Base, TUL_XCtrl) | 0x80); 1785 /* wait until DMA xfer not pending */ 1786 while (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND); 1787 } 1788 } else { 1789 /*-------- DATA OUT -----------*/ 1790 if ((TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1) & TSS_XFER_CMP) == 0) { 1791 if (pCurHcb->HCS_ActTcs->TCS_JS_Period & TSC_WIDE_SCSI) 1792 cnt += (TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F) << 1; 1793 else 1794 cnt += (TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F); 1795 } 1796 if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & XPEND) { /* if DMA xfer is pending, abort DMA xfer */ 1797 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT); 1798 /* wait Abort DMA xfer done */ 1799 while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & XABT) == 0); 1800 } 1801 if ((cnt == 1) && (pCurHcb->HCS_Phase == DATA_OUT)) { 1802 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1803 if (wait_tulip(pCurHcb) == -1) { 1804 return (-1); 1805 } 1806 cnt = 0; 1807 } else { 1808 if ((TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1) & TSS_XFER_CMP) == 0) 1809 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 1810 } 1811 } 1812 1813 if (cnt == 0) { 1814 pCurScb->SCB_BufLen = 0; 1815 return (6); /* Go to state 6 */ 1816 } 1817 /* Update active data pointer */ 1818 xcnt = (long) pCurScb->SCB_BufLen - cnt; /* xcnt== bytes already xferred */ 1819 pCurScb->SCB_BufLen = (U32) cnt; /* cnt == bytes left to be xferred */ 1820 if (pCurScb->SCB_Flags & SCF_SG) { 1821 register SG *sgp; 1822 ULONG i; 1823 1824 sgp = &pCurScb->SCB_SGList[pCurScb->SCB_SGIdx]; 1825 for (i = pCurScb->SCB_SGIdx; i < pCurScb->SCB_SGMax; sgp++, i++) { 1826 xcnt -= (long) sgp->SG_Len; 1827 if (xcnt < 0) { /* this sgp xfer half done */ 1828 xcnt += (long) sgp->SG_Len; /* xcnt == bytes xferred in this sgp */ 1829 sgp->SG_Ptr += (U32) xcnt; /* new ptr to be xfer */ 1830 sgp->SG_Len -= (U32) xcnt; /* new len to be xfer */ 1831 pCurScb->SCB_BufPtr += ((U32) (i - pCurScb->SCB_SGIdx) << 3); 1832 /* new SG table ptr */ 1833 pCurScb->SCB_SGLen = (BYTE) (pCurScb->SCB_SGMax - i); 1834 /* new SG table len */ 1835 pCurScb->SCB_SGIdx = (WORD) i; 1836 /* for next disc and come in this loop */ 1837 return (4); /* Go to state 4 */ 1838 } 1839 /* else (xcnt >= 0 , i.e. this sgp already xferred */ 1840 } /* for */ 1841 return (6); /* Go to state 6 */ 1842 } else { 1843 pCurScb->SCB_BufPtr += (U32) xcnt; 1844 } 1845 return (4); /* Go to state 4 */ 1846 } 1847 1848 /***************************************************************************/ 1849 /* state after Data phase */ 1850 int tul_state_6(HCS * pCurHcb) 1851 { 1852 SCB *pCurScb = pCurHcb->HCS_ActScb; 1853 1854 #if DEBUG_STATE 1855 printk("-s6-"); 1856 #endif 1857 for (;;) { 1858 switch (pCurHcb->HCS_Phase) { 1859 case STATUS_IN: /* Status phase */ 1860 if ((tul_status_msg(pCurHcb)) == -1) 1861 return (-1); 1862 break; 1863 1864 case MSG_IN: /* Message in phase */ 1865 pCurScb->SCB_NxtStat = 6; 1866 if ((tul_msgin(pCurHcb)) == -1) 1867 return (-1); 1868 break; 1869 1870 case MSG_OUT: /* Message out phase */ 1871 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP); /* msg nop */ 1872 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 1873 if (wait_tulip(pCurHcb) == -1) 1874 return (-1); 1875 break; 1876 1877 case DATA_IN: /* Data in phase */ 1878 return (tul_xpad_in(pCurHcb)); 1879 1880 case DATA_OUT: /* Data out phase */ 1881 return (tul_xpad_out(pCurHcb)); 1882 1883 default: 1884 return (tul_bad_seq(pCurHcb)); 1885 } 1886 } 1887 } 1888 1889 /***************************************************************************/ 1890 int tul_state_7(HCS * pCurHcb) 1891 { 1892 int cnt, i; 1893 1894 #if DEBUG_STATE 1895 printk("-s7-"); 1896 #endif 1897 /* flush SCSI FIFO */ 1898 cnt = TUL_RD(pCurHcb->HCS_Base, TUL_SFifoCnt) & 0x1F; 1899 if (cnt) { 1900 for (i = 0; i < cnt; i++) 1901 TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); 1902 } 1903 switch (pCurHcb->HCS_Phase) { 1904 case DATA_IN: /* Data in phase */ 1905 case DATA_OUT: /* Data out phase */ 1906 return (tul_bad_seq(pCurHcb)); 1907 default: 1908 return (6); /* Go to state 6 */ 1909 } 1910 } 1911 1912 /***************************************************************************/ 1913 int tul_xfer_data_in(HCS * pCurHcb) 1914 { 1915 SCB *pCurScb = pCurHcb->HCS_ActScb; 1916 1917 if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_DOUT) { 1918 return (6); /* wrong direction */ 1919 } 1920 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, pCurScb->SCB_BufLen); 1921 1922 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_DMA_IN); /* 7/25/95 */ 1923 1924 if (pCurScb->SCB_Flags & SCF_SG) { /* S/G xfer */ 1925 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, ((ULONG) pCurScb->SCB_SGLen) << 3); 1926 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr); 1927 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_SG_IN); 1928 } else { 1929 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, pCurScb->SCB_BufLen); 1930 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr); 1931 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_IN); 1932 } 1933 pCurScb->SCB_NxtStat = 0x5; 1934 return (0); /* return to OS, wait xfer done , let jas_isr come in */ 1935 } 1936 1937 1938 /***************************************************************************/ 1939 int tul_xfer_data_out(HCS * pCurHcb) 1940 { 1941 SCB *pCurScb = pCurHcb->HCS_ActScb; 1942 1943 if ((pCurScb->SCB_Flags & SCF_DIR) == SCF_DIN) { 1944 return (6); /* wrong direction */ 1945 } 1946 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, pCurScb->SCB_BufLen); 1947 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_DMA_OUT); 1948 1949 if (pCurScb->SCB_Flags & SCF_SG) { /* S/G xfer */ 1950 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, ((ULONG) pCurScb->SCB_SGLen) << 3); 1951 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr); 1952 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_SG_OUT); 1953 } else { 1954 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XCntH, pCurScb->SCB_BufLen); 1955 TUL_WRLONG(pCurHcb->HCS_Base + TUL_XAddH, pCurScb->SCB_BufPtr); 1956 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_OUT); 1957 } 1958 1959 pCurScb->SCB_NxtStat = 0x5; 1960 return (0); /* return to OS, wait xfer done , let jas_isr come in */ 1961 } 1962 1963 1964 /***************************************************************************/ 1965 int tul_xpad_in(HCS * pCurHcb) 1966 { 1967 SCB *pCurScb = pCurHcb->HCS_ActScb; 1968 TCS *pCurTcb = pCurHcb->HCS_ActTcs; 1969 1970 if ((pCurScb->SCB_Flags & SCF_DIR) != SCF_NO_DCHK) { 1971 pCurScb->SCB_HaStat = HOST_DO_DU; /* over run */ 1972 } 1973 for (;;) { 1974 if (pCurTcb->TCS_JS_Period & TSC_WIDE_SCSI) 1975 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 2); 1976 else 1977 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 1978 1979 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 1980 if ((wait_tulip(pCurHcb)) == -1) { 1981 return (-1); 1982 } 1983 if (pCurHcb->HCS_Phase != DATA_IN) { 1984 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 1985 return (6); 1986 } 1987 TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); 1988 } 1989 } 1990 1991 int tul_xpad_out(HCS * pCurHcb) 1992 { 1993 SCB *pCurScb = pCurHcb->HCS_ActScb; 1994 TCS *pCurTcb = pCurHcb->HCS_ActTcs; 1995 1996 if ((pCurScb->SCB_Flags & SCF_DIR) != SCF_NO_DCHK) { 1997 pCurScb->SCB_HaStat = HOST_DO_DU; /* over run */ 1998 } 1999 for (;;) { 2000 if (pCurTcb->TCS_JS_Period & TSC_WIDE_SCSI) 2001 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 2); 2002 else 2003 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 2004 2005 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 0); 2006 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2007 if ((wait_tulip(pCurHcb)) == -1) { 2008 return (-1); 2009 } 2010 if (pCurHcb->HCS_Phase != DATA_OUT) { /* Disable wide CPU to allow read 16 bits */ 2011 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); 2012 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 2013 return (6); 2014 } 2015 } 2016 } 2017 2018 2019 /***************************************************************************/ 2020 int tul_status_msg(HCS * pCurHcb) 2021 { /* status & MSG_IN */ 2022 SCB *pCurScb = pCurHcb->HCS_ActScb; 2023 BYTE msg; 2024 2025 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_CMD_COMP); 2026 if ((wait_tulip(pCurHcb)) == -1) { 2027 return (-1); 2028 } 2029 /* get status */ 2030 pCurScb->SCB_TaStat = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); 2031 2032 if (pCurHcb->HCS_Phase == MSG_OUT) { 2033 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) { 2034 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_PARITY); 2035 } else { 2036 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_NOP); 2037 } 2038 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2039 return (wait_tulip(pCurHcb)); 2040 } 2041 if (pCurHcb->HCS_Phase == MSG_IN) { 2042 msg = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); 2043 if (pCurHcb->HCS_JSStatus0 & TSS_PAR_ERROR) { /* Parity error */ 2044 if ((tul_msgin_accept(pCurHcb)) == -1) 2045 return (-1); 2046 if (pCurHcb->HCS_Phase != MSG_OUT) 2047 return (tul_bad_seq(pCurHcb)); 2048 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_PARITY); 2049 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2050 return (wait_tulip(pCurHcb)); 2051 } 2052 if (msg == 0) { /* Command complete */ 2053 2054 if ((pCurScb->SCB_TaStat & 0x18) == 0x10) { /* No link support */ 2055 return (tul_bad_seq(pCurHcb)); 2056 } 2057 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 2058 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT); 2059 return tul_wait_done_disc(pCurHcb); 2060 2061 } 2062 if ((msg == MSG_LINK_COMP) || (msg == MSG_LINK_FLAG)) { 2063 if ((pCurScb->SCB_TaStat & 0x18) == 0x10) 2064 return (tul_msgin_accept(pCurHcb)); 2065 } 2066 } 2067 return (tul_bad_seq(pCurHcb)); 2068 } 2069 2070 2071 /***************************************************************************/ 2072 /* scsi bus free */ 2073 int int_tul_busfree(HCS * pCurHcb) 2074 { 2075 SCB *pCurScb = pCurHcb->HCS_ActScb; 2076 2077 if (pCurScb != NULL) { 2078 if (pCurScb->SCB_Status & SCB_SELECT) { /* selection timeout */ 2079 tul_unlink_pend_scb(pCurHcb, pCurScb); 2080 pCurScb->SCB_HaStat = HOST_SEL_TOUT; 2081 tul_append_done_scb(pCurHcb, pCurScb); 2082 } else { /* Unexpected bus free */ 2083 tul_unlink_busy_scb(pCurHcb, pCurScb); 2084 pCurScb->SCB_HaStat = HOST_BUS_FREE; 2085 tul_append_done_scb(pCurHcb, pCurScb); 2086 } 2087 pCurHcb->HCS_ActScb = NULL; 2088 pCurHcb->HCS_ActTcs = NULL; 2089 } 2090 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */ 2091 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT); 2092 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */ 2093 return (-1); 2094 } 2095 2096 2097 /***************************************************************************/ 2098 /* scsi bus reset */ 2099 static int int_tul_scsi_rst(HCS * pCurHcb) 2100 { 2101 SCB *pCurScb; 2102 int i; 2103 2104 /* if DMA xfer is pending, abort DMA xfer */ 2105 if (TUL_RD(pCurHcb->HCS_Base, TUL_XStatus) & 0x01) { 2106 TUL_WR(pCurHcb->HCS_Base + TUL_XCmd, TAX_X_ABT | TAX_X_CLR_FIFO); 2107 /* wait Abort DMA xfer done */ 2108 while ((TUL_RD(pCurHcb->HCS_Base, TUL_Int) & 0x04) == 0); 2109 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 2110 } 2111 /* Abort all active & disconnected scb */ 2112 while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) { 2113 pCurScb->SCB_HaStat = HOST_BAD_PHAS; 2114 tul_append_done_scb(pCurHcb, pCurScb); 2115 } 2116 pCurHcb->HCS_ActScb = NULL; 2117 pCurHcb->HCS_ActTcs = NULL; 2118 2119 /* clr sync nego. done flag */ 2120 for (i = 0; i < pCurHcb->HCS_MaxTar; i++) { 2121 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE); 2122 } 2123 return (-1); 2124 } 2125 2126 2127 /***************************************************************************/ 2128 /* scsi reselection */ 2129 int int_tul_resel(HCS * pCurHcb) 2130 { 2131 SCB *pCurScb; 2132 TCS *pCurTcb; 2133 BYTE tag, msg = 0; 2134 BYTE tar, lun; 2135 2136 if ((pCurScb = pCurHcb->HCS_ActScb) != NULL) { 2137 if (pCurScb->SCB_Status & SCB_SELECT) { /* if waiting for selection complete */ 2138 pCurScb->SCB_Status &= ~SCB_SELECT; 2139 } 2140 pCurHcb->HCS_ActScb = NULL; 2141 } 2142 /* --------- get target id---------------------- */ 2143 tar = TUL_RD(pCurHcb->HCS_Base, TUL_SBusId); 2144 /* ------ get LUN from Identify message----------- */ 2145 lun = TUL_RD(pCurHcb->HCS_Base, TUL_SIdent) & 0x0F; 2146 /* 07/22/98 from 0x1F -> 0x0F */ 2147 pCurTcb = &pCurHcb->HCS_Tcs[tar]; 2148 pCurHcb->HCS_ActTcs = pCurTcb; 2149 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurTcb->TCS_SConfig0); 2150 TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurTcb->TCS_JS_Period); 2151 2152 2153 /* ------------- tag queueing ? ------------------- */ 2154 if (pCurTcb->TCS_DrvFlags & TCF_DRV_EN_TAG) { 2155 if ((tul_msgin_accept(pCurHcb)) == -1) 2156 return (-1); 2157 if (pCurHcb->HCS_Phase != MSG_IN) 2158 goto no_tag; 2159 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 2160 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 2161 if ((wait_tulip(pCurHcb)) == -1) 2162 return (-1); 2163 msg = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); /* Read Tag Message */ 2164 2165 if ((msg < MSG_STAG) || (msg > MSG_OTAG)) /* Is simple Tag */ 2166 goto no_tag; 2167 2168 if ((tul_msgin_accept(pCurHcb)) == -1) 2169 return (-1); 2170 2171 if (pCurHcb->HCS_Phase != MSG_IN) 2172 goto no_tag; 2173 2174 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 2175 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 2176 if ((wait_tulip(pCurHcb)) == -1) 2177 return (-1); 2178 tag = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); /* Read Tag ID */ 2179 pCurScb = pCurHcb->HCS_Scb + tag; 2180 if ((pCurScb->SCB_Target != tar) || (pCurScb->SCB_Lun != lun)) { 2181 return tul_msgout_abort_tag(pCurHcb); 2182 } 2183 if (pCurScb->SCB_Status != SCB_BUSY) { /* 03/24/95 */ 2184 return tul_msgout_abort_tag(pCurHcb); 2185 } 2186 pCurHcb->HCS_ActScb = pCurScb; 2187 if ((tul_msgin_accept(pCurHcb)) == -1) 2188 return (-1); 2189 } else { /* No tag */ 2190 no_tag: 2191 if ((pCurScb = tul_find_busy_scb(pCurHcb, tar | (lun << 8))) == NULL) { 2192 return tul_msgout_abort_targ(pCurHcb); 2193 } 2194 pCurHcb->HCS_ActScb = pCurScb; 2195 if (!(pCurTcb->TCS_DrvFlags & TCF_DRV_EN_TAG)) { 2196 if ((tul_msgin_accept(pCurHcb)) == -1) 2197 return (-1); 2198 } 2199 } 2200 return 0; 2201 } 2202 2203 2204 /***************************************************************************/ 2205 static int int_tul_bad_seq(HCS * pCurHcb) 2206 { /* target wrong phase */ 2207 SCB *pCurScb; 2208 int i; 2209 2210 tul_reset_scsi(pCurHcb, 10); 2211 2212 while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) { 2213 pCurScb->SCB_HaStat = HOST_BAD_PHAS; 2214 tul_append_done_scb(pCurHcb, pCurScb); 2215 } 2216 for (i = 0; i < pCurHcb->HCS_MaxTar; i++) { 2217 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE); 2218 } 2219 return (-1); 2220 } 2221 2222 2223 /***************************************************************************/ 2224 int tul_msgout_abort_targ(HCS * pCurHcb) 2225 { 2226 2227 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2228 if (tul_msgin_accept(pCurHcb) == -1) 2229 return (-1); 2230 if (pCurHcb->HCS_Phase != MSG_OUT) 2231 return (tul_bad_seq(pCurHcb)); 2232 2233 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_ABORT); 2234 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2235 2236 return tul_wait_disc(pCurHcb); 2237 } 2238 2239 /***************************************************************************/ 2240 int tul_msgout_abort_tag(HCS * pCurHcb) 2241 { 2242 2243 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2244 if (tul_msgin_accept(pCurHcb) == -1) 2245 return (-1); 2246 if (pCurHcb->HCS_Phase != MSG_OUT) 2247 return (tul_bad_seq(pCurHcb)); 2248 2249 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_ABORT_TAG); 2250 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2251 2252 return tul_wait_disc(pCurHcb); 2253 2254 } 2255 2256 /***************************************************************************/ 2257 int tul_msgin(HCS * pCurHcb) 2258 { 2259 TCS *pCurTcb; 2260 2261 for (;;) { 2262 2263 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 2264 2265 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 2266 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 2267 if ((wait_tulip(pCurHcb)) == -1) 2268 return (-1); 2269 2270 switch (TUL_RD(pCurHcb->HCS_Base, TUL_SFifo)) { 2271 case MSG_DISC: /* Disconnect msg */ 2272 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT); 2273 2274 return tul_wait_disc(pCurHcb); 2275 2276 case MSG_SDP: 2277 case MSG_RESTORE: 2278 case MSG_NOP: 2279 tul_msgin_accept(pCurHcb); 2280 break; 2281 2282 case MSG_REJ: /* Clear ATN first */ 2283 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, 2284 (TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7))); 2285 pCurTcb = pCurHcb->HCS_ActTcs; 2286 if ((pCurTcb->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) { /* do sync nego */ 2287 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2288 } 2289 tul_msgin_accept(pCurHcb); 2290 break; 2291 2292 case MSG_EXTEND: /* extended msg */ 2293 tul_msgin_extend(pCurHcb); 2294 break; 2295 2296 case MSG_IGNOREWIDE: 2297 tul_msgin_accept(pCurHcb); 2298 break; 2299 2300 /* get */ 2301 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 2302 if (wait_tulip(pCurHcb) == -1) 2303 return -1; 2304 2305 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 0); /* put pad */ 2306 TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); /* get IGNORE field */ 2307 TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); /* get pad */ 2308 2309 tul_msgin_accept(pCurHcb); 2310 break; 2311 2312 case MSG_COMP: 2313 { 2314 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 2315 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT); 2316 return tul_wait_done_disc(pCurHcb); 2317 } 2318 default: 2319 tul_msgout_reject(pCurHcb); 2320 break; 2321 } 2322 if (pCurHcb->HCS_Phase != MSG_IN) 2323 return (pCurHcb->HCS_Phase); 2324 } 2325 /* statement won't reach here */ 2326 } 2327 2328 2329 2330 2331 /***************************************************************************/ 2332 int tul_msgout_reject(HCS * pCurHcb) 2333 { 2334 2335 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2336 2337 if ((tul_msgin_accept(pCurHcb)) == -1) 2338 return (-1); 2339 2340 if (pCurHcb->HCS_Phase == MSG_OUT) { 2341 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_REJ); /* Msg reject */ 2342 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2343 return (wait_tulip(pCurHcb)); 2344 } 2345 return (pCurHcb->HCS_Phase); 2346 } 2347 2348 2349 2350 /***************************************************************************/ 2351 int tul_msgout_ide(HCS * pCurHcb) 2352 { 2353 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_IDE); /* Initiator Detected Error */ 2354 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2355 return (wait_tulip(pCurHcb)); 2356 } 2357 2358 2359 /***************************************************************************/ 2360 int tul_msgin_extend(HCS * pCurHcb) 2361 { 2362 BYTE len, idx; 2363 2364 if (tul_msgin_accept(pCurHcb) != MSG_IN) 2365 return (pCurHcb->HCS_Phase); 2366 2367 /* Get extended msg length */ 2368 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 2369 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 2370 if (wait_tulip(pCurHcb) == -1) 2371 return (-1); 2372 2373 len = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); 2374 pCurHcb->HCS_Msg[0] = len; 2375 for (idx = 1; len != 0; len--) { 2376 2377 if ((tul_msgin_accept(pCurHcb)) != MSG_IN) 2378 return (pCurHcb->HCS_Phase); 2379 TUL_WRLONG(pCurHcb->HCS_Base + TUL_SCnt0, 1); 2380 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_IN); 2381 if (wait_tulip(pCurHcb) == -1) 2382 return (-1); 2383 pCurHcb->HCS_Msg[idx++] = TUL_RD(pCurHcb->HCS_Base, TUL_SFifo); 2384 } 2385 if (pCurHcb->HCS_Msg[1] == 1) { /* if it's synchronous data transfer request */ 2386 if (pCurHcb->HCS_Msg[0] != 3) /* if length is not right */ 2387 return (tul_msgout_reject(pCurHcb)); 2388 if (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_SYNC_NEGO) { /* Set OFFSET=0 to do async, nego back */ 2389 pCurHcb->HCS_Msg[3] = 0; 2390 } else { 2391 if ((tul_msgin_sync(pCurHcb) == 0) && 2392 (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_SYNC_DONE)) { 2393 tul_sync_done(pCurHcb); 2394 return (tul_msgin_accept(pCurHcb)); 2395 } 2396 } 2397 2398 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2399 if ((tul_msgin_accept(pCurHcb)) != MSG_OUT) 2400 return (pCurHcb->HCS_Phase); 2401 /* sync msg out */ 2402 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); 2403 2404 tul_sync_done(pCurHcb); 2405 2406 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND); 2407 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); 2408 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 1); 2409 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[2]); 2410 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[3]); 2411 2412 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2413 return (wait_tulip(pCurHcb)); 2414 } 2415 if ((pCurHcb->HCS_Msg[0] != 2) || (pCurHcb->HCS_Msg[1] != 3)) 2416 return (tul_msgout_reject(pCurHcb)); 2417 /* if it's WIDE DATA XFER REQ */ 2418 if (pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_WDTR) { 2419 pCurHcb->HCS_Msg[2] = 0; 2420 } else { 2421 if (pCurHcb->HCS_Msg[2] > 2) /* > 32 bits */ 2422 return (tul_msgout_reject(pCurHcb)); 2423 if (pCurHcb->HCS_Msg[2] == 2) { /* == 32 */ 2424 pCurHcb->HCS_Msg[2] = 1; 2425 } else { 2426 if ((pCurHcb->HCS_ActTcs->TCS_Flags & TCF_NO_WDTR) == 0) { 2427 wdtr_done(pCurHcb); 2428 if ((pCurHcb->HCS_ActTcs->TCS_Flags & (TCF_SYNC_DONE | TCF_NO_SYNC_NEGO)) == 0) 2429 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2430 return (tul_msgin_accept(pCurHcb)); 2431 } 2432 } 2433 } 2434 TUL_WR(pCurHcb->HCS_Base + TUL_SSignal, ((TUL_RD(pCurHcb->HCS_Base, TUL_SSignal) & (TSC_SET_ACK | 7)) | TSC_SET_ATN)); 2435 2436 if (tul_msgin_accept(pCurHcb) != MSG_OUT) 2437 return (pCurHcb->HCS_Phase); 2438 /* WDTR msg out */ 2439 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_EXTEND); 2440 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 2); 2441 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, 3); 2442 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurHcb->HCS_Msg[2]); 2443 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2444 return (wait_tulip(pCurHcb)); 2445 } 2446 2447 /***************************************************************************/ 2448 int tul_msgin_sync(HCS * pCurHcb) 2449 { 2450 char default_period; 2451 2452 default_period = tul_rate_tbl[pCurHcb->HCS_ActTcs->TCS_Flags & TCF_SCSI_RATE]; 2453 if (pCurHcb->HCS_Msg[3] > MAX_OFFSET) { 2454 pCurHcb->HCS_Msg[3] = MAX_OFFSET; 2455 if (pCurHcb->HCS_Msg[2] < default_period) { 2456 pCurHcb->HCS_Msg[2] = default_period; 2457 return 1; 2458 } 2459 if (pCurHcb->HCS_Msg[2] >= 59) { /* Change to async */ 2460 pCurHcb->HCS_Msg[3] = 0; 2461 } 2462 return 1; 2463 } 2464 /* offset requests asynchronous transfers ? */ 2465 if (pCurHcb->HCS_Msg[3] == 0) { 2466 return 0; 2467 } 2468 if (pCurHcb->HCS_Msg[2] < default_period) { 2469 pCurHcb->HCS_Msg[2] = default_period; 2470 return 1; 2471 } 2472 if (pCurHcb->HCS_Msg[2] >= 59) { 2473 pCurHcb->HCS_Msg[3] = 0; 2474 return 1; 2475 } 2476 return 0; 2477 } 2478 2479 2480 /***************************************************************************/ 2481 int wdtr_done(HCS * pCurHcb) 2482 { 2483 pCurHcb->HCS_ActTcs->TCS_Flags &= ~TCF_SYNC_DONE; 2484 pCurHcb->HCS_ActTcs->TCS_Flags |= TCF_WDTR_DONE; 2485 2486 pCurHcb->HCS_ActTcs->TCS_JS_Period = 0; 2487 if (pCurHcb->HCS_Msg[2]) { /* if 16 bit */ 2488 pCurHcb->HCS_ActTcs->TCS_JS_Period |= TSC_WIDE_SCSI; 2489 } 2490 pCurHcb->HCS_ActTcs->TCS_SConfig0 &= ~TSC_ALT_PERIOD; 2491 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_ActTcs->TCS_SConfig0); 2492 TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurHcb->HCS_ActTcs->TCS_JS_Period); 2493 2494 return 1; 2495 } 2496 2497 /***************************************************************************/ 2498 int tul_sync_done(HCS * pCurHcb) 2499 { 2500 int i; 2501 2502 pCurHcb->HCS_ActTcs->TCS_Flags |= TCF_SYNC_DONE; 2503 2504 if (pCurHcb->HCS_Msg[3]) { 2505 pCurHcb->HCS_ActTcs->TCS_JS_Period |= pCurHcb->HCS_Msg[3]; 2506 for (i = 0; i < 8; i++) { 2507 if (tul_rate_tbl[i] >= pCurHcb->HCS_Msg[2]) /* pick the big one */ 2508 break; 2509 } 2510 pCurHcb->HCS_ActTcs->TCS_JS_Period |= (i << 4); 2511 pCurHcb->HCS_ActTcs->TCS_SConfig0 |= TSC_ALT_PERIOD; 2512 } 2513 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, pCurHcb->HCS_ActTcs->TCS_SConfig0); 2514 TUL_WR(pCurHcb->HCS_Base + TUL_SPeriod, pCurHcb->HCS_ActTcs->TCS_JS_Period); 2515 2516 return (-1); 2517 } 2518 2519 2520 int tul_post_scsi_rst(HCS * pCurHcb) 2521 { 2522 SCB *pCurScb; 2523 TCS *pCurTcb; 2524 int i; 2525 2526 pCurHcb->HCS_ActScb = NULL; 2527 pCurHcb->HCS_ActTcs = NULL; 2528 pCurHcb->HCS_Flags = 0; 2529 2530 while ((pCurScb = tul_pop_busy_scb(pCurHcb)) != NULL) { 2531 pCurScb->SCB_HaStat = HOST_BAD_PHAS; 2532 tul_append_done_scb(pCurHcb, pCurScb); 2533 } 2534 /* clear sync done flag */ 2535 pCurTcb = &pCurHcb->HCS_Tcs[0]; 2536 for (i = 0; i < pCurHcb->HCS_MaxTar; pCurTcb++, i++) { 2537 pCurTcb->TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE); 2538 /* Initialize the sync. xfer register values to an asyn xfer */ 2539 pCurTcb->TCS_JS_Period = 0; 2540 pCurTcb->TCS_SConfig0 = pCurHcb->HCS_SConf1; 2541 pCurHcb->HCS_ActTags[0] = 0; /* 07/22/98 */ 2542 pCurHcb->HCS_Tcs[i].TCS_Flags &= ~TCF_BUSY; /* 07/22/98 */ 2543 } /* for */ 2544 2545 return (-1); 2546 } 2547 2548 /***************************************************************************/ 2549 void tul_select_atn_stop(HCS * pCurHcb, SCB * pCurScb) 2550 { 2551 pCurScb->SCB_Status |= SCB_SELECT; 2552 pCurScb->SCB_NxtStat = 0x1; 2553 pCurHcb->HCS_ActScb = pCurScb; 2554 pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target]; 2555 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SELATNSTOP); 2556 return; 2557 } 2558 2559 2560 /***************************************************************************/ 2561 void tul_select_atn(HCS * pCurHcb, SCB * pCurScb) 2562 { 2563 int i; 2564 2565 pCurScb->SCB_Status |= SCB_SELECT; 2566 pCurScb->SCB_NxtStat = 0x2; 2567 2568 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident); 2569 for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++) 2570 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]); 2571 pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target]; 2572 pCurHcb->HCS_ActScb = pCurScb; 2573 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SEL_ATN); 2574 return; 2575 } 2576 2577 /***************************************************************************/ 2578 void tul_select_atn3(HCS * pCurHcb, SCB * pCurScb) 2579 { 2580 int i; 2581 2582 pCurScb->SCB_Status |= SCB_SELECT; 2583 pCurScb->SCB_NxtStat = 0x2; 2584 2585 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_Ident); 2586 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagMsg); 2587 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_TagId); 2588 for (i = 0; i < (int) pCurScb->SCB_CDBLen; i++) 2589 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, pCurScb->SCB_CDB[i]); 2590 pCurHcb->HCS_ActTcs = &pCurHcb->HCS_Tcs[pCurScb->SCB_Target]; 2591 pCurHcb->HCS_ActScb = pCurScb; 2592 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_SEL_ATN3); 2593 return; 2594 } 2595 2596 /***************************************************************************/ 2597 /* SCSI Bus Device Reset */ 2598 int tul_bus_device_reset(HCS * pCurHcb) 2599 { 2600 SCB *pCurScb = pCurHcb->HCS_ActScb; 2601 TCS *pCurTcb = pCurHcb->HCS_ActTcs; 2602 SCB *pTmpScb, *pPrevScb; 2603 BYTE tar; 2604 2605 if (pCurHcb->HCS_Phase != MSG_OUT) { 2606 return (int_tul_bad_seq(pCurHcb)); /* Unexpected phase */ 2607 } 2608 tul_unlink_pend_scb(pCurHcb, pCurScb); 2609 tul_release_scb(pCurHcb, pCurScb); 2610 2611 2612 tar = pCurScb->SCB_Target; /* target */ 2613 pCurTcb->TCS_Flags &= ~(TCF_SYNC_DONE | TCF_WDTR_DONE | TCF_BUSY); 2614 /* clr sync. nego & WDTR flags 07/22/98 */ 2615 2616 /* abort all SCB with same target */ 2617 pPrevScb = pTmpScb = pCurHcb->HCS_FirstBusy; /* Check Busy queue */ 2618 while (pTmpScb != NULL) { 2619 2620 if (pTmpScb->SCB_Target == tar) { 2621 /* unlink it */ 2622 if (pTmpScb == pCurHcb->HCS_FirstBusy) { 2623 if ((pCurHcb->HCS_FirstBusy = pTmpScb->SCB_NxtScb) == NULL) 2624 pCurHcb->HCS_LastBusy = NULL; 2625 } else { 2626 pPrevScb->SCB_NxtScb = pTmpScb->SCB_NxtScb; 2627 if (pTmpScb == pCurHcb->HCS_LastBusy) 2628 pCurHcb->HCS_LastBusy = pPrevScb; 2629 } 2630 pTmpScb->SCB_HaStat = HOST_ABORTED; 2631 tul_append_done_scb(pCurHcb, pTmpScb); 2632 } 2633 /* Previous haven't change */ 2634 else { 2635 pPrevScb = pTmpScb; 2636 } 2637 pTmpScb = pTmpScb->SCB_NxtScb; 2638 } 2639 2640 TUL_WR(pCurHcb->HCS_Base + TUL_SFifo, MSG_DEVRST); 2641 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_XF_FIFO_OUT); 2642 2643 return tul_wait_disc(pCurHcb); 2644 2645 } 2646 2647 /***************************************************************************/ 2648 int tul_msgin_accept(HCS * pCurHcb) 2649 { 2650 TUL_WR(pCurHcb->HCS_Base + TUL_SCmd, TSC_MSG_ACCEPT); 2651 return (wait_tulip(pCurHcb)); 2652 } 2653 2654 /***************************************************************************/ 2655 int wait_tulip(HCS * pCurHcb) 2656 { 2657 2658 while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0)) 2659 & TSS_INT_PENDING)); 2660 2661 pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt); 2662 pCurHcb->HCS_Phase = pCurHcb->HCS_JSStatus0 & TSS_PH_MASK; 2663 pCurHcb->HCS_JSStatus1 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus1); 2664 2665 if (pCurHcb->HCS_JSInt & TSS_RESEL_INT) { /* if SCSI bus reset detected */ 2666 return (int_tul_resel(pCurHcb)); 2667 } 2668 if (pCurHcb->HCS_JSInt & TSS_SEL_TIMEOUT) { /* if selected/reselected timeout interrupt */ 2669 return (int_tul_busfree(pCurHcb)); 2670 } 2671 if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) { /* if SCSI bus reset detected */ 2672 return (int_tul_scsi_rst(pCurHcb)); 2673 } 2674 if (pCurHcb->HCS_JSInt & TSS_DISC_INT) { /* BUS disconnection */ 2675 if (pCurHcb->HCS_Flags & HCF_EXPECT_DONE_DISC) { 2676 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */ 2677 tul_unlink_busy_scb(pCurHcb, pCurHcb->HCS_ActScb); 2678 pCurHcb->HCS_ActScb->SCB_HaStat = 0; 2679 tul_append_done_scb(pCurHcb, pCurHcb->HCS_ActScb); 2680 pCurHcb->HCS_ActScb = NULL; 2681 pCurHcb->HCS_ActTcs = NULL; 2682 pCurHcb->HCS_Flags &= ~HCF_EXPECT_DONE_DISC; 2683 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT); 2684 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */ 2685 return (-1); 2686 } 2687 if (pCurHcb->HCS_Flags & HCF_EXPECT_DISC) { 2688 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */ 2689 pCurHcb->HCS_ActScb = NULL; 2690 pCurHcb->HCS_ActTcs = NULL; 2691 pCurHcb->HCS_Flags &= ~HCF_EXPECT_DISC; 2692 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT); 2693 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */ 2694 return (-1); 2695 } 2696 return (int_tul_busfree(pCurHcb)); 2697 } 2698 if (pCurHcb->HCS_JSInt & (TSS_FUNC_COMP | TSS_BUS_SERV)) { 2699 return (pCurHcb->HCS_Phase); 2700 } 2701 return (pCurHcb->HCS_Phase); 2702 } 2703 /***************************************************************************/ 2704 int tul_wait_disc(HCS * pCurHcb) 2705 { 2706 2707 while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0)) 2708 & TSS_INT_PENDING)); 2709 2710 2711 pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt); 2712 2713 if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) { /* if SCSI bus reset detected */ 2714 return (int_tul_scsi_rst(pCurHcb)); 2715 } 2716 if (pCurHcb->HCS_JSInt & TSS_DISC_INT) { /* BUS disconnection */ 2717 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */ 2718 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT); 2719 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */ 2720 pCurHcb->HCS_ActScb = NULL; 2721 return (-1); 2722 } 2723 return (tul_bad_seq(pCurHcb)); 2724 } 2725 2726 /***************************************************************************/ 2727 int tul_wait_done_disc(HCS * pCurHcb) 2728 { 2729 2730 2731 while (!((pCurHcb->HCS_JSStatus0 = TUL_RD(pCurHcb->HCS_Base, TUL_SStatus0)) 2732 & TSS_INT_PENDING)); 2733 2734 pCurHcb->HCS_JSInt = TUL_RD(pCurHcb->HCS_Base, TUL_SInt); 2735 2736 2737 if (pCurHcb->HCS_JSInt & TSS_SCSIRST_INT) { /* if SCSI bus reset detected */ 2738 return (int_tul_scsi_rst(pCurHcb)); 2739 } 2740 if (pCurHcb->HCS_JSInt & TSS_DISC_INT) { /* BUS disconnection */ 2741 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl0, TSC_FLUSH_FIFO); /* Flush SCSI FIFO */ 2742 TUL_WR(pCurHcb->HCS_Base + TUL_SConfig, TSC_INITDEFAULT); 2743 TUL_WR(pCurHcb->HCS_Base + TUL_SCtrl1, TSC_HW_RESELECT); /* Enable HW reselect */ 2744 tul_unlink_busy_scb(pCurHcb, pCurHcb->HCS_ActScb); 2745 2746 tul_append_done_scb(pCurHcb, pCurHcb->HCS_ActScb); 2747 pCurHcb->HCS_ActScb = NULL; 2748 return (-1); 2749 } 2750 return (tul_bad_seq(pCurHcb)); 2751 } 2752 2753 static irqreturn_t i91u_intr(int irqno, void *dev_id, struct pt_regs *regs) 2754 { 2755 struct Scsi_Host *dev = dev_id; 2756 unsigned long flags; 2757 2758 spin_lock_irqsave(dev->host_lock, flags); 2759 tul_isr((HCS *)dev->base); 2760 spin_unlock_irqrestore(dev->host_lock, flags); 2761 return IRQ_HANDLED; 2762 } 2763 2764 static int tul_NewReturnNumberOfAdapters(void) 2765 { 2766 struct pci_dev *pDev = NULL; /* Start from none */ 2767 int iAdapters = 0; 2768 long dRegValue; 2769 WORD wBIOS; 2770 int i = 0; 2771 2772 init_i91uAdapter_table(); 2773 2774 for (i = 0; i < TULSZ(i91u_pci_devices); i++) 2775 { 2776 while ((pDev = pci_find_device(i91u_pci_devices[i].vendor_id, i91u_pci_devices[i].device_id, pDev)) != NULL) { 2777 if (pci_enable_device(pDev)) 2778 continue; 2779 pci_read_config_dword(pDev, 0x44, (u32 *) & dRegValue); 2780 wBIOS = (UWORD) (dRegValue & 0xFF); 2781 if (((dRegValue & 0xFF00) >> 8) == 0xFF) 2782 dRegValue = 0; 2783 wBIOS = (wBIOS << 8) + ((UWORD) ((dRegValue & 0xFF00) >> 8)); 2784 if (pci_set_dma_mask(pDev, DMA_32BIT_MASK)) { 2785 printk(KERN_WARNING 2786 "i91u: Could not set 32 bit DMA mask\n"); 2787 continue; 2788 } 2789 2790 if (Addi91u_into_Adapter_table(wBIOS, 2791 (pDev->resource[0].start), 2792 pDev->irq, 2793 pDev->bus->number, 2794 (pDev->devfn >> 3) 2795 ) == 0) 2796 iAdapters++; 2797 } 2798 } 2799 2800 return (iAdapters); 2801 } 2802 2803 static int i91u_detect(struct scsi_host_template * tpnt) 2804 { 2805 HCS *pHCB; 2806 struct Scsi_Host *hreg; 2807 unsigned long i; /* 01/14/98 */ 2808 int ok = 0, iAdapters; 2809 ULONG dBiosAdr; 2810 BYTE *pbBiosAdr; 2811 2812 /* Get total number of adapters in the motherboard */ 2813 iAdapters = tul_NewReturnNumberOfAdapters(); 2814 if (iAdapters == 0) /* If no tulip founded, return */ 2815 return (0); 2816 2817 tul_num_ch = (iAdapters > tul_num_ch) ? tul_num_ch : iAdapters; 2818 /* Update actually channel number */ 2819 if (tul_tag_enable) { /* 1.01i */ 2820 tul_num_scb = MAX_TARGETS * i91u_MAXQUEUE; 2821 } else { 2822 tul_num_scb = MAX_TARGETS + 3; /* 1-tape, 1-CD_ROM, 1- extra */ 2823 } /* Update actually SCBs per adapter */ 2824 2825 /* Get total memory needed for HCS */ 2826 i = tul_num_ch * sizeof(HCS); 2827 memset((unsigned char *) &tul_hcs[0], 0, i); /* Initialize tul_hcs 0 */ 2828 /* Get total memory needed for SCB */ 2829 2830 for (; tul_num_scb >= MAX_TARGETS + 3; tul_num_scb--) { 2831 i = tul_num_ch * tul_num_scb * sizeof(SCB); 2832 if ((tul_scb = (SCB *) kmalloc(i, GFP_ATOMIC | GFP_DMA)) != NULL) 2833 break; 2834 } 2835 if (tul_scb == NULL) { 2836 printk("i91u: SCB memory allocation error\n"); 2837 return (0); 2838 } 2839 memset((unsigned char *) tul_scb, 0, i); 2840 2841 for (i = 0, pHCB = &tul_hcs[0]; /* Get pointer for control block */ 2842 i < tul_num_ch; 2843 i++, pHCB++) { 2844 get_tulipPCIConfig(pHCB, i); 2845 2846 dBiosAdr = pHCB->HCS_BIOS; 2847 dBiosAdr = (dBiosAdr << 4); 2848 2849 pbBiosAdr = phys_to_virt(dBiosAdr); 2850 2851 init_tulip(pHCB, tul_scb + (i * tul_num_scb), tul_num_scb, pbBiosAdr, 10); 2852 request_region(pHCB->HCS_Base, 256, "i91u"); /* Register */ 2853 2854 pHCB->HCS_Index = i; /* 7/29/98 */ 2855 hreg = scsi_register(tpnt, sizeof(HCS)); 2856 if(hreg == NULL) { 2857 release_region(pHCB->HCS_Base, 256); 2858 return 0; 2859 } 2860 hreg->io_port = pHCB->HCS_Base; 2861 hreg->n_io_port = 0xff; 2862 hreg->can_queue = tul_num_scb; /* 03/05/98 */ 2863 hreg->unique_id = pHCB->HCS_Base; 2864 hreg->max_id = pHCB->HCS_MaxTar; 2865 hreg->max_lun = 32; /* 10/21/97 */ 2866 hreg->irq = pHCB->HCS_Intr; 2867 hreg->this_id = pHCB->HCS_SCSI_ID; /* Assign HCS index */ 2868 hreg->base = (unsigned long)pHCB; 2869 hreg->sg_tablesize = TOTAL_SG_ENTRY; /* Maximun support is 32 */ 2870 2871 /* Initial tulip chip */ 2872 ok = request_irq(pHCB->HCS_Intr, i91u_intr, SA_INTERRUPT | SA_SHIRQ, "i91u", hreg); 2873 if (ok < 0) { 2874 printk(KERN_WARNING "i91u: unable to request IRQ %d\n\n", pHCB->HCS_Intr); 2875 return 0; 2876 } 2877 } 2878 2879 tpnt->this_id = -1; 2880 tpnt->can_queue = 1; 2881 2882 return 1; 2883 } 2884 2885 static void i91uBuildSCB(HCS * pHCB, SCB * pSCB, struct scsi_cmnd * SCpnt) 2886 { /* Create corresponding SCB */ 2887 struct scatterlist *pSrbSG; 2888 SG *pSG; /* Pointer to SG list */ 2889 int i; 2890 long TotalLen; 2891 dma_addr_t dma_addr; 2892 2893 pSCB->SCB_Post = i91uSCBPost; /* i91u's callback routine */ 2894 pSCB->SCB_Srb = SCpnt; 2895 pSCB->SCB_Opcode = ExecSCSI; 2896 pSCB->SCB_Flags = SCF_POST; /* After SCSI done, call post routine */ 2897 pSCB->SCB_Target = SCpnt->device->id; 2898 pSCB->SCB_Lun = SCpnt->device->lun; 2899 pSCB->SCB_Ident = SCpnt->device->lun | DISC_ALLOW; 2900 2901 pSCB->SCB_Flags |= SCF_SENSE; /* Turn on auto request sense */ 2902 dma_addr = dma_map_single(&pHCB->pci_dev->dev, SCpnt->sense_buffer, 2903 SENSE_SIZE, DMA_FROM_DEVICE); 2904 pSCB->SCB_SensePtr = cpu_to_le32((u32)dma_addr); 2905 pSCB->SCB_SenseLen = cpu_to_le32(SENSE_SIZE); 2906 SCpnt->SCp.ptr = (char *)(unsigned long)dma_addr; 2907 2908 pSCB->SCB_CDBLen = SCpnt->cmd_len; 2909 pSCB->SCB_HaStat = 0; 2910 pSCB->SCB_TaStat = 0; 2911 memcpy(&pSCB->SCB_CDB[0], &SCpnt->cmnd, SCpnt->cmd_len); 2912 2913 if (SCpnt->device->tagged_supported) { /* Tag Support */ 2914 pSCB->SCB_TagMsg = SIMPLE_QUEUE_TAG; /* Do simple tag only */ 2915 } else { 2916 pSCB->SCB_TagMsg = 0; /* No tag support */ 2917 } 2918 /* todo handle map_sg error */ 2919 if (SCpnt->use_sg) { 2920 dma_addr = dma_map_single(&pHCB->pci_dev->dev, &pSCB->SCB_SGList[0], 2921 sizeof(struct SG_Struc) * TOTAL_SG_ENTRY, 2922 DMA_BIDIRECTIONAL); 2923 pSCB->SCB_BufPtr = cpu_to_le32((u32)dma_addr); 2924 SCpnt->SCp.dma_handle = dma_addr; 2925 2926 pSrbSG = (struct scatterlist *) SCpnt->request_buffer; 2927 pSCB->SCB_SGLen = dma_map_sg(&pHCB->pci_dev->dev, pSrbSG, 2928 SCpnt->use_sg, SCpnt->sc_data_direction); 2929 2930 pSCB->SCB_Flags |= SCF_SG; /* Turn on SG list flag */ 2931 for (i = 0, TotalLen = 0, pSG = &pSCB->SCB_SGList[0]; /* 1.01g */ 2932 i < pSCB->SCB_SGLen; i++, pSG++, pSrbSG++) { 2933 pSG->SG_Ptr = cpu_to_le32((u32)sg_dma_address(pSrbSG)); 2934 TotalLen += pSG->SG_Len = cpu_to_le32((u32)sg_dma_len(pSrbSG)); 2935 } 2936 2937 pSCB->SCB_BufLen = (SCpnt->request_bufflen > TotalLen) ? 2938 TotalLen : SCpnt->request_bufflen; 2939 } else if (SCpnt->request_bufflen) { /* Non SG */ 2940 dma_addr = dma_map_single(&pHCB->pci_dev->dev, SCpnt->request_buffer, 2941 SCpnt->request_bufflen, 2942 SCpnt->sc_data_direction); 2943 SCpnt->SCp.dma_handle = dma_addr; 2944 pSCB->SCB_BufPtr = cpu_to_le32((u32)dma_addr); 2945 pSCB->SCB_BufLen = cpu_to_le32((u32)SCpnt->request_bufflen); 2946 pSCB->SCB_SGLen = 0; 2947 } else { 2948 pSCB->SCB_BufLen = 0; 2949 pSCB->SCB_SGLen = 0; 2950 } 2951 } 2952 2953 static int i91u_queuecommand(struct scsi_cmnd *cmd, 2954 void (*done)(struct scsi_cmnd *)) 2955 { 2956 HCS *pHCB = (HCS *) cmd->device->host->base; 2957 register SCB *pSCB; 2958 2959 cmd->scsi_done = done; 2960 2961 pSCB = tul_alloc_scb(pHCB); 2962 if (!pSCB) 2963 return SCSI_MLQUEUE_HOST_BUSY; 2964 2965 i91uBuildSCB(pHCB, pSCB, cmd); 2966 tul_exec_scb(pHCB, pSCB); 2967 return 0; 2968 } 2969 2970 #if 0 /* no new EH yet */ 2971 /* 2972 * Abort a queued command 2973 * (commands that are on the bus can't be aborted easily) 2974 */ 2975 static int i91u_abort(struct scsi_cmnd * SCpnt) 2976 { 2977 HCS *pHCB; 2978 2979 pHCB = (HCS *) SCpnt->device->host->base; 2980 return tul_abort_srb(pHCB, SCpnt); 2981 } 2982 2983 /* 2984 * Reset registers, reset a hanging bus and 2985 * kill active and disconnected commands for target w/o soft reset 2986 */ 2987 static int i91u_reset(struct scsi_cmnd * SCpnt, unsigned int reset_flags) 2988 { /* I need Host Control Block Information */ 2989 HCS *pHCB; 2990 2991 pHCB = (HCS *) SCpnt->device->host->base; 2992 2993 if (reset_flags & (SCSI_RESET_SUGGEST_BUS_RESET | SCSI_RESET_SUGGEST_HOST_RESET)) 2994 return tul_reset_scsi_bus(pHCB); 2995 else 2996 return tul_device_reset(pHCB, SCpnt, SCpnt->device->id, reset_flags); 2997 } 2998 #endif 2999 3000 static int i91u_bus_reset(struct scsi_cmnd * SCpnt) 3001 { 3002 HCS *pHCB; 3003 3004 pHCB = (HCS *) SCpnt->device->host->base; 3005 3006 spin_lock_irq(SCpnt->device->host->host_lock); 3007 tul_reset_scsi(pHCB, 0); 3008 spin_unlock_irq(SCpnt->device->host->host_lock); 3009 3010 return SUCCESS; 3011 } 3012 3013 /* 3014 * Return the "logical geometry" 3015 */ 3016 static int i91u_biosparam(struct scsi_device *sdev, struct block_device *dev, 3017 sector_t capacity, int *info_array) 3018 { 3019 HCS *pHcb; /* Point to Host adapter control block */ 3020 TCS *pTcb; 3021 3022 pHcb = (HCS *) sdev->host->base; 3023 pTcb = &pHcb->HCS_Tcs[sdev->id]; 3024 3025 if (pTcb->TCS_DrvHead) { 3026 info_array[0] = pTcb->TCS_DrvHead; 3027 info_array[1] = pTcb->TCS_DrvSector; 3028 info_array[2] = (unsigned long)capacity / pTcb->TCS_DrvHead / pTcb->TCS_DrvSector; 3029 } else { 3030 if (pTcb->TCS_DrvFlags & TCF_DRV_255_63) { 3031 info_array[0] = 255; 3032 info_array[1] = 63; 3033 info_array[2] = (unsigned long)capacity / 255 / 63; 3034 } else { 3035 info_array[0] = 64; 3036 info_array[1] = 32; 3037 info_array[2] = (unsigned long)capacity >> 11; 3038 } 3039 } 3040 3041 #if defined(DEBUG_BIOSPARAM) 3042 if (i91u_debug & debug_biosparam) { 3043 printk("bios geometry: head=%d, sec=%d, cyl=%d\n", 3044 info_array[0], info_array[1], info_array[2]); 3045 printk("WARNING: check, if the bios geometry is correct.\n"); 3046 } 3047 #endif 3048 3049 return 0; 3050 } 3051 3052 static void i91u_unmap_cmnd(struct pci_dev *pci_dev, struct scsi_cmnd *cmnd) 3053 { 3054 /* auto sense buffer */ 3055 if (cmnd->SCp.ptr) { 3056 dma_unmap_single(&pci_dev->dev, 3057 (dma_addr_t)((unsigned long)cmnd->SCp.ptr), 3058 SENSE_SIZE, DMA_FROM_DEVICE); 3059 cmnd->SCp.ptr = NULL; 3060 } 3061 3062 /* request buffer */ 3063 if (cmnd->use_sg) { 3064 dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle, 3065 sizeof(struct SG_Struc) * TOTAL_SG_ENTRY, 3066 DMA_BIDIRECTIONAL); 3067 3068 dma_unmap_sg(&pci_dev->dev, cmnd->request_buffer, 3069 cmnd->use_sg, 3070 cmnd->sc_data_direction); 3071 } else if (cmnd->request_bufflen) { 3072 dma_unmap_single(&pci_dev->dev, cmnd->SCp.dma_handle, 3073 cmnd->request_bufflen, 3074 cmnd->sc_data_direction); 3075 } 3076 } 3077 3078 /***************************************************************************** 3079 Function name : i91uSCBPost 3080 Description : This is callback routine be called when tulip finish one 3081 SCSI command. 3082 Input : pHCB - Pointer to host adapter control block. 3083 pSCB - Pointer to SCSI control block. 3084 Output : None. 3085 Return : None. 3086 *****************************************************************************/ 3087 static void i91uSCBPost(BYTE * pHcb, BYTE * pScb) 3088 { 3089 struct scsi_cmnd *pSRB; /* Pointer to SCSI request block */ 3090 HCS *pHCB; 3091 SCB *pSCB; 3092 3093 pHCB = (HCS *) pHcb; 3094 pSCB = (SCB *) pScb; 3095 if ((pSRB = pSCB->SCB_Srb) == 0) { 3096 printk("i91uSCBPost: SRB pointer is empty\n"); 3097 3098 tul_release_scb(pHCB, pSCB); /* Release SCB for current channel */ 3099 return; 3100 } 3101 switch (pSCB->SCB_HaStat) { 3102 case 0x0: 3103 case 0xa: /* Linked command complete without error and linked normally */ 3104 case 0xb: /* Linked command complete without error interrupt generated */ 3105 pSCB->SCB_HaStat = 0; 3106 break; 3107 3108 case 0x11: /* Selection time out-The initiator selection or target 3109 reselection was not complete within the SCSI Time out period */ 3110 pSCB->SCB_HaStat = DID_TIME_OUT; 3111 break; 3112 3113 case 0x14: /* Target bus phase sequence failure-An invalid bus phase or bus 3114 phase sequence was requested by the target. The host adapter 3115 will generate a SCSI Reset Condition, notifying the host with 3116 a SCRD interrupt */ 3117 pSCB->SCB_HaStat = DID_RESET; 3118 break; 3119 3120 case 0x1a: /* SCB Aborted. 07/21/98 */ 3121 pSCB->SCB_HaStat = DID_ABORT; 3122 break; 3123 3124 case 0x12: /* Data overrun/underrun-The target attempted to transfer more data 3125 than was allocated by the Data Length field or the sum of the 3126 Scatter / Gather Data Length fields. */ 3127 case 0x13: /* Unexpected bus free-The target dropped the SCSI BSY at an unexpected time. */ 3128 case 0x16: /* Invalid SCB Operation Code. */ 3129 3130 default: 3131 printk("ini9100u: %x %x\n", pSCB->SCB_HaStat, pSCB->SCB_TaStat); 3132 pSCB->SCB_HaStat = DID_ERROR; /* Couldn't find any better */ 3133 break; 3134 } 3135 3136 pSRB->result = pSCB->SCB_TaStat | (pSCB->SCB_HaStat << 16); 3137 3138 if (pSRB == NULL) { 3139 printk("pSRB is NULL\n"); 3140 } 3141 3142 i91u_unmap_cmnd(pHCB->pci_dev, pSRB); 3143 pSRB->scsi_done(pSRB); /* Notify system DONE */ 3144 3145 tul_release_scb(pHCB, pSCB); /* Release SCB for current channel */ 3146 } 3147 3148 /* 3149 * Release ressources 3150 */ 3151 static int i91u_release(struct Scsi_Host *hreg) 3152 { 3153 free_irq(hreg->irq, hreg); 3154 release_region(hreg->io_port, 256); 3155 return 0; 3156 } 3157 MODULE_LICENSE("Dual BSD/GPL"); 3158 3159 static struct scsi_host_template driver_template = { 3160 .proc_name = "INI9100U", 3161 .name = i91u_REVID, 3162 .detect = i91u_detect, 3163 .release = i91u_release, 3164 .queuecommand = i91u_queuecommand, 3165 // .abort = i91u_abort, 3166 // .reset = i91u_reset, 3167 .eh_bus_reset_handler = i91u_bus_reset, 3168 .bios_param = i91u_biosparam, 3169 .can_queue = 1, 3170 .this_id = 1, 3171 .sg_tablesize = SG_ALL, 3172 .cmd_per_lun = 1, 3173 .use_clustering = ENABLE_CLUSTERING, 3174 }; 3175 #include "scsi_module.c" 3176 3177