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