1/* 2 * sim710.c - Copyright (C) 1999 Richard Hirst <richard@sleepie.demon.co.uk> 3 * 4 *---------------------------------------------------------------------------- 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 *---------------------------------------------------------------------------- 19 * 20 * MCA card detection code by Trent McNair. 21 * Fixes to not explicitly nul bss data from Xavier Bestel. 22 * Some multiboard fixes from Rolf Eike Beer. 23 * Auto probing of EISA config space from Trevor Hemsley. 24 * 25 * Various bits of code in this driver have been copied from 53c7,8xx,c, 26 * which is coyright Drew Eckhardt. The scripts for the SCSI chip are 27 * compiled with the script compiler written by Drew. 28 * 29 * This is a simple driver for the NCR53c710. More complex drivers 30 * for this chip (e.g. 53c7xx.c) require that the scsi chip be able to 31 * do DMA block moves between memory and on-chip registers, which can 32 * be a problem if those registers are in the I/O address space. There 33 * can also be problems on hardware where the registers are memory 34 * mapped, if the design is such that memory-to-memory transfers initiated 35 * by the scsi chip cannot access the chip registers. 36 * 37 * This driver is designed to avoid these problems and is intended to 38 * work with any Intel machines using 53c710 chips, including various 39 * Compaq and NCR machines. It was initially written for the Tadpole 40 * TP34V VME board which is 68030 based. 41 * 42 * The driver supports boot-time parameters similar to 43 * sim710=addr:0x9000,irq:15 44 * and insmod parameters similar to 45 * sim710="addr:0x9000 irq:15" 46 * 47 * Multiple controllers can also be set up by command line, provided the 48 * addr: parameter is specified first for each controller. e.g. 49 * sim710="addr:0x9000 irq:15 addr:0x8000 irq:14" 50 * 51 * To seperate the different options, ' ', '+', and ',' can be used, except 52 * that ',' can not be used in module parameters. ' ' can be a pain, because 53 * it needs to be quoted, which causes problems with some installers. 54 * The command line above is completely equivalent to 55 * sim710="addr:0x9000+irq:15+addr:0x8000+irq:14" 56 * 57 * The complete list of options are: 58 * 59 * addr:0x9000 Specifies the base I/O port (or address) of the 53C710. 60 * irq:15 Specifies the IRQ number used by the 53c710. 61 * debug:0xffff Generates lots of debug output. 62 * ignore:0x0a Makes the driver ignore SCSI IDs 0 and 2. 63 * nodisc:0x70 Prevents disconnects from IDs 6, 5 and 4. 64 * noneg:0x10 Prevents SDTR negotiation on ID 4. 65 * disabled:1 Completely disables the driver. When present, overrides 66 * all other options. 67 * 68 * The driver will auto-probe chip addresses and IRQs now, so typically no 69 * parameters are needed. Auto-probing of addresses is disabled if any addr: 70 * parameters are specified. 71 * 72 * Current limitations: 73 * 74 * o Async only 75 * o Severely lacking in error recovery 76 * o 'debug:' should be per host really. 77 * 78 */ 79 80#include <linux/config.h> 81#include <linux/module.h> 82 83#include <linux/version.h> 84#include <linux/kernel.h> 85#include <linux/types.h> 86#include <linux/string.h> 87#include <linux/ioport.h> 88#include <linux/delay.h> 89#include <linux/sched.h> 90#include <linux/proc_fs.h> 91#include <linux/init.h> 92#include <linux/mca.h> 93#include <linux/interrupt.h> 94#include <asm/dma.h> 95#include <asm/system.h> 96#include <linux/spinlock.h> 97#include <asm/io.h> 98#include <asm/pgtable.h> 99#include <asm/byteorder.h> 100#include <linux/blk.h> 101 102/* All targets are I/O mapped at the moment */ 103#define IO_MAPPED 104 105#if defined(CONFIG_MCA) 106 107/* 108 * For each known microchannel card using the 53c710 we need a list 109 * of possible IRQ and IO settings, as well as their corresponding 110 * bit assignment in pos[]. This might get cumbersome if there 111 * are more than a few cards (I only know of 2 at this point). 112 */ 113 114#define MCA_53C710_IDS { 0x01bb, 0x01ba, 0x004f } 115 116/* CARD ID 01BB and 01BA use the same pos values */ 117 118#define MCA_01BB_IO_PORTS { 0x0000, 0x0000, 0x0800, 0x0C00, 0x1000, 0x1400, \ 119 0x1800, 0x1C00, 0x2000, 0x2400, 0x2800, \ 120 0x2C00, 0x3000, 0x3400, 0x3800, 0x3C00, \ 121 0x4000, 0x4400, 0x4800, 0x4C00, 0x5000 } 122 123#define MCA_01BB_IRQS { 3, 5, 11, 14 } 124 125/* CARD ID 004f */ 126 127#define MCA_004F_IO_PORTS { 0x0000, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600 } 128 129#define MCA_004F_IRQS { 5, 9, 14 } 130 131#endif 132 133#include "scsi.h" 134#include "hosts.h" 135#include "sim710.h" 136 137#include<linux/stat.h> 138 139#define DEBUG 140#undef DEBUG_LIMIT_INTS /* Define to 10 to hang driver after 10 ints */ 141 142/* Debug options available via the "debug:0x1234" parameter */ 143 144#define DEB_NONE 0x0000 /* Nothing */ 145#define DEB_HALT 0x0001 /* Detailed trace of chip halt funtion */ 146#define DEB_REGS 0x0002 /* All chip register read/writes */ 147#define DEB_SYNC 0x0004 /* Sync/async negotiation */ 148#define DEB_PMM 0x0008 /* Phase mis-match handling */ 149#define DEB_INTS 0x0010 /* General interrupt trace */ 150#define DEB_TOUT 0x0020 /* Selection timeouts */ 151#define DEB_RESUME 0x0040 /* Resume addresses for the script */ 152#define DEB_CMND 0x0080 /* Commands and status returned */ 153#define DEB_FIXUP 0x0100 /* Fixup of scsi addresses */ 154#define DEB_DISC 0x0200 /* Disconnect/reselect handling */ 155 156#define DEB_ANY 0xffff /* Any and all debug options */ 157 158#ifdef DEBUG 159#define DEB(m,x) if (sim710_debug & m) x 160int sim710_debug; 161#else 162#define DEB(m,x) 163#endif 164 165/* Redefine scsi_done to force renegotiation of (a)sync transfers 166 * following any failed command. 167 */ 168 169#define SCSI_DONE(cmd) { \ 170 DEB(DEB_CMND, printk("scsi%d: Complete %08x\n", \ 171 host->host_no, cmd->result)); \ 172 if (cmd->result) \ 173 hostdata->negotiate |= (1 << cmd->target); \ 174 cmd->scsi_done(cmd); \ 175 } 176 177#ifndef offsetof 178#define offsetof(t, m) ((size_t) (&((t *)0)->m)) 179#endif 180 181#define STATE_INITIALISED 0 182#define STATE_HALTED 1 183#define STATE_IDLE 2 184#define STATE_BUSY 3 185#define STATE_DISABLED 4 186 187#define MAXBOARDS 4 /* Increase this and the sizes of the 188 arrays below, if you need more.. */ 189 190#ifdef MODULE 191 192char *sim710; /* command line passed by insmod */ 193 194MODULE_AUTHOR("Richard Hirst"); 195MODULE_DESCRIPTION("Simple NCR53C710 driver"); 196MODULE_LICENSE("GPL"); 197 198MODULE_PARM(sim710, "s"); 199 200#endif 201 202static int sim710_errors; /* Count of error interrupts */ 203static int sim710_intrs; /* Count of all interrupts */ 204static int ignore_ids[MAXBOARDS]; /* Accept all SCSI IDs */ 205static int opt_nodisc[MAXBOARDS]; /* Allow disconnect on all IDs */ 206static int opt_noneg[MAXBOARDS]; /* Allow SDTR negotiation on all IDs */ 207static int hostdata_order; /* Encoded size of hostdata for free_pages() */ 208static int no_of_boards; /* Actual number of boards/chips */ 209static unsigned int bases[MAXBOARDS]; /* Base addresses of chips */ 210static unsigned int irq_vectors[MAXBOARDS]; /* IRQ vectors used by chips */ 211 212/* The SCSI Script!!! */ 213 214#include "sim710_d.h" 215 216/* Now define offsets in the DSA, as (A_dsa_xxx/4) */ 217 218#define DSA_SELECT (A_dsa_select/4) 219#define DSA_MSGOUT (A_dsa_msgout/4) 220#define DSA_CMND (A_dsa_cmnd/4) 221#define DSA_STATUS (A_dsa_status/4) 222#define DSA_MSGIN (A_dsa_msgin/4) 223#define DSA_DATAIN (A_dsa_datain/4) 224#define DSA_DATAOUT (A_dsa_dataout/4) 225#define DSA_SIZE (A_dsa_size/4) 226 227#define MAX_SG 128 /* Scatter/Gather elements */ 228 229#define MAX_MSGOUT 8 230#define MAX_MSGIN 8 231#define MAX_CMND 12 232#define MAX_STATUS 1 233 234struct sim710_hostdata{ 235 int state; 236 Scsi_Cmnd * issue_queue; 237 Scsi_Cmnd * running; 238 int chip; 239 u8 negotiate; 240 u8 reselected_identify; 241 u8 msgin_buf[MAX_MSGIN]; 242 u8 msg_reject; 243 u32 test1_src __attribute__ ((aligned (4))); 244 u32 test1_dst; 245 246 struct sim710_target { 247 Scsi_Cmnd *cur_cmd; 248 u32 resume_offset; 249 u32 data_in_jump; 250 u32 data_out_jump; 251 u32 dsa[DSA_SIZE]; /* SCSI Script DSA area */ 252 u8 dsa_msgout[MAX_MSGOUT]; 253 u8 dsa_msgin[MAX_MSGIN]; 254 u8 dsa_cdb[MAX_CMND]; 255 u8 dsa_status[MAX_STATUS]; 256 } target[8]; 257 258 u32 script[sizeof(SCRIPT)/4] __attribute__ ((aligned (4))); 259}; 260 261 262/* Template to request asynchronous transfers */ 263 264static const unsigned char async_message[] = { 265 EXTENDED_MESSAGE, 3 /* length */, EXTENDED_SDTR, 0, 0 /* asynchronous */}; 266 267 268static void sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs); 269static void do_sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs); 270static __inline__ void run_process_issue_queue(struct sim710_hostdata *); 271static void process_issue_queue (struct sim710_hostdata *, unsigned long flags); 272static int full_reset(struct Scsi_Host * host); 273 274 275/* 276 * Function : static void ncr_dump (struct Scsi_Host *host) 277 * 278 * Purpose : Dump (possibly) useful info 279 * 280 * Inputs : host - pointer to this host adapter's structure 281 */ 282 283static void 284ncr_dump (struct Scsi_Host *host) 285{ 286 unsigned long flags; 287 struct sim710_hostdata *hostdata = (struct sim710_hostdata *) 288 host->hostdata[0]; 289 290 save_flags(flags); 291 cli(); 292 printk("scsi%d: Chip register contents:\n", host->host_no); 293 printk(" (script at virt %p, bus %lx)\n", 294 hostdata->script, virt_to_bus(hostdata->script)); 295 printk(" 00 sien: %02x sdid: %02x scntl1:%02x scntl0:%02x\n" 296 " 04 socl: %02x sodl: %02x sxfer: %02x scid: %02x\n" 297 " 08 sbcl: %02x sbdl: %02x sidl: %02x sfbr: %02x\n" 298 " 0C sstat2:%02x sstat1:%02x sstat0:%02x dstat: %02x\n" 299 " 10 dsa: %08x\n" 300 " 14 ctest3:%02x ctest2:%02x ctest1:%02x ctest0:%02x\n" 301 " 18 ctest7:%02x ctest6:%02x ctest5:%02x ctest4:%02x\n" 302 " 1C temp: %08x\n" 303 " 20 lcrc: %02x ctest8:%02x istat: %02x dfifo: %02x\n" 304 " 24 dbc: %08x dnad: %08x dsp: %08x\n" 305 " 30 dsps: %08x scratch:%08x\n" 306 " 38 dcntl: %02x dwt: %02x dien: %02x dmode: %02x\n" 307 " 3C adder: %08x\n", 308 NCR_read8(SIEN_REG), NCR_read8(SDID_REG), NCR_read8(SCNTL1_REG), 309 NCR_read8(SCNTL0_REG), NCR_read8(SOCL_REG), NCR_read8(SODL_REG), 310 NCR_read8(SXFER_REG), NCR_read8(SCID_REG), NCR_read8(SBCL_REG), 311 NCR_read8(SBDL_REG), NCR_read8(SIDL_REG), NCR_read8(SFBR_REG), 312 NCR_read8(SSTAT2_REG), NCR_read8(SSTAT1_REG), NCR_read8(SSTAT0_REG), 313 NCR_read8(DSTAT_REG), NCR_read32(DSA_REG), NCR_read8(CTEST3_REG), 314 NCR_read8(CTEST2_REG), NCR_read8(CTEST1_REG), NCR_read8(CTEST0_REG), 315 NCR_read8(CTEST7_REG), NCR_read8(CTEST6_REG), NCR_read8(CTEST5_REG), 316 NCR_read8(CTEST4_REG), NCR_read8(TEMP_REG), NCR_read8(LCRC_REG), 317 NCR_read8(CTEST8_REG), NCR_read8(ISTAT_REG), NCR_read8(DFIFO_REG), 318 NCR_read32(DBC_REG), NCR_read32(DNAD_REG), NCR_read32(DSP_REG), 319 NCR_read32(DSPS_REG), NCR_read32(SCRATCH_REG), NCR_read8(DCNTL_REG), 320 NCR_read8(DWT_REG), NCR_read8(DIEN_REG), NCR_read8(DMODE_REG), 321 NCR_read32(ADDER_REG)); 322 323 restore_flags(flags); 324} 325 326 327/* 328 * Function: int param_setup(char *str) 329 */ 330 331__init int 332param_setup(char *str) 333{ 334 char *cur = str; 335 char *p, *pc, *pv; 336 int val; 337 int c; 338 339 no_of_boards = 0; 340 while (no_of_boards < MAXBOARDS && cur != NULL && 341 (pc = strchr(cur, ':')) != NULL) { 342 char *pe; 343 344 val = 0; 345 pv = pc; 346 c = *++pv; 347 348 val = (int) simple_strtoul(pv, &pe, 0); 349 350 if (!strncmp(cur, "addr:", 5)) { 351 bases[no_of_boards++] = val; 352 } 353#ifdef DEBUG 354 else if (!strncmp(cur, "debug:", 6)) { 355 sim710_debug = val; 356 } 357#endif 358 else if (no_of_boards == 0) { 359 printk("sim710: Invalid parameters, addr: must come first\n"); 360 no_of_boards = -1; 361 return 1; 362 } 363 else if (!strncmp(cur, "irq:", 4)) 364 irq_vectors[no_of_boards-1] = val; 365 else if (!strncmp(cur, "ignore:", 7)) 366 ignore_ids[no_of_boards-1] = val; 367 else if (!strncmp(cur, "nodisc:", 7)) 368 opt_nodisc[no_of_boards-1] = val; 369 else if (!strncmp(cur, "noneg:", 6)) 370 opt_noneg[no_of_boards-1] = val; 371 else if (!strncmp(cur, "disabled:", 9)) { 372 no_of_boards = -1; 373 return 1; 374 } 375 else { 376 printk("sim710: unexpected boot option '%.*s'\n", (int)(pc-cur+1), cur); 377 no_of_boards = -1; 378 return 1; 379 } 380 381 /* Allow ',', ' ', or '+' seperators. Used to be ',' at boot and 382 * ' ' for module load, some installers crap out on the space and 383 * insmod doesn't like the comma. 384 */ 385 if ((p = strchr(cur, ',')) || (p = strchr(cur, ' ')) || 386 (p = strchr(cur, '+'))) 387 cur = p + 1; 388 else 389 break; 390 } 391 return 1; 392} 393 394#ifndef MODULE 395__setup("sim710=", param_setup); 396#endif 397 398 399/* 400 * Function: static const char *sbcl_to_phase (int sbcl) 401 */ 402 403static const char * 404sbcl_to_phase (int sbcl) { 405 switch (sbcl & SBCL_PHASE_MASK) { 406 case SBCL_PHASE_DATAIN: 407 return "DATAIN"; 408 case SBCL_PHASE_DATAOUT: 409 return "DATAOUT"; 410 case SBCL_PHASE_MSGIN: 411 return "MSGIN"; 412 case SBCL_PHASE_MSGOUT: 413 return "MSGOUT"; 414 case SBCL_PHASE_CMDOUT: 415 return "CMDOUT"; 416 case SBCL_PHASE_STATIN: 417 return "STATUSIN"; 418 default: 419 return "unknown"; 420 } 421} 422 423 424/* 425 * Function : static int ncr_halt (struct Scsi_Host *host) 426 * 427 * Purpose : halts the SCSI SCRIPTS(tm) processor on the NCR chip 428 * 429 * Inputs : host - SCSI chip to halt 430 * 431 * Returns : 0 on success 432 */ 433 434static int 435ncr_halt (struct Scsi_Host *host) 436{ 437 unsigned long flags; 438 unsigned char istat, tmp; 439 struct sim710_hostdata *hostdata = (struct sim710_hostdata *) 440 host->hostdata[0]; 441 int stage; 442 int timeout; 443 int res = 0; 444 445 save_flags(flags); 446 cli(); 447 /* Stage 0 : eat all interrupts 448 Stage 1 : set ABORT 449 Stage 2 : eat all but abort interrupts 450 Stage 3 : eat all interrupts 451 We loop for 50000 times with a delay of 10us which should give us 452 about half a second. 453 */ 454 for (stage = 0, timeout = 50000; timeout; timeout--) { 455 if (stage == 1) { 456 DEB(DEB_HALT, printk("ncr_halt: writing ISTAT_ABRT\n")); 457 NCR_write8(ISTAT_REG, ISTAT_ABRT); 458 ++stage; 459 } 460 istat = NCR_read8 (ISTAT_REG); 461 if (istat & ISTAT_SIP) { 462 DEB(DEB_HALT, printk("ncr_halt: got ISTAT_SIP, istat=%02x\n", istat)); 463 tmp = NCR_read8(SSTAT0_REG); 464 DEB(DEB_HALT, printk("ncr_halt: got SSTAT0_REG=%02x\n", tmp)); 465 } else if (istat & ISTAT_DIP) { 466 DEB(DEB_HALT, printk("ncr_halt: got ISTAT_DIP, istat=%02x\n", istat)); 467 tmp = NCR_read8(DSTAT_REG); 468 DEB(DEB_HALT, printk("ncr_halt: got DSTAT_REG=%02x\n", tmp)); 469 if (stage == 2) { 470 if (tmp & DSTAT_ABRT) { 471 DEB(DEB_HALT, printk("ncr_halt: got DSTAT_ABRT, clearing istat\n")); 472 NCR_write8(ISTAT_REG, 0); 473 ++stage; 474 } else { 475 res = 1; 476 break; 477 } 478 } 479 } 480 if (!(istat & (ISTAT_SIP|ISTAT_DIP))) { 481 if (stage == 0) 482 ++stage; 483 else if (stage == 3) 484 break; 485 } 486 udelay(10); 487 } 488 restore_flags(flags); 489 490 if (timeout == 0 || res) { 491 printk(KERN_ALERT "scsi%d: could not halt NCR chip\n", host->host_no); 492 return 1; 493 } 494 else { 495 hostdata->state = STATE_HALTED; 496 return 0; 497 } 498} 499 500/* 501 * Function : static void sim710_soft_reset (struct Scsi_Host *host) 502 * 503 * Purpose : perform a soft reset of the NCR53c7xx chip 504 * 505 * Inputs : host - pointer to this host adapter's structure 506 * 507 * Preconditions : sim710_init must have been called for this 508 * host. 509 * 510 */ 511 512static void 513sim710_soft_reset (struct Scsi_Host *host) 514{ 515 unsigned long flags; 516 517 save_flags(flags); 518 cli(); 519 /* 520 * Do a soft reset of the chip so that everything is 521 * reinitialized to the power-on state. 522 * 523 * Basically follow the procedure outlined in the NCR53c700 524 * data manual under Chapter Six, How to Use, Steps Necessary to 525 * Start SCRIPTS, with the exception of actually starting the 526 * script and setting up the synchronous transfer gunk. 527 */ 528 529 530 NCR_write8(SCNTL1_REG, SCNTL1_RST); /* Reset the bus */ 531 udelay(50); 532 NCR_write8(SCNTL1_REG, 0); 533 534 udelay(500); 535 536 NCR_write8(ISTAT_REG, ISTAT_10_SRST); /* Reset the chip */ 537 udelay(50); 538 NCR_write8(ISTAT_REG, 0); 539 540 mdelay(1000); /* Let devices recover */ 541 542 NCR_write32(SCRATCH_REG, 0); 543 NCR_write8(DCNTL_REG, DCNTL_10_COM | DCNTL_700_CF_3); 544 NCR_write8(CTEST7_REG, CTEST7_10_CDIS|CTEST7_STD); 545 NCR_write8(DMODE_REG, DMODE_10_BL_8 | DMODE_10_FC2); 546 NCR_write8(SCID_REG, 1 << host->this_id); 547 NCR_write8(SBCL_REG, 0); 548 NCR_write8(SXFER_REG, 0); 549 NCR_write8(SCNTL1_REG, SCNTL1_ESR_700); 550 NCR_write8(SCNTL0_REG, SCNTL0_EPC | SCNTL0_EPG_700 | SCNTL0_ARB1 | 551 SCNTL0_ARB2); 552 553 NCR_write8(DIEN_REG, DIEN_700_BF | 554 DIEN_ABRT | DIEN_SSI | DIEN_SIR | DIEN_700_OPC); 555 556 NCR_write8(SIEN_REG_700, 557 SIEN_PAR | SIEN_700_STO | SIEN_RST | SIEN_UDC | SIEN_SGE | SIEN_MA); 558 559 restore_flags(flags); 560} 561 562 563/* 564 * Function : static void sim710_driver_init (struct Scsi_Host *host) 565 * 566 * Purpose : Initialize internal structures, as required on startup, or 567 * after a SCSI bus reset. 568 * 569 * Inputs : host - pointer to this host adapter's structure 570 */ 571 572static void 573sim710_driver_init (struct Scsi_Host *host) 574{ 575 struct sim710_hostdata *hostdata = (struct sim710_hostdata *) 576 host->hostdata[0]; 577 int i; 578 579 hostdata->running = NULL; 580 memcpy (hostdata->script, SCRIPT, sizeof(SCRIPT)); 581 for (i = 0; i < PATCHES; i++) 582 hostdata->script[LABELPATCHES[i]] += virt_to_bus(hostdata->script); 583 patch_abs_32 (hostdata->script, 0, reselected_identify, 584 virt_to_bus((void *)&(hostdata->reselected_identify))); 585 patch_abs_32 (hostdata->script, 0, msgin_buf, 586 virt_to_bus((void *)&(hostdata->msgin_buf[0]))); 587 patch_abs_32 (hostdata->script, 0, msg_reject, 588 virt_to_bus((void *)&(hostdata->msg_reject))); 589 patch_abs_32 (hostdata->script, 0, test1_src, 590 virt_to_bus((void *)&(hostdata->test1_src))); 591 patch_abs_32 (hostdata->script, 0, test1_dst, 592 virt_to_bus((void *)&(hostdata->test1_dst))); 593 hostdata->state = STATE_INITIALISED; 594 hostdata->negotiate = 0xff; 595} 596 597 598/* Handle incoming Synchronous data transfer request. If our negotiate 599 * flag is set then this is a response to our request, otherwise it is 600 * spurious request from the target. Don't really expect target initiated 601 * SDTRs, because we always negotiate on the first command. Could still 602 * get them though.. 603 * The chip is currently paused with ACK asserted on the last byte of the 604 * SDTR. 605 * resa is the resume address if the message is in response to our outgoing 606 * SDTR. Only possible on initial identify. 607 * resb is the resume address if the message exchange is initiated by the 608 * target. 609 */ 610 611static u32 612handle_sdtr (struct Scsi_Host * host, Scsi_Cmnd * cmd, u32 resa, u32 resb) 613{ 614 struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0]; 615 struct sim710_target *targdata = hostdata->target + cmd->target; 616 u32 resume_offset; 617 618 if (resa && hostdata->negotiate & (1 << cmd->target)) { 619 DEB(DEB_SYNC, printk("scsi%d: Response to host SDTR = %02x %02x\n", 620 host->host_no, hostdata->msgin_buf[3], hostdata->msgin_buf[4])); 621 /* We always issue an SDTR with the identify, so we must issue 622 * the CDB next. 623 */ 624 resume_offset = resa; 625 hostdata->negotiate &= ~(1 << cmd->target); 626 } 627 else { 628 DEB(DEB_SYNC, printk("scsi%d: Target initiated SDTR = %02x %02x\n", 629 host->host_no, hostdata->msgin_buf[3], hostdata->msgin_buf[4])); 630 memcpy(targdata->dsa_msgout, async_message, sizeof(async_message)); 631 targdata->dsa[DSA_MSGOUT] = sizeof(async_message); 632 /* I guess the target could do this anytime; we have to send our 633 * response, and then continue (sending the CDB if not already done). 634 */ 635 resume_offset = resb; 636 } 637 return resume_offset; 638} 639 640 641/* 642 * Function : static int datapath_residual (Scsi_Host *host) 643 * 644 * Purpose : return residual data count of what's in the chip. 645 * 646 * Inputs : host - SCSI host 647 */ 648 649static int 650datapath_residual (struct Scsi_Host *host) { 651 int count, synchronous, sstat; 652 unsigned int ddir; 653 654 count = ((NCR_read8 (DFIFO_REG) & DFIFO_10_BO_MASK) - 655 (NCR_read32 (DBC_REG) & DFIFO_10_BO_MASK)) & DFIFO_10_BO_MASK; 656 synchronous = NCR_read8 (SXFER_REG) & SXFER_MO_MASK; 657 ddir = NCR_read8 (CTEST0_REG_700) & CTEST0_700_DDIR; 658 659 if (ddir) { 660 /* Receive */ 661 if (synchronous) 662 count += (NCR_read8 (SSTAT2_REG) & SSTAT2_FF_MASK) >> SSTAT2_FF_SHIFT; 663 else 664 if (NCR_read8 (SSTAT1_REG) & SSTAT1_ILF) 665 ++count; 666 } else { 667 /* Send */ 668 sstat = NCR_read8 (SSTAT1_REG); 669 if (sstat & SSTAT1_OLF) 670 ++count; 671 if (synchronous && (sstat & SSTAT1_ORF)) 672 ++count; 673 } 674 return count; 675} 676 677 678static u32 679handle_idd (struct Scsi_Host * host, Scsi_Cmnd * cmd) 680{ 681 struct sim710_hostdata *hostdata = 682 (struct sim710_hostdata *)host->hostdata[0]; 683 struct sim710_target *targdata = hostdata->target + cmd->target; 684 u32 resume_offset = 0, index; 685 686 index = (u32)((u32 *)(bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script); 687 688 switch (index) { 689 case Ent_wait_disc_complete/4 + 2: 690 cmd->result = targdata->dsa_status[0]; 691 SCSI_DONE(cmd); 692 targdata->cur_cmd = NULL; 693 resume_offset = Ent_reselect; 694 break; 695 case Ent_wait_disc2/4 + 2: 696 /* Disconnect after command - just wait for a reselect */ 697 targdata->resume_offset = Ent_resume_msgin2a; 698 resume_offset = Ent_reselect; 699 break; 700 case Ent_wait_disc3/4 + 2: 701 /* Disconnect after the data phase */ 702 targdata->resume_offset = Ent_resume_msgin3a; 703 resume_offset = Ent_reselect; 704 break; 705 case Ent_wait_disc1/4 + 2: 706 /* Disconnect before command - not expected */ 707 targdata->resume_offset = Ent_resume_msgin1a; 708 resume_offset = Ent_reselect; 709 break; 710 default: 711 printk("scsi%d: Unexpected Illegal Instruction, script[%04x]\n", 712 host->host_no, index); 713 sim710_errors++; 714 /* resume_offset is zero, which will cause host reset */ 715 } 716 return resume_offset; 717} 718 719 720/* Handle a phase mismatch. 721 */ 722 723static u32 724handle_phase_mismatch (struct Scsi_Host * host, Scsi_Cmnd * cmd) 725{ 726 struct sim710_hostdata *hostdata = 727 (struct sim710_hostdata *)host->hostdata[0]; 728 struct sim710_target *targdata = hostdata->target + cmd->target; 729 u32 resume_offset = 0, index; 730 unsigned char sbcl; 731 732 sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK; 733 index = (u32)((u32 *)(bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script); 734 735 DEB(DEB_PMM, printk("scsi%d: Phase mismatch, phase %s (%x) at script[0x%x]\n", 736 host->host_no, sbcl_to_phase(sbcl), sbcl, index)); 737 DEB(DEB_PMM, print_command(cmd->cmnd)); 738 739 if (index == Ent_done_ident/4) { 740 /* Sending initial message out - probably rejecting our sync 741 * negotiation request. 742 */ 743 NCR_write8(SOCL_REG, 0); /* Negate ATN */ 744 if (sbcl == SBCL_PHASE_MSGIN) 745 resume_offset = Ent_resume_rej_ident; 746 else if (sbcl == SBCL_PHASE_CMDOUT) { 747 /* Some old devices (SQ555) switch to cmdout after the first 748 * byte of an identify message, regardless of whether we 749 * have more bytes to send! 750 */ 751 printk("scsi%d: Unexpected switch to CMDOUT during IDENTIFY\n", 752 host->host_no); 753 resume_offset = Ent_resume_cmd; 754 } 755 else if (sbcl == SBCL_PHASE_STATIN) { 756 /* Some devices do this on parity error, at least */ 757 printk("scsi%d: Unexpected switch to STATUSIN on initial message out\n", 758 host->host_no); 759 resume_offset = Ent_end_data_trans; 760 } 761 else { 762 printk("scsi%d: Unexpected phase change to %s on initial msgout\n", 763 host->host_no, sbcl_to_phase(sbcl)); 764 /* resume_offset is zero, which will cause a host reset */ 765 } 766 hostdata->negotiate &= ~(1 << cmd->target); 767 } 768 else if (index > Ent_patch_input_data/4 && 769 index < Ent_patch_output_data/4) { 770 /* DataIn transfer phase */ 771 u32 sg_id, oaddr, olen, naddr, nlen; 772 int residual; 773 774 sg_id = (index - Ent_patch_input_data/4 - 4) / 2; 775 targdata->data_in_jump = hostdata->script[Ent_patch_input_data/4+1] = 776 virt_to_bus(hostdata->script + Ent_patch_input_data/4 + sg_id * 2 + 2); 777 olen = targdata->dsa[DSA_DATAIN + sg_id * 2]; 778 oaddr = targdata->dsa[DSA_DATAIN + sg_id * 2 + 1]; 779 residual = datapath_residual (host); 780 if (residual) 781 printk("scsi%d: Residual count %d on DataIn - NOT expected!!!", 782 host->host_no, residual); 783 naddr = NCR_read32(DNAD_REG) - residual; 784 nlen = (NCR_read32(DBC_REG) & 0x00ffffff) + residual; 785 DEB(DEB_PMM, printk("scsi%d: DIN sg %d, old %08x/%08x, new %08x/%08x (%d)\n", 786 host->host_no, sg_id, oaddr, olen, naddr, nlen, residual)); 787 if (oaddr+olen != naddr+nlen) { 788 printk("scsi%d: PMM DIN counts error: 0x%x + 0x%x != 0x%x + 0x%x", 789 host->host_no, oaddr, olen, naddr, nlen); 790 } 791 else { 792 targdata->dsa[DSA_DATAIN + sg_id * 2] = nlen; 793 targdata->dsa[DSA_DATAIN + sg_id * 2 + 1] = naddr; 794 resume_offset = Ent_resume_pmm; 795 } 796 } 797 else if (index > Ent_patch_output_data/4 && 798 index <= Ent_end_data_trans/4) { 799 /* Dataout transfer phase */ 800 u32 sg_id, oaddr, olen, naddr, nlen; 801 int residual; 802 803 sg_id = (index - Ent_patch_output_data/4 - 4) / 2; 804 targdata->data_out_jump = hostdata->script[Ent_patch_output_data/4+1] = 805 virt_to_bus(hostdata->script + Ent_patch_output_data/4 + sg_id * 2 + 2); 806 olen = targdata->dsa[DSA_DATAOUT + sg_id * 2]; 807 oaddr = targdata->dsa[DSA_DATAOUT + sg_id * 2 + 1]; 808 residual = datapath_residual (host); 809 naddr = NCR_read32(DNAD_REG) - residual; 810 nlen = (NCR_read32(DBC_REG) & 0x00ffffff) + residual; 811 DEB(DEB_PMM, printk("scsi%d: DOUT sg %d, old %08x/%08x, new %08x/%08x (%d)\n", 812 host->host_no, sg_id, oaddr, olen, naddr, nlen, residual)); 813 if (oaddr+olen != naddr+nlen) { 814 printk("scsi%d: PMM DOUT counts error: 0x%x + 0x%x != 0x%x + 0x%x", 815 host->host_no, oaddr, olen, naddr, nlen); 816 } 817 else { 818 targdata->dsa[DSA_DATAOUT + sg_id * 2] = nlen; 819 targdata->dsa[DSA_DATAOUT + sg_id * 2 + 1] = naddr; 820 resume_offset = Ent_resume_pmm; 821 } 822 } 823 else if (sbcl == SBCL_PHASE_STATIN) { 824 /* Change to Status In at some random point; probably wants to report a 825 * parity error or similar. 826 */ 827 printk("scsi%d: Unexpected phase change to STATUSIN at index 0x%x\n", 828 host->host_no, index); 829 resume_offset = Ent_end_data_trans; 830 } 831 else { 832 printk("scsi%d: Unexpected phase change to %s at index 0x%x\n", 833 host->host_no, sbcl_to_phase(sbcl), index); 834 /* resume_offset is zero, which will cause a host reset */ 835 } 836 /* Flush DMA FIFO */ 837 NCR_write8 (CTEST8_REG, CTEST8_10_CLF); 838 while (NCR_read8 (CTEST8_REG) & CTEST8_10_CLF); 839 840 return resume_offset; 841} 842 843 844static u32 845handle_script_int(struct Scsi_Host * host, Scsi_Cmnd * cmd) 846{ 847 struct sim710_hostdata *hostdata = 848 (struct sim710_hostdata *)host->hostdata[0]; 849 struct sim710_target *targdata = hostdata->target + cmd->target; 850 u32 dsps, resume_offset = 0; 851 unsigned char sbcl; 852 853 dsps = NCR_read32(DSPS_REG); 854 855 switch (dsps) { 856 case A_int_cmd_complete: 857 cmd->result = targdata->dsa_status[0]; 858 SCSI_DONE(cmd); 859 targdata->cur_cmd = NULL; 860 resume_offset = Ent_reselect; 861 break; 862 case A_int_msg_sdtr1: 863 resume_offset = handle_sdtr(host, cmd, 864 Ent_resume_msgin1a, Ent_resume_msgin1b); 865 break; 866 case A_int_msg_sdtr2: 867 resume_offset = handle_sdtr(host, cmd, 0, Ent_resume_msgin2b); 868 break; 869 case A_int_msg_sdtr3: 870 resume_offset = handle_sdtr(host, cmd, 0, Ent_resume_msgin3b); 871 break; 872 case A_int_disc1: 873 /* Disconnect before command - not expected */ 874 targdata->resume_offset = Ent_resume_msgin1a; 875 resume_offset = Ent_reselect; 876 break; 877 case A_int_disc2: 878 /* Disconnect after command - just wait for a reselect */ 879 targdata->resume_offset = Ent_resume_msgin2a; 880 resume_offset = Ent_reselect; 881 break; 882 case A_int_disc3: 883 /* Disconnect after the data phase */ 884 targdata->resume_offset = Ent_resume_msgin3a; 885 resume_offset = Ent_reselect; 886 break; 887 case A_int_reselected: 888 hostdata->script[Ent_patch_output_data/4+1] = targdata->data_out_jump; 889 hostdata->script[Ent_patch_input_data/4+1] = targdata->data_in_jump; 890 NCR_write32(DSA_REG, virt_to_bus(targdata->dsa)); 891 resume_offset = targdata->resume_offset; 892 break; 893 case A_int_data_bad_phase: 894 sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK; 895 printk("scsi%d: int_data_bad_phase, phase %s (%x)\n", 896 host->host_no, sbcl_to_phase(sbcl), sbcl); 897 break; 898 case A_int_bad_msg1: 899 case A_int_bad_msg2: 900 case A_int_bad_msg3: 901 case A_int_cmd_bad_phase: 902 case A_int_no_msgout1: 903 case A_int_no_msgout2: 904 case A_int_no_msgout3: 905 case A_int_not_cmd_complete: 906 case A_int_sel_no_ident: 907 case A_int_sel_not_cmd: 908 case A_int_status_not_msgin: 909 case A_int_resel_not_msgin: 910 case A_int_selected: 911 case A_int_not_rej: 912 default: 913 sbcl = NCR_read8(SBCL_REG) & SBCL_PHASE_MASK; 914 printk("scsi%d: Unimplemented script interrupt: %08x, phase %s\n", 915 host->host_no, dsps, sbcl_to_phase(sbcl)); 916 sim710_errors++; 917 /* resume_offset is zero, which will cause a host reset */ 918 } 919 return resume_offset; 920} 921 922 923/* A quick wrapper for sim710_intr_handle to grab the spin lock */ 924 925static void 926do_sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs) 927{ 928 unsigned long flags; 929 930 spin_lock_irqsave(&io_request_lock, flags); 931 sim710_intr_handle(irq, dev_id, regs); 932 spin_unlock_irqrestore(&io_request_lock, flags); 933} 934 935 936/* A "high" level interrupt handler */ 937 938static void 939sim710_intr_handle(int irq, void *dev_id, struct pt_regs *regs) 940{ 941 struct Scsi_Host * host = (struct Scsi_Host *)dev_id; 942 struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0]; 943 Scsi_Cmnd * cmd; 944 unsigned char istat, dstat; 945 unsigned char sstat0; 946 u32 scratch, dsps, resume_offset = 0; 947 948 istat = NCR_read8(ISTAT_REG); 949 if (!(istat & (ISTAT_SIP|ISTAT_DIP))) 950 return; 951 else { 952 sim710_intrs++; 953 dsps = NCR_read32(DSPS_REG); 954 hostdata->state = STATE_HALTED; 955 sstat0 = dstat = 0; 956 scratch = NCR_read32(SCRATCH_REG); 957 if (istat & ISTAT_SIP) { 958 sstat0 = NCR_read8(SSTAT0_REG); 959 } 960 if (istat & ISTAT_DIP) { 961 udelay(10); /* Some comment somewhere about 10cycles 962 * between accesses to sstat0 and dstat ??? */ 963 dstat = NCR_read8(DSTAT_REG); 964 } 965 DEB(DEB_INTS, printk("scsi%d: Int %d, istat %02x, sstat0 %02x " 966 "dstat %02x, dsp [%04x], scratch %02x\n", 967 host->host_no, sim710_intrs, istat, sstat0, dstat, 968 (u32 *)(bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script, 969 scratch)); 970 if (scratch & 0x100) { 971 u8 *p = hostdata->msgin_buf; 972 973 DEB(DEB_INTS, printk(" msgin_buf: %02x %02x %02x %02x\n", 974 p[0], p[1], p[2], p[3])); 975 } 976 if ((dstat & DSTAT_SIR) && dsps == A_int_reselected) { 977 /* Reselected. Identify the target from LCRC_REG, and 978 * update current command. If we were trying to select 979 * a device, then that command needs to go back on the 980 * issue_queue for later. 981 */ 982 unsigned char lcrc = NCR_read8(LCRC_REG_10); 983 int id = 0; 984 985 if (!(lcrc & 0x7f)) { 986 printk("scsi%d: Reselected with LCRC = %02x\n", 987 host->host_no, lcrc); 988 cmd = NULL; 989 } 990 else { 991 while (!(lcrc & 1)) { 992 id++; 993 lcrc >>= 1; 994 } 995 DEB(DEB_DISC, printk("scsi%d: Reselected by ID %d\n", 996 host->host_no, id)); 997 if (hostdata->running) { 998 /* Clear SIGP */ 999 (void)NCR_read8(CTEST2_REG_700); 1000 1001 DEB(DEB_DISC, printk("scsi%d: Select of %d interrupted " 1002 "by reselect from %d (%p)\n", 1003 host->host_no, hostdata->running->target, 1004 id, hostdata->target[id].cur_cmd)); 1005 cmd = hostdata->running; 1006 hostdata->target[cmd->target].cur_cmd = NULL; 1007 cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue; 1008 hostdata->issue_queue = cmd; 1009 } 1010 cmd = hostdata->running = hostdata->target[id].cur_cmd; 1011 } 1012 } 1013 else 1014 cmd = hostdata->running; 1015 1016 if (!cmd) { 1017 printk("scsi%d: No active command!\n", host->host_no); 1018 printk("scsi%d: Int %d, istat %02x, sstat0 %02x " 1019 "dstat %02x, dsp [%04x], scratch %02x, dsps %08x\n", 1020 host->host_no, sim710_intrs, istat, sstat0, dstat, 1021 (u32 *)(bus_to_virt(NCR_read32(DSP_REG))) - hostdata->script, 1022 NCR_read32(SCRATCH_REG), dsps); 1023 /* resume_offset is zero, which will cause a host reset */ 1024 } 1025 else if (sstat0 & SSTAT0_700_STO) { 1026 DEB(DEB_TOUT, printk("scsi%d: Selection timeout\n", host->host_no)); 1027 cmd->result = DID_NO_CONNECT << 16; 1028 SCSI_DONE(cmd); 1029 hostdata->target[cmd->target].cur_cmd = NULL; 1030 resume_offset = Ent_reselect; 1031 } 1032 else if (sstat0 & (SSTAT0_SGE|SSTAT0_UDC|SSTAT0_RST|SSTAT0_PAR)) { 1033 printk("scsi%d: Serious error, sstat0 = %02x\n", host->host_no, 1034 sstat0); 1035 sim710_errors++; 1036 /* resume_offset is zero, which will cause a host reset */ 1037 } 1038 else if (dstat & (DSTAT_BF|DSTAT_ABRT|DSTAT_SSI|DSTAT_WTD)) { 1039 printk("scsi%d: Serious error, dstat = %02x\n", host->host_no, 1040 dstat); 1041 sim710_errors++; 1042 /* resume_offset is zero, which will cause a host reset */ 1043 } 1044 else if (dstat & DSTAT_SIR) 1045 resume_offset = handle_script_int(host, cmd); 1046 else if (sstat0 & SSTAT0_MA) 1047 resume_offset = handle_phase_mismatch(host, cmd); 1048 else if (dstat & DSTAT_IID) { 1049 /* This can be due to a quick reselect while doing a WAIT 1050 * DISCONNECT. 1051 */ 1052 resume_offset = handle_idd(host, cmd); 1053 } 1054 else { 1055 sim710_errors++; 1056 printk("scsi%d: Spurious interrupt!\n", host->host_no); 1057 /* resume_offset is zero, which will cause a host reset */ 1058 } 1059 } 1060 1061 if (resume_offset) { 1062 if (resume_offset == Ent_reselect) { 1063 hostdata->running = NULL; 1064 hostdata->state = STATE_IDLE; 1065 } 1066 else 1067 hostdata->state = STATE_BUSY; 1068 DEB(DEB_RESUME, printk("scsi%d: Resuming at script[0x%x]\n", 1069 host->host_no, resume_offset/4)); 1070#ifdef DEBUG_LIMIT_INTS 1071 if (sim710_intrs < DEBUG_LIMIT_INTS) 1072#endif 1073 { 1074 NCR_write32(SCRATCH_REG, 0); 1075 NCR_write32(DSP_REG, virt_to_bus(hostdata->script+resume_offset/4)); 1076 } 1077 if (resume_offset == Ent_reselect) 1078 run_process_issue_queue(hostdata); 1079 } 1080 else { 1081 printk("scsi%d: Failed to handle interrupt. Failing commands " 1082 "and resetting SCSI bus and chip\n", host->host_no); 1083 mdelay(1000); /* Give chance to read screen!! */ 1084 full_reset(host); 1085 } 1086} 1087 1088 1089static void 1090run_command (struct sim710_hostdata *hostdata, Scsi_Cmnd *cmd) 1091{ 1092 struct Scsi_Host *host = cmd->host; 1093 struct sim710_target *targdata = hostdata->target + cmd->target; 1094 int i, datain, dataout, sg_start; 1095 u32 *dip, *dop, dsa; 1096 1097 DEB(DEB_CMND, printk("scsi%d: id%d starting ", host->host_no, 1098 cmd->target)); 1099 DEB(DEB_CMND, print_command(cmd->cmnd)); 1100 1101 switch (cmd->cmnd[0]) { 1102 case INQUIRY: 1103 case MODE_SENSE: 1104 case READ_6: 1105 case READ_10: 1106 case READ_CAPACITY: 1107 case REQUEST_SENSE: 1108 case READ_BLOCK_LIMITS: 1109 case READ_TOC: 1110 datain = 1; 1111 dataout = 0; 1112 break; 1113 case MODE_SELECT: 1114 case WRITE_6: 1115 case WRITE_10: 1116 datain = 0; 1117 dataout = 1; 1118 break; 1119 case TEST_UNIT_READY: 1120 case ALLOW_MEDIUM_REMOVAL: 1121 case START_STOP: 1122 datain = dataout = 0; 1123 break; 1124 default: 1125 datain = dataout = 1; 1126 } 1127 1128 memcpy(targdata->dsa_cdb, cmd->cmnd, MAX_CMND); 1129 1130 targdata->dsa_msgout[0] = 1131 IDENTIFY((opt_nodisc[hostdata->chip] & (1<<cmd->target)) ? 0 : 1 ,0); 1132 if (hostdata->negotiate & (1 << cmd->target)) { 1133 if (opt_noneg[hostdata->chip] & (1 << cmd->target)) { 1134 hostdata->negotiate ^= (1 << cmd->target); 1135 targdata->dsa[DSA_MSGOUT] = 1; 1136 } 1137 else { 1138 DEB(DEB_SYNC, printk("scsi%d: Negotiating async transfers " 1139 "for ID %d\n", 1140 host->host_no, cmd->target)); 1141 memcpy(targdata->dsa_msgout+1, async_message, sizeof(async_message)); 1142 targdata->dsa[DSA_MSGOUT] = sizeof(async_message) + 1; 1143 } 1144 } 1145 else 1146 targdata->dsa[DSA_MSGOUT] = 1; 1147 1148 targdata->dsa_msgin[0] = 0xff; 1149 targdata->dsa_status[0] = 0xff; 1150 1151 targdata->dsa[DSA_SELECT] = (1 << cmd->target) << 16; 1152 targdata->dsa[DSA_MSGOUT+1] = virt_to_bus(targdata->dsa_msgout); 1153 targdata->dsa[DSA_CMND] = cmd->cmd_len; 1154 targdata->dsa[DSA_CMND+1] = virt_to_bus(targdata->dsa_cdb); 1155 targdata->dsa[DSA_STATUS] = 1; 1156 targdata->dsa[DSA_STATUS+1] = virt_to_bus(targdata->dsa_status); 1157 targdata->dsa[DSA_MSGIN] = 1; 1158 targdata->dsa[DSA_MSGIN+1] = virt_to_bus(targdata->dsa_msgin); 1159 1160 sg_start = (MAX_SG - (cmd->use_sg ? cmd->use_sg : 1)) * 2; 1161 dip = targdata->dsa + DSA_DATAIN + sg_start; 1162 dop = targdata->dsa + DSA_DATAOUT + sg_start; 1163 1164 for (i = 0; cmd->use_sg ? (i < cmd->use_sg) : !i; i++) { 1165 u32 vbuf = cmd->use_sg ? 1166 (u32)(((struct scatterlist *)cmd->buffer)[i].address) : 1167 (u32)(cmd->request_buffer); 1168 u32 bbuf = virt_to_bus((void *)vbuf); 1169 u32 cnt = cmd->use_sg ? 1170 ((struct scatterlist *)cmd->buffer)[i].length : 1171 cmd->request_bufflen; 1172 1173 if (datain) { 1174 *dip++ = cnt; 1175 *dip++ = bbuf; 1176 } 1177 if (dataout) { 1178 *dop++ = cnt; 1179 *dop++ = bbuf; 1180 } 1181 } 1182 targdata->data_out_jump = hostdata->script[Ent_patch_output_data/4+1] = 1183 virt_to_bus(hostdata->script + Ent_patch_output_data/4 + sg_start + 2); 1184 targdata->data_in_jump = hostdata->script[Ent_patch_input_data/4+1] = 1185 virt_to_bus(hostdata->script + Ent_patch_input_data/4 + sg_start + 2); 1186 1187 for (i = 0, dsa = virt_to_bus(targdata->dsa); i < 4; i++) { 1188 u32 v = hostdata->script[Ent_patch_new_dsa/4 + i * 2]; 1189 1190 v &= ~0x0000ff00; 1191 v |= (dsa & 0xff) << 8; 1192 hostdata->script[Ent_patch_new_dsa/4 + i * 2] = v; 1193 dsa >>= 8; 1194 } 1195 hostdata->running = targdata->cur_cmd = cmd; 1196 hostdata->state = STATE_BUSY; 1197 1198 NCR_write8(ISTAT_REG, ISTAT_10_SIGP); 1199} 1200 1201 1202static volatile int process_issue_queue_running = 0; 1203 1204static __inline__ void 1205run_process_issue_queue(struct sim710_hostdata *hostdata) 1206{ 1207 unsigned long flags; 1208 save_flags (flags); 1209 cli(); 1210 if (!process_issue_queue_running) { 1211 process_issue_queue_running = 1; 1212 process_issue_queue(hostdata, flags); 1213 /* 1214 * process_issue_queue_running is cleared in process_issue_queue 1215 * once it can't do more work, and process_issue_queue exits with 1216 * interrupts disabled. 1217 */ 1218 } 1219 restore_flags (flags); 1220} 1221 1222 1223/* 1224 * Function : process_issue_queue (hostdata, flags) 1225 * 1226 * Purpose : Start next command for any idle target. 1227 * 1228 * NOTE : process_issue_queue exits with interrupts *disabled*, so the 1229 * caller must reenable them if it desires. 1230 * 1231 * NOTE : process_issue_queue should be called from both 1232 * sim710_queue_command() and from the interrupt handler 1233 * after command completion. 1234 */ 1235 1236static void 1237process_issue_queue (struct sim710_hostdata *hostdata, unsigned long flags) 1238{ 1239 Scsi_Cmnd *tmp, *prev; 1240 int done; 1241 1242 /* 1243 * We run (with interrupts disabled) until we're sure that none of 1244 * the host adapters have anything that can be done, at which point 1245 * we set process_issue_queue_running to 0 and exit. 1246 * 1247 * Interrupts are enabled before doing various other internal 1248 * instructions, after we've decided that we need to run through 1249 * the loop again. 1250 * 1251 */ 1252 1253 do { 1254 cli(); /* Freeze request queues */ 1255 done = 1; 1256 if (hostdata->issue_queue) { 1257 if (hostdata->state == STATE_DISABLED) { 1258 tmp = (Scsi_Cmnd *) hostdata->issue_queue; 1259 hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr; 1260 tmp->result = (DID_BAD_TARGET << 16); 1261 tmp->scsi_done (tmp); 1262 done = 0; 1263 } 1264 else if (hostdata->state == STATE_IDLE) { 1265 for (tmp = hostdata->issue_queue, prev = NULL; tmp; 1266 prev = tmp, tmp = (Scsi_Cmnd *) tmp->SCp.ptr) { 1267 if (hostdata->target[tmp->target].cur_cmd == NULL) { 1268 if (prev) 1269 prev->SCp.ptr = tmp->SCp.ptr; 1270 else 1271 hostdata->issue_queue = (Scsi_Cmnd *) tmp->SCp.ptr; 1272 tmp->SCp.ptr = NULL; 1273 run_command (hostdata, tmp); 1274 done = 0; 1275 } /* if target/lun is not busy */ 1276 } /* scan issue queue for work */ 1277 } /* host is idle */ 1278 } /* if hostdata->issue_queue */ 1279 if (!done) 1280 restore_flags (flags); 1281 } while (!done); 1282 process_issue_queue_running = 0; 1283} 1284 1285 1286int 1287sim710_queuecommand(Scsi_Cmnd * cmd, void (*done)(Scsi_Cmnd *)) 1288{ 1289 struct Scsi_Host *host = cmd->host; 1290 struct sim710_hostdata *hostdata = (struct sim710_hostdata *)host->hostdata[0]; 1291 Scsi_Cmnd *tmp; 1292 unsigned long flags; 1293 1294 if (cmd->lun) { 1295 /* Silently ignore luns other than zero! */ 1296 cmd->result = (DID_BAD_TARGET << 16); 1297 done(cmd); 1298 return 0; 1299 } 1300 1301 DEB(DEB_CMND, printk("scsi%d: id%d queuing ", host->host_no, 1302 cmd->target)); 1303 DEB(DEB_CMND, print_command(cmd->cmnd)); 1304 1305 cmd->scsi_done = done; 1306 cmd->host_scribble = NULL; 1307 cmd->SCp.ptr = NULL; 1308 cmd->SCp.buffer = NULL; 1309 1310 save_flags(flags); 1311 cli(); 1312 1313 if (ignore_ids[hostdata->chip] & (1 << cmd->target)) { 1314 printk("scsi%d: ignoring target %d\n", host->host_no, cmd->target); 1315 cmd->result = (DID_BAD_TARGET << 16); 1316 done(cmd); 1317 restore_flags (flags); 1318 return 0; 1319 } 1320#ifdef DEBUG_LIMIT_INTS 1321 if (sim710_intrs > DEBUG_LIMIT_INTS) { 1322 cmd->result = (DID_BAD_TARGET << 16); 1323 done(cmd); 1324 restore_flags (flags); 1325 return 0; 1326 } 1327#endif 1328 if (cmd->use_sg > MAX_SG) 1329 panic ("cmd->use_sg = %d\n", cmd->use_sg); 1330 1331 if (!(hostdata->issue_queue) || (cmd->cmnd[0] == REQUEST_SENSE)) { 1332 cmd->SCp.ptr = (unsigned char *) hostdata->issue_queue; 1333 hostdata->issue_queue = cmd; 1334 } else { 1335 for (tmp = hostdata->issue_queue; tmp->SCp.ptr; 1336 tmp = (Scsi_Cmnd *) tmp->SCp.ptr); 1337 tmp->SCp.ptr = (unsigned char *) cmd; 1338 } 1339 restore_flags (flags); 1340 run_process_issue_queue(hostdata); 1341 return 0; 1342} 1343 1344 1345__init int 1346sim710_detect(Scsi_Host_Template * tpnt) 1347{ 1348 unsigned char scsi_id; 1349 unsigned int base_addr; 1350 struct Scsi_Host * host = NULL; 1351 struct sim710_hostdata *hostdata; 1352 unsigned long timeout; 1353 unsigned long irq_mask; 1354 int requested_irq; 1355 int probed_irq; 1356 u32 dsps; 1357 int chips = 0; 1358 int limit; 1359 int indx; 1360 int revision; 1361 int size; 1362 volatile u8 tmp; 1363 struct Scsi_Host *our_hosts[MAXBOARDS+1]; 1364 1365#ifdef MODULE 1366 if (sim710) 1367 param_setup(sim710); 1368#endif 1369 1370 if (no_of_boards < 0) { 1371 printk("sim710: NCR53C710 driver disabled\n"); 1372 return 0; 1373 } 1374 1375#ifdef CONFIG_MCA 1376 /* If board details have been specified via boot/module parameters, 1377 * then don't bother probing. 1378 */ 1379 if (no_of_boards == 0) { 1380 int slot; 1381 int pos[3]; 1382 int mca_53c710_ids[] = MCA_53C710_IDS; 1383 int *id_to_check = mca_53c710_ids; 1384 static int io_004f_by_pos[] = MCA_004F_IO_PORTS; 1385 static int irq_004f_by_pos[] = MCA_004F_IRQS; 1386 static int io_01bb_by_pos[] = MCA_01BB_IO_PORTS; 1387 static int irq_01bb_by_pos[] = MCA_01BB_IRQS; 1388 1389 while ( *id_to_check && no_of_boards < MAXBOARDS) { 1390 if (!MCA_bus) 1391 return 0; 1392 1393 if ((slot = mca_find_adapter(*id_to_check, 0)) != MCA_NOTFOUND) { 1394 1395 pos[0] = mca_read_stored_pos(slot, 2); 1396 pos[1] = mca_read_stored_pos(slot, 3); 1397 pos[2] = mca_read_stored_pos(slot, 4); 1398 1399 /* 1400 * 01BB & 01BA port base by bits 7,6,5,4,3,2 in pos[2] 1401 * 1402 * 000000 <disabled> 001010 0x2800 1403 * 000001 <invalid> 001011 0x2C00 1404 * 000010 0x0800 001100 0x3000 1405 * 000011 0x0C00 001101 0x3400 1406 * 000100 0x1000 001110 0x3800 1407 * 000101 0x1400 001111 0x3C00 1408 * 000110 0x1800 010000 0x4000 1409 * 000111 0x1C00 010001 0x4400 1410 * 001000 0x2000 010010 0x4800 1411 * 001001 0x2400 010011 0x4C00 1412 * 010100 0x5000 1413 * 1414 * 00F4 port base by bits 3,2,1 in pos[0] 1415 * 1416 * 000 <disabled> 001 0x200 1417 * 010 0x300 011 0x400 1418 * 100 0x500 101 0x600 1419 * 1420 * 01BB & 01BA IRQ is specified in pos[0] bits 7 and 6: 1421 * 1422 * 00 3 10 11 1423 * 01 5 11 14 1424 * 1425 * 00F4 IRQ specified by bits 6,5,4 in pos[0] 1426 * 1427 * 100 5 101 9 1428 * 110 14 1429 */ 1430 1431 if ( *id_to_check == 0x01bb || *id_to_check == 0x01ba ) { 1432 bases[no_of_boards] = io_01bb_by_pos[(pos[2] & 0xFC) >> 2]; 1433 irq_vectors[no_of_boards] = 1434 irq_01bb_by_pos[((pos[0] & 0xC0) >> 6)]; 1435 if (bases[no_of_boards] == 0x0000) 1436 printk("sim710: NCR53C710 Adapter ID 0x01bb is disabled.\n"); 1437 else { 1438 no_of_boards++; 1439 if ( *id_to_check == 0x01bb ) 1440 mca_set_adapter_name( slot, 1441 "NCR 3360/3430 SCSI SubSystem" ); 1442 else 1443 mca_set_adapter_name(slot, 1444 "NCR Dual SIOP SCSI Host Adapter Board"); 1445 } 1446 } 1447 else if ( *id_to_check == 0x004f ) { 1448 bases[no_of_boards] = io_004f_by_pos[((pos[0] & 0x0E) >> 1)]; 1449 irq_vectors[no_of_boards] = 1450 irq_004f_by_pos[((pos[0] & 0x70) >> 4) - 4]; 1451 if (bases[no_of_boards] == 0x0000) 1452 printk("sim710: NCR53C710 Adapter ID 0x004f is disabled.\n"); 1453 else { 1454 no_of_boards++; 1455 mca_set_adapter_name(slot, 1456 "NCR 53c710 SCSI Host Adapter Board"); 1457 } 1458 } 1459 } 1460 id_to_check++; 1461 } 1462 } 1463#endif 1464 1465#ifdef CONFIG_EISA 1466 /* Auto probe, if no boards specified in boot parameters */ 1467 if (no_of_boards == 0) { 1468 int io_addr; 1469 /* reverse probe, so my on-board controller at 0x9000 is always scsi0 */ 1470 for (io_addr = 0x9000; no_of_boards < MAXBOARDS && io_addr >= 0x1000; io_addr -= 0x1000) { 1471 if (request_region(io_addr, 0x40, "sim710") != NULL) { 1472 int id0 = inw(io_addr + 0xc80); 1473 int id1 = inw(io_addr + 0xc82); 1474 /* The on-board controller on my Proliant 2000 is 0x1044, 1475 * my EISA card is 0x1144. 1476 */ 1477 if (id0 == 0x110e && (id1 == 0x1044 || id1 == 0x1144)) { 1478 bases[no_of_boards] = io_addr; 1479 no_of_boards++; 1480 } 1481 release_region(io_addr, 64); 1482 } 1483 } 1484 } 1485#endif 1486 if (!no_of_boards) { 1487 printk("sim710: No NCR53C710 adapter found.\n"); 1488 return 0; 1489 } 1490 1491 size = sizeof(struct sim710_hostdata); 1492 hostdata_order = 0; 1493 while (size > (PAGE_SIZE << hostdata_order)) 1494 hostdata_order++; 1495 size = PAGE_SIZE << hostdata_order; 1496 1497 DEB(DEB_ANY, printk("sim710: hostdata %d bytes, size %d, order %d\n", 1498 sizeof(struct sim710_hostdata), size, hostdata_order)); 1499 1500 tpnt->proc_name = "sim710"; 1501 1502 memset(our_hosts, 0, sizeof(our_hosts)); 1503 for (indx = 0; indx < no_of_boards; indx++) { 1504 unsigned long page = __get_free_pages(GFP_ATOMIC, hostdata_order); 1505 if(page == 0UL) 1506 { 1507 printk(KERN_WARNING "sim710: out of memory registering board %d.\n", indx); 1508 break; 1509 } 1510 host = scsi_register(tpnt, 4); 1511 if(host == NULL) { 1512 free_pages(host->hostdata[0], hostdata_order); 1513 break; 1514 } 1515 our_hosts[chips] = host; 1516 host->hostdata[0] = page; 1517 hostdata = (struct sim710_hostdata *)host->hostdata[0]; 1518 memset(hostdata, 0, size); 1519 scsi_id = 7; 1520 base_addr = bases[indx]; 1521 requested_irq = irq_vectors[indx]; 1522 printk("scsi%d: Configuring Sim710 (SCSI-ID %d) at %x, IRQ %d\n", 1523 host->host_no, scsi_id, base_addr, requested_irq); 1524 DEB(DEB_ANY, printk("sim710: hostdata = %p (%d bytes), dsa0 = %p\n", 1525 hostdata, sizeof(struct sim710_hostdata), 1526 hostdata->target[0].dsa)); 1527 hostdata->chip = indx; 1528 host->irq = requested_irq; 1529 host->this_id = scsi_id; 1530 host->unique_id = base_addr; 1531 host->base = base_addr; 1532 hostdata->msg_reject = MESSAGE_REJECT; 1533 1534 if (ncr_halt(host)) { 1535 free_pages(host->hostdata[0], hostdata_order); 1536 scsi_unregister (host); 1537 printk("scsi%d: Failed to initialise 53c710 at address %x\n", 1538 host->host_no, base_addr); 1539 continue; 1540 } 1541 DEB(DEB_ANY,ncr_dump(host)); 1542 revision = (NCR_read8(CTEST8_REG) & 0xF0) >> 4; 1543 printk("scsi%d: Revision 0x%x\n",host->host_no,revision); 1544 sim710_soft_reset(host); 1545 1546 sim710_driver_init(host); 1547 1548 request_region((u32)host->base, 64, "sim710"); 1549 /* Now run test1 */ 1550 hostdata->test1_src = 0x53c710aa; 1551 hostdata->test1_dst = 0x76543210; 1552 NCR_write32(DSPS_REG, 0x89abcdef); 1553 irq_mask = probe_irq_on(); 1554 NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_test1/4)); 1555 timeout = 5; 1556 while (hostdata->test1_dst != hostdata->test1_src && timeout--) 1557 mdelay(100); 1558 tmp = NCR_read8(ISTAT_REG); 1559 tmp = NCR_read8(SSTAT0_REG); 1560 udelay(10); 1561 tmp = NCR_read8(DSTAT_REG); 1562 probed_irq = probe_irq_off(irq_mask); 1563 if (requested_irq == 0) { 1564 if (probed_irq > 0) { 1565 printk("scsi%d: Chip is using IRQ %d\n", host->host_no, 1566 probed_irq); 1567 requested_irq = host->irq = probed_irq; 1568 } 1569 else { 1570 printk("scsi%d: Failed to probe for IRQ (returned %d)\n", 1571 host->host_no, probed_irq); 1572 ncr_halt(host); 1573 free_pages(host->hostdata[0], hostdata_order); 1574 scsi_unregister (host); 1575 release_region((u32)host->base, 64); 1576 continue; 1577 } 1578 } 1579 else if (probed_irq > 0 && probed_irq != requested_irq) 1580 printk("scsi%d: WARNING requested IRQ %d, but probed as %d\n", 1581 host->host_no, requested_irq, probed_irq); 1582 else if (probed_irq <= 0) 1583 printk("scsi%d: WARNING IRQ probe failed, (returned %d)\n", 1584 host->host_no, probed_irq); 1585 1586 dsps = NCR_read32(DSPS_REG); 1587 if (hostdata->test1_dst != 0x53c710aa || dsps != A_int_test1) { 1588 if (hostdata->test1_dst != 0x53c710aa) 1589 printk("scsi%d: test 1 FAILED: data: exp 0x53c710aa, got 0x%08x\n", 1590 host->host_no, hostdata->test1_dst); 1591 if (dsps != A_int_test1) 1592 printk("scsi%d: test 1 FAILED: dsps: exp 0x%08x, got 0x%08x\n", 1593 host->host_no, A_int_test1, dsps); 1594 ncr_dump(host); 1595 ncr_halt(host); 1596 free_pages(host->hostdata[0], hostdata_order); 1597 scsi_unregister (host); 1598 release_region((u32)host->base, 64); 1599 continue; 1600 } 1601 printk("scsi%d: test 1 completed ok.\n", host->host_no); 1602 1603 NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_reselect/4)); 1604 hostdata->state = STATE_IDLE; 1605 chips++; 1606 } 1607 /* OK, now run down our_hosts[] calling request_irq(... SA_SHIRQ ...). 1608 * Couldn't call request_irq earlier, as probing would have failed. 1609 */ 1610 for (indx = 0, limit = chips; indx < limit; indx++) { 1611 host = our_hosts[indx]; 1612 if (request_irq(host->irq, do_sim710_intr_handle, 1613 SA_INTERRUPT | SA_SHIRQ, "sim710", host)) 1614 { 1615 printk("scsi%d : IRQ%d not free, detaching\n", 1616 host->host_no, host->irq); 1617 ncr_halt(host); 1618 free_pages(host->hostdata[0], hostdata_order); 1619 scsi_unregister (host); 1620 chips--; 1621 } 1622 } 1623 1624 return chips; 1625} 1626 1627int 1628sim710_abort(Scsi_Cmnd * cmd) 1629{ 1630 struct Scsi_Host * host = cmd->host; 1631 1632 printk("scsi%d: Unable to abort command for target %d\n", 1633 host->host_no, cmd->target); 1634 return FAILED; 1635} 1636 1637/* 1638 * This is a device reset. Need to select and send a Bus Device Reset msg. 1639 */ 1640 1641int 1642sim710_dev_reset(Scsi_Cmnd * SCpnt) 1643{ 1644 struct Scsi_Host * host = SCpnt->host; 1645 1646 printk("scsi%d: Unable to send Bus Device Reset for target %d\n", 1647 host->host_no, SCpnt->target); 1648 return FAILED; 1649} 1650 1651/* 1652 * This is bus reset. We need to reset the bus and fail any active commands. 1653 */ 1654 1655int 1656sim710_bus_reset(Scsi_Cmnd * SCpnt) 1657{ 1658 struct Scsi_Host * host = SCpnt->host; 1659 1660 printk("scsi%d: Unable to do SCSI bus reset\n", host->host_no); 1661 return FAILED; 1662} 1663 1664static int 1665full_reset(struct Scsi_Host * host) 1666{ 1667 struct sim710_hostdata *hostdata = (struct sim710_hostdata *) 1668 host->hostdata[0]; 1669 int target; 1670 Scsi_Cmnd *cmd; 1671 u32 istat, dstat = 0, sstat0 = 0, sstat1 = 0, dsp, dsps, scratch; 1672 unsigned long flags; 1673 1674 save_flags(flags); 1675 cli(); 1676 1677 istat = NCR_read8(ISTAT_REG); 1678 if (istat & ISTAT_SIP) { 1679 sstat0 = NCR_read8(SSTAT0_REG); 1680 sstat1 = NCR_read8(SSTAT1_REG); 1681 udelay(10); 1682 } 1683 if (istat & ISTAT_DIP) 1684 dstat = NCR_read8(DSTAT_REG); 1685 1686 if (ncr_halt(host)) { 1687 restore_flags(flags); 1688 return FAILED; 1689 } 1690 restore_flags(flags); 1691 dsp = NCR_read32(DSP_REG); 1692 dsps = NCR_read32(DSPS_REG); 1693 scratch = NCR_read32(SCRATCH_REG); 1694 printk("scsi%d: istat = %02x, sstat0 = %02x, sstat1 = %02x, dstat = %02x\n", 1695 host->host_no, istat, sstat0, sstat1, dstat); 1696 printk("scsi%d: dsp = %08x (script[0x%04x]), dsps = %08x, scratch = %08x\n", 1697 host->host_no, dsp, 1698 ((u32)bus_to_virt(dsp) - (u32)hostdata->script)/4, dsps, scratch); 1699 1700 for (target = 0; target < 7; target++) { 1701 if ((cmd = hostdata->target[target].cur_cmd)) { 1702 printk("scsi%d: Failing command for ID%d\n", 1703 host->host_no, target); 1704 cmd->result = DID_RESET << 16; 1705 cmd->scsi_done(cmd); 1706 hostdata->target[target].cur_cmd = NULL; 1707 } 1708 } 1709 1710 sim710_soft_reset(host); 1711 sim710_driver_init(host); 1712 1713 NCR_write32(DSP_REG, virt_to_bus(hostdata->script+Ent_reselect/4)); 1714 hostdata->state = STATE_IDLE; 1715 1716 run_process_issue_queue(hostdata); 1717 1718 return SUCCESS; 1719} 1720 1721/* 1722 * This is host reset. We need to reset the chip and the bus. 1723 */ 1724 1725int 1726sim710_host_reset(Scsi_Cmnd * SCpnt) 1727{ 1728 struct Scsi_Host * host = SCpnt->host; 1729 1730 printk("scsi%d: >>>>>>>>>>>> Host reset <<<<<<<<<<<<\n", host->host_no); 1731 1732 return full_reset(host); 1733} 1734 1735#ifdef MODULE 1736 1737int 1738sim710_release(struct Scsi_Host *host) 1739{ 1740 ncr_halt(host); 1741 free_pages(host->hostdata[0], hostdata_order); 1742 free_irq(host->irq, host); 1743 release_region((u32)host->base, 64); 1744 return 1; 1745} 1746 1747#endif 1748 1749static Scsi_Host_Template driver_template = SIM710_SCSI; 1750 1751#include "scsi_module.c" 1752