1 /* 2 * linux/drivers/acorn/scsi/acornscsi.c 3 * 4 * Acorn SCSI 3 driver 5 * By R.M.King. 6 * 7 * This program is free software; you can redistribute it and/or modify 8 * it under the terms of the GNU General Public License version 2 as 9 * published by the Free Software Foundation. 10 * 11 * Abandoned using the Select and Transfer command since there were 12 * some nasty races between our software and the target devices that 13 * were not easy to solve, and the device errata had a lot of entries 14 * for this command, some of them quite nasty... 15 * 16 * Changelog: 17 * 26-Sep-1997 RMK Re-jigged to use the queue module. 18 * Re-coded state machine to be based on driver 19 * state not scsi state. Should be easier to debug. 20 * Added acornscsi_release to clean up properly. 21 * Updated proc/scsi reporting. 22 * 05-Oct-1997 RMK Implemented writing to SCSI devices. 23 * 06-Oct-1997 RMK Corrected small (non-serious) bug with the connect/ 24 * reconnect race condition causing a warning message. 25 * 12-Oct-1997 RMK Added catch for re-entering interrupt routine. 26 * 15-Oct-1997 RMK Improved handling of commands. 27 * 27-Jun-1998 RMK Changed asm/delay.h to linux/delay.h. 28 * 13-Dec-1998 RMK Better abort code and command handling. Extra state 29 * transitions added to allow dodgy devices to work. 30 */ 31 #define DEBUG_NO_WRITE 1 32 #define DEBUG_QUEUES 2 33 #define DEBUG_DMA 4 34 #define DEBUG_ABORT 8 35 #define DEBUG_DISCON 16 36 #define DEBUG_CONNECT 32 37 #define DEBUG_PHASES 64 38 #define DEBUG_WRITE 128 39 #define DEBUG_LINK 256 40 #define DEBUG_MESSAGES 512 41 #define DEBUG_RESET 1024 42 #define DEBUG_ALL (DEBUG_RESET|DEBUG_MESSAGES|DEBUG_LINK|DEBUG_WRITE|\ 43 DEBUG_PHASES|DEBUG_CONNECT|DEBUG_DISCON|DEBUG_ABORT|\ 44 DEBUG_DMA|DEBUG_QUEUES) 45 46 /* DRIVER CONFIGURATION 47 * 48 * SCSI-II Tagged queue support. 49 * 50 * I don't have any SCSI devices that support it, so it is totally untested 51 * (except to make sure that it doesn't interfere with any non-tagging 52 * devices). It is not fully implemented either - what happens when a 53 * tagging device reconnects??? 54 * 55 * You can tell if you have a device that supports tagged queueing my 56 * cating (eg) /proc/scsi/acornscsi/0 and see if the SCSI revision is reported 57 * as '2 TAG'. 58 * 59 * Also note that CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE is normally set in the config 60 * scripts, but disabled here. Once debugged, remove the #undef, otherwise to debug, 61 * comment out the undef. 62 */ 63 #undef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE 64 /* 65 * SCSI-II Linked command support. 66 * 67 * The higher level code doesn't support linked commands yet, and so the option 68 * is undef'd here. 69 */ 70 #undef CONFIG_SCSI_ACORNSCSI_LINK 71 /* 72 * SCSI-II Synchronous transfer support. 73 * 74 * Tried and tested... 75 * 76 * SDTR_SIZE - maximum number of un-acknowledged bytes (0 = off, 12 = max) 77 * SDTR_PERIOD - period of REQ signal (min=125, max=1020) 78 * DEFAULT_PERIOD - default REQ period. 79 */ 80 #define SDTR_SIZE 12 81 #define SDTR_PERIOD 125 82 #define DEFAULT_PERIOD 500 83 84 /* 85 * Debugging information 86 * 87 * DEBUG - bit mask from list above 88 * DEBUG_TARGET - is defined to the target number if you want to debug 89 * a specific target. [only recon/write/dma]. 90 */ 91 #define DEBUG (DEBUG_RESET|DEBUG_WRITE|DEBUG_NO_WRITE) 92 /* only allow writing to SCSI device 0 */ 93 #define NO_WRITE 0xFE 94 /*#define DEBUG_TARGET 2*/ 95 /* 96 * Select timeout time (in 10ms units) 97 * 98 * This is the timeout used between the start of selection and the WD33C93 99 * chip deciding that the device isn't responding. 100 */ 101 #define TIMEOUT_TIME 10 102 /* 103 * Define this if you want to have verbose explanation of SCSI 104 * status/messages. 105 */ 106 #undef CONFIG_ACORNSCSI_CONSTANTS 107 /* 108 * Define this if you want to use the on board DMAC [don't remove this option] 109 * If not set, then use PIO mode (not currently supported). 110 */ 111 #define USE_DMAC 112 113 /* 114 * ==================================================================================== 115 */ 116 117 #ifdef DEBUG_TARGET 118 #define DBG(cmd,xxx...) \ 119 if (cmd->device->id == DEBUG_TARGET) { \ 120 xxx; \ 121 } 122 #else 123 #define DBG(cmd,xxx...) xxx 124 #endif 125 126 #include <linux/module.h> 127 #include <linux/kernel.h> 128 #include <linux/string.h> 129 #include <linux/signal.h> 130 #include <linux/errno.h> 131 #include <linux/proc_fs.h> 132 #include <linux/ioport.h> 133 #include <linux/blkdev.h> 134 #include <linux/delay.h> 135 #include <linux/interrupt.h> 136 #include <linux/init.h> 137 #include <linux/bitops.h> 138 #include <linux/stringify.h> 139 #include <linux/io.h> 140 141 #include <asm/ecard.h> 142 143 #include "../scsi.h" 144 #include <scsi/scsi_dbg.h> 145 #include <scsi/scsi_host.h> 146 #include <scsi/scsi_transport_spi.h> 147 #include "acornscsi.h" 148 #include "msgqueue.h" 149 #include "scsi.h" 150 151 #include <scsi/scsicam.h> 152 153 #define VER_MAJOR 2 154 #define VER_MINOR 0 155 #define VER_PATCH 6 156 157 #ifndef ABORT_TAG 158 #define ABORT_TAG 0xd 159 #else 160 #error "Yippee! ABORT TAG is now defined! Remove this error!" 161 #endif 162 163 #ifdef CONFIG_SCSI_ACORNSCSI_LINK 164 #error SCSI2 LINKed commands not supported (yet)! 165 #endif 166 167 #ifdef USE_DMAC 168 /* 169 * DMAC setup parameters 170 */ 171 #define INIT_DEVCON0 (DEVCON0_RQL|DEVCON0_EXW|DEVCON0_CMP) 172 #define INIT_DEVCON1 (DEVCON1_BHLD) 173 #define DMAC_READ (MODECON_READ) 174 #define DMAC_WRITE (MODECON_WRITE) 175 #define INIT_SBICDMA (CTRL_DMABURST) 176 177 #define scsi_xferred have_data_in 178 179 /* 180 * Size of on-board DMA buffer 181 */ 182 #define DMAC_BUFFER_SIZE 65536 183 #endif 184 185 #define STATUS_BUFFER_TO_PRINT 24 186 187 unsigned int sdtr_period = SDTR_PERIOD; 188 unsigned int sdtr_size = SDTR_SIZE; 189 190 static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, 191 unsigned int result); 192 static int acornscsi_reconnect_finish(AS_Host *host); 193 static void acornscsi_dma_cleanup(AS_Host *host); 194 static void acornscsi_abortcmd(AS_Host *host, unsigned char tag); 195 196 /* ==================================================================================== 197 * Miscellaneous 198 */ 199 200 /* Offsets from MEMC base */ 201 #define SBIC_REGIDX 0x2000 202 #define SBIC_REGVAL 0x2004 203 #define DMAC_OFFSET 0x3000 204 205 /* Offsets from FAST IOC base */ 206 #define INT_REG 0x2000 207 #define PAGE_REG 0x3000 208 209 static inline void sbic_arm_write(AS_Host *host, unsigned int reg, unsigned int value) 210 { 211 writeb(reg, host->base + SBIC_REGIDX); 212 writeb(value, host->base + SBIC_REGVAL); 213 } 214 215 static inline int sbic_arm_read(AS_Host *host, unsigned int reg) 216 { 217 if(reg == SBIC_ASR) 218 return readl(host->base + SBIC_REGIDX) & 255; 219 writeb(reg, host->base + SBIC_REGIDX); 220 return readl(host->base + SBIC_REGVAL) & 255; 221 } 222 223 #define sbic_arm_writenext(host, val) writeb((val), (host)->base + SBIC_REGVAL) 224 #define sbic_arm_readnext(host) readb((host)->base + SBIC_REGVAL) 225 226 #ifdef USE_DMAC 227 #define dmac_read(host,reg) \ 228 readb((host)->base + DMAC_OFFSET + ((reg) << 2)) 229 230 #define dmac_write(host,reg,value) \ 231 ({ writeb((value), (host)->base + DMAC_OFFSET + ((reg) << 2)); }) 232 233 #define dmac_clearintr(host) writeb(0, (host)->fast + INT_REG) 234 235 static inline unsigned int dmac_address(AS_Host *host) 236 { 237 return dmac_read(host, DMAC_TXADRHI) << 16 | 238 dmac_read(host, DMAC_TXADRMD) << 8 | 239 dmac_read(host, DMAC_TXADRLO); 240 } 241 242 static 243 void acornscsi_dumpdma(AS_Host *host, char *where) 244 { 245 unsigned int mode, addr, len; 246 247 mode = dmac_read(host, DMAC_MODECON); 248 addr = dmac_address(host); 249 len = dmac_read(host, DMAC_TXCNTHI) << 8 | 250 dmac_read(host, DMAC_TXCNTLO); 251 252 printk("scsi%d: %s: DMAC %02x @%06x+%04x msk %02x, ", 253 host->host->host_no, where, 254 mode, addr, (len + 1) & 0xffff, 255 dmac_read(host, DMAC_MASKREG)); 256 257 printk("DMA @%06x, ", host->dma.start_addr); 258 printk("BH @%p +%04x, ", host->scsi.SCp.ptr, 259 host->scsi.SCp.this_residual); 260 printk("DT @+%04x ST @+%04x", host->dma.transferred, 261 host->scsi.SCp.scsi_xferred); 262 printk("\n"); 263 } 264 #endif 265 266 static 267 unsigned long acornscsi_sbic_xfcount(AS_Host *host) 268 { 269 unsigned long length; 270 271 length = sbic_arm_read(host, SBIC_TRANSCNTH) << 16; 272 length |= sbic_arm_readnext(host) << 8; 273 length |= sbic_arm_readnext(host); 274 275 return length; 276 } 277 278 static int 279 acornscsi_sbic_wait(AS_Host *host, int stat_mask, int stat, int timeout, char *msg) 280 { 281 int asr; 282 283 do { 284 asr = sbic_arm_read(host, SBIC_ASR); 285 286 if ((asr & stat_mask) == stat) 287 return 0; 288 289 udelay(1); 290 } while (--timeout); 291 292 printk("scsi%d: timeout while %s\n", host->host->host_no, msg); 293 294 return -1; 295 } 296 297 static 298 int acornscsi_sbic_issuecmd(AS_Host *host, int command) 299 { 300 if (acornscsi_sbic_wait(host, ASR_CIP, 0, 1000, "issuing command")) 301 return -1; 302 303 sbic_arm_write(host, SBIC_CMND, command); 304 305 return 0; 306 } 307 308 static void 309 acornscsi_csdelay(unsigned int cs) 310 { 311 unsigned long target_jiffies, flags; 312 313 target_jiffies = jiffies + 1 + cs * HZ / 100; 314 315 local_save_flags(flags); 316 local_irq_enable(); 317 318 while (time_before(jiffies, target_jiffies)) barrier(); 319 320 local_irq_restore(flags); 321 } 322 323 static 324 void acornscsi_resetcard(AS_Host *host) 325 { 326 unsigned int i, timeout; 327 328 /* assert reset line */ 329 host->card.page_reg = 0x80; 330 writeb(host->card.page_reg, host->fast + PAGE_REG); 331 332 /* wait 3 cs. SCSI standard says 25ms. */ 333 acornscsi_csdelay(3); 334 335 host->card.page_reg = 0; 336 writeb(host->card.page_reg, host->fast + PAGE_REG); 337 338 /* 339 * Should get a reset from the card 340 */ 341 timeout = 1000; 342 do { 343 if (readb(host->fast + INT_REG) & 8) 344 break; 345 udelay(1); 346 } while (--timeout); 347 348 if (timeout == 0) 349 printk("scsi%d: timeout while resetting card\n", 350 host->host->host_no); 351 352 sbic_arm_read(host, SBIC_ASR); 353 sbic_arm_read(host, SBIC_SSR); 354 355 /* setup sbic - WD33C93A */ 356 sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id); 357 sbic_arm_write(host, SBIC_CMND, CMND_RESET); 358 359 /* 360 * Command should cause a reset interrupt 361 */ 362 timeout = 1000; 363 do { 364 if (readb(host->fast + INT_REG) & 8) 365 break; 366 udelay(1); 367 } while (--timeout); 368 369 if (timeout == 0) 370 printk("scsi%d: timeout while resetting card\n", 371 host->host->host_no); 372 373 sbic_arm_read(host, SBIC_ASR); 374 if (sbic_arm_read(host, SBIC_SSR) != 0x01) 375 printk(KERN_CRIT "scsi%d: WD33C93A didn't give enhanced reset interrupt\n", 376 host->host->host_no); 377 378 sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI); 379 sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME); 380 sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA); 381 sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); 382 383 host->card.page_reg = 0x40; 384 writeb(host->card.page_reg, host->fast + PAGE_REG); 385 386 /* setup dmac - uPC71071 */ 387 dmac_write(host, DMAC_INIT, 0); 388 #ifdef USE_DMAC 389 dmac_write(host, DMAC_INIT, INIT_8BIT); 390 dmac_write(host, DMAC_CHANNEL, CHANNEL_0); 391 dmac_write(host, DMAC_DEVCON0, INIT_DEVCON0); 392 dmac_write(host, DMAC_DEVCON1, INIT_DEVCON1); 393 #endif 394 395 host->SCpnt = NULL; 396 host->scsi.phase = PHASE_IDLE; 397 host->scsi.disconnectable = 0; 398 399 memset(host->busyluns, 0, sizeof(host->busyluns)); 400 401 for (i = 0; i < 8; i++) { 402 host->device[i].sync_state = SYNC_NEGOCIATE; 403 host->device[i].disconnect_ok = 1; 404 } 405 406 /* wait 25 cs. SCSI standard says 250ms. */ 407 acornscsi_csdelay(25); 408 } 409 410 /*============================================================================================= 411 * Utility routines (eg. debug) 412 */ 413 #ifdef CONFIG_ACORNSCSI_CONSTANTS 414 static char *acornscsi_interrupttype[] = { 415 "rst", "suc", "p/a", "3", 416 "term", "5", "6", "7", 417 "serv", "9", "a", "b", 418 "c", "d", "e", "f" 419 }; 420 421 static signed char acornscsi_map[] = { 422 0, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 423 -1, 2, -1, -1, -1, -1, 3, -1, 4, 5, 6, 7, 8, 9, 10, 11, 424 12, 13, 14, -1, -1, -1, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11, 425 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 426 15, 16, 17, 18, 19, -1, -1, 20, 4, 5, 6, 7, 8, 9, 10, 11, 427 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 428 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 429 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 430 21, 22, -1, -1, -1, 23, -1, -1, 4, 5, 6, 7, 8, 9, 10, 11, 431 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 432 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 433 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 434 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 435 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 436 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 437 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 438 }; 439 440 static char *acornscsi_interruptcode[] = { 441 /* 0 */ 442 "reset - normal mode", /* 00 */ 443 "reset - advanced mode", /* 01 */ 444 445 /* 2 */ 446 "sel", /* 11 */ 447 "sel+xfer", /* 16 */ 448 "data-out", /* 18 */ 449 "data-in", /* 19 */ 450 "cmd", /* 1A */ 451 "stat", /* 1B */ 452 "??-out", /* 1C */ 453 "??-in", /* 1D */ 454 "msg-out", /* 1E */ 455 "msg-in", /* 1F */ 456 457 /* 12 */ 458 "/ACK asserted", /* 20 */ 459 "save-data-ptr", /* 21 */ 460 "{re}sel", /* 22 */ 461 462 /* 15 */ 463 "inv cmd", /* 40 */ 464 "unexpected disconnect", /* 41 */ 465 "sel timeout", /* 42 */ 466 "P err", /* 43 */ 467 "P err+ATN", /* 44 */ 468 "bad status byte", /* 47 */ 469 470 /* 21 */ 471 "resel, no id", /* 80 */ 472 "resel", /* 81 */ 473 "discon", /* 85 */ 474 }; 475 476 static 477 void print_scsi_status(unsigned int ssr) 478 { 479 if (acornscsi_map[ssr] != -1) 480 printk("%s:%s", 481 acornscsi_interrupttype[(ssr >> 4)], 482 acornscsi_interruptcode[acornscsi_map[ssr]]); 483 else 484 printk("%X:%X", ssr >> 4, ssr & 0x0f); 485 } 486 #endif 487 488 static 489 void print_sbic_status(int asr, int ssr, int cmdphase) 490 { 491 #ifdef CONFIG_ACORNSCSI_CONSTANTS 492 printk("sbic: %c%c%c%c%c%c ", 493 asr & ASR_INT ? 'I' : 'i', 494 asr & ASR_LCI ? 'L' : 'l', 495 asr & ASR_BSY ? 'B' : 'b', 496 asr & ASR_CIP ? 'C' : 'c', 497 asr & ASR_PE ? 'P' : 'p', 498 asr & ASR_DBR ? 'D' : 'd'); 499 printk("scsi: "); 500 print_scsi_status(ssr); 501 printk(" ph %02X\n", cmdphase); 502 #else 503 printk("sbic: %02X scsi: %X:%X ph: %02X\n", 504 asr, (ssr & 0xf0)>>4, ssr & 0x0f, cmdphase); 505 #endif 506 } 507 508 static void 509 acornscsi_dumplogline(AS_Host *host, int target, int line) 510 { 511 unsigned long prev; 512 signed int ptr; 513 514 ptr = host->status_ptr[target] - STATUS_BUFFER_TO_PRINT; 515 if (ptr < 0) 516 ptr += STATUS_BUFFER_SIZE; 517 518 printk("%c: %3s:", target == 8 ? 'H' : '0' + target, 519 line == 0 ? "ph" : line == 1 ? "ssr" : "int"); 520 521 prev = host->status[target][ptr].when; 522 523 for (; ptr != host->status_ptr[target]; ptr = (ptr + 1) & (STATUS_BUFFER_SIZE - 1)) { 524 unsigned long time_diff; 525 526 if (!host->status[target][ptr].when) 527 continue; 528 529 switch (line) { 530 case 0: 531 printk("%c%02X", host->status[target][ptr].irq ? '-' : ' ', 532 host->status[target][ptr].ph); 533 break; 534 535 case 1: 536 printk(" %02X", host->status[target][ptr].ssr); 537 break; 538 539 case 2: 540 time_diff = host->status[target][ptr].when - prev; 541 prev = host->status[target][ptr].when; 542 if (time_diff == 0) 543 printk("==^"); 544 else if (time_diff >= 100) 545 printk(" "); 546 else 547 printk(" %02ld", time_diff); 548 break; 549 } 550 } 551 552 printk("\n"); 553 } 554 555 static 556 void acornscsi_dumplog(AS_Host *host, int target) 557 { 558 do { 559 acornscsi_dumplogline(host, target, 0); 560 acornscsi_dumplogline(host, target, 1); 561 acornscsi_dumplogline(host, target, 2); 562 563 if (target == 8) 564 break; 565 566 target = 8; 567 } while (1); 568 } 569 570 static 571 char acornscsi_target(AS_Host *host) 572 { 573 if (host->SCpnt) 574 return '0' + host->SCpnt->device->id; 575 return 'H'; 576 } 577 578 /* 579 * Prototype: cmdtype_t acornscsi_cmdtype(int command) 580 * Purpose : differentiate READ from WRITE from other commands 581 * Params : command - command to interpret 582 * Returns : CMD_READ - command reads data, 583 * CMD_WRITE - command writes data, 584 * CMD_MISC - everything else 585 */ 586 static inline 587 cmdtype_t acornscsi_cmdtype(int command) 588 { 589 switch (command) { 590 case WRITE_6: case WRITE_10: case WRITE_12: 591 return CMD_WRITE; 592 case READ_6: case READ_10: case READ_12: 593 return CMD_READ; 594 default: 595 return CMD_MISC; 596 } 597 } 598 599 /* 600 * Prototype: int acornscsi_datadirection(int command) 601 * Purpose : differentiate between commands that have a DATA IN phase 602 * and a DATA OUT phase 603 * Params : command - command to interpret 604 * Returns : DATADIR_OUT - data out phase expected 605 * DATADIR_IN - data in phase expected 606 */ 607 static 608 datadir_t acornscsi_datadirection(int command) 609 { 610 switch (command) { 611 case CHANGE_DEFINITION: case COMPARE: case COPY: 612 case COPY_VERIFY: case LOG_SELECT: case MODE_SELECT: 613 case MODE_SELECT_10: case SEND_DIAGNOSTIC: case WRITE_BUFFER: 614 case FORMAT_UNIT: case REASSIGN_BLOCKS: case RESERVE: 615 case SEARCH_EQUAL: case SEARCH_HIGH: case SEARCH_LOW: 616 case WRITE_6: case WRITE_10: case WRITE_VERIFY: 617 case UPDATE_BLOCK: case WRITE_LONG: case WRITE_SAME: 618 case SEARCH_HIGH_12: case SEARCH_EQUAL_12: case SEARCH_LOW_12: 619 case WRITE_12: case WRITE_VERIFY_12: case SET_WINDOW: 620 case MEDIUM_SCAN: case SEND_VOLUME_TAG: case 0xea: 621 return DATADIR_OUT; 622 default: 623 return DATADIR_IN; 624 } 625 } 626 627 /* 628 * Purpose : provide values for synchronous transfers with 33C93. 629 * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting 630 * Modified by Russell King for 8MHz WD33C93A 631 */ 632 static struct sync_xfer_tbl { 633 unsigned int period_ns; 634 unsigned char reg_value; 635 } sync_xfer_table[] = { 636 { 1, 0x20 }, { 249, 0x20 }, { 374, 0x30 }, 637 { 499, 0x40 }, { 624, 0x50 }, { 749, 0x60 }, 638 { 874, 0x70 }, { 999, 0x00 }, { 0, 0 } 639 }; 640 641 /* 642 * Prototype: int acornscsi_getperiod(unsigned char syncxfer) 643 * Purpose : period for the synchronous transfer setting 644 * Params : syncxfer SYNCXFER register value 645 * Returns : period in ns. 646 */ 647 static 648 int acornscsi_getperiod(unsigned char syncxfer) 649 { 650 int i; 651 652 syncxfer &= 0xf0; 653 if (syncxfer == 0x10) 654 syncxfer = 0; 655 656 for (i = 1; sync_xfer_table[i].period_ns; i++) 657 if (syncxfer == sync_xfer_table[i].reg_value) 658 return sync_xfer_table[i].period_ns; 659 return 0; 660 } 661 662 /* 663 * Prototype: int round_period(unsigned int period) 664 * Purpose : return index into above table for a required REQ period 665 * Params : period - time (ns) for REQ 666 * Returns : table index 667 * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting 668 */ 669 static inline 670 int round_period(unsigned int period) 671 { 672 int i; 673 674 for (i = 1; sync_xfer_table[i].period_ns; i++) { 675 if ((period <= sync_xfer_table[i].period_ns) && 676 (period > sync_xfer_table[i - 1].period_ns)) 677 return i; 678 } 679 return 7; 680 } 681 682 /* 683 * Prototype: unsigned char calc_sync_xfer(unsigned int period, unsigned int offset) 684 * Purpose : calculate value for 33c93s SYNC register 685 * Params : period - time (ns) for REQ 686 * offset - offset in bytes between REQ/ACK 687 * Returns : value for SYNC register 688 * Copyright: Copyright (c) 1996 John Shifflett, GeoLog Consulting 689 */ 690 static 691 unsigned char calc_sync_xfer(unsigned int period, unsigned int offset) 692 { 693 return sync_xfer_table[round_period(period)].reg_value | 694 ((offset < SDTR_SIZE) ? offset : SDTR_SIZE); 695 } 696 697 /* ==================================================================================== 698 * Command functions 699 */ 700 /* 701 * Function: acornscsi_kick(AS_Host *host) 702 * Purpose : kick next command to interface 703 * Params : host - host to send command to 704 * Returns : INTR_IDLE if idle, otherwise INTR_PROCESSING 705 * Notes : interrupts are always disabled! 706 */ 707 static 708 intr_ret_t acornscsi_kick(AS_Host *host) 709 { 710 int from_queue = 0; 711 struct scsi_cmnd *SCpnt; 712 713 /* first check to see if a command is waiting to be executed */ 714 SCpnt = host->origSCpnt; 715 host->origSCpnt = NULL; 716 717 /* retrieve next command */ 718 if (!SCpnt) { 719 SCpnt = queue_remove_exclude(&host->queues.issue, host->busyluns); 720 if (!SCpnt) 721 return INTR_IDLE; 722 723 from_queue = 1; 724 } 725 726 if (host->scsi.disconnectable && host->SCpnt) { 727 queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt); 728 host->scsi.disconnectable = 0; 729 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON)) 730 DBG(host->SCpnt, printk("scsi%d.%c: moved command to disconnected queue\n", 731 host->host->host_no, acornscsi_target(host))); 732 #endif 733 host->SCpnt = NULL; 734 } 735 736 /* 737 * If we have an interrupt pending, then we may have been reselected. 738 * In this case, we don't want to write to the registers 739 */ 740 if (!(sbic_arm_read(host, SBIC_ASR) & (ASR_INT|ASR_BSY|ASR_CIP))) { 741 sbic_arm_write(host, SBIC_DESTID, SCpnt->device->id); 742 sbic_arm_write(host, SBIC_CMND, CMND_SELWITHATN); 743 } 744 745 /* 746 * claim host busy - all of these must happen atomically wrt 747 * our interrupt routine. Failure means command loss. 748 */ 749 host->scsi.phase = PHASE_CONNECTING; 750 host->SCpnt = SCpnt; 751 host->scsi.SCp = SCpnt->SCp; 752 host->dma.xfer_setup = 0; 753 host->dma.xfer_required = 0; 754 host->dma.xfer_done = 0; 755 756 #if (DEBUG & (DEBUG_ABORT|DEBUG_CONNECT)) 757 DBG(SCpnt,printk("scsi%d.%c: starting cmd %02X\n", 758 host->host->host_no, '0' + SCpnt->device->id, 759 SCpnt->cmnd[0])); 760 #endif 761 762 if (from_queue) { 763 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE 764 /* 765 * tagged queueing - allocate a new tag to this command 766 */ 767 if (SCpnt->device->simple_tags) { 768 SCpnt->device->current_tag += 1; 769 if (SCpnt->device->current_tag == 0) 770 SCpnt->device->current_tag = 1; 771 SCpnt->tag = SCpnt->device->current_tag; 772 } else 773 #endif 774 set_bit(SCpnt->device->id * 8 + SCpnt->device->lun, host->busyluns); 775 776 host->stats.removes += 1; 777 778 switch (acornscsi_cmdtype(SCpnt->cmnd[0])) { 779 case CMD_WRITE: 780 host->stats.writes += 1; 781 break; 782 case CMD_READ: 783 host->stats.reads += 1; 784 break; 785 case CMD_MISC: 786 host->stats.miscs += 1; 787 break; 788 } 789 } 790 791 return INTR_PROCESSING; 792 } 793 794 /* 795 * Function: void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, unsigned int result) 796 * Purpose : complete processing for command 797 * Params : host - interface that completed 798 * result - driver byte of result 799 */ 800 static void acornscsi_done(AS_Host *host, struct scsi_cmnd **SCpntp, 801 unsigned int result) 802 { 803 struct scsi_cmnd *SCpnt = *SCpntp; 804 805 /* clean up */ 806 sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); 807 808 host->stats.fins += 1; 809 810 if (SCpnt) { 811 *SCpntp = NULL; 812 813 acornscsi_dma_cleanup(host); 814 815 SCpnt->result = result << 16 | host->scsi.SCp.Message << 8 | host->scsi.SCp.Status; 816 817 /* 818 * In theory, this should not happen. In practice, it seems to. 819 * Only trigger an error if the device attempts to report all happy 820 * but with untransferred buffers... If we don't do something, then 821 * data loss will occur. Should we check SCpnt->underflow here? 822 * It doesn't appear to be set to something meaningful by the higher 823 * levels all the time. 824 */ 825 if (result == DID_OK) { 826 int xfer_warn = 0; 827 828 if (SCpnt->underflow == 0) { 829 if (host->scsi.SCp.ptr && 830 acornscsi_cmdtype(SCpnt->cmnd[0]) != CMD_MISC) 831 xfer_warn = 1; 832 } else { 833 if (host->scsi.SCp.scsi_xferred < SCpnt->underflow || 834 host->scsi.SCp.scsi_xferred != host->dma.transferred) 835 xfer_warn = 1; 836 } 837 838 /* ANSI standard says: (SCSI-2 Rev 10c Sect 5.6.6) 839 * Targets which break data transfers into multiple 840 * connections shall end each successful connection 841 * (except possibly the last) with a SAVE DATA 842 * POINTER - DISCONNECT message sequence. 843 * 844 * This makes it difficult to ensure that a transfer has 845 * completed. If we reach the end of a transfer during 846 * the command, then we can only have finished the transfer. 847 * therefore, if we seem to have some data remaining, this 848 * is not a problem. 849 */ 850 if (host->dma.xfer_done) 851 xfer_warn = 0; 852 853 if (xfer_warn) { 854 switch (status_byte(SCpnt->result)) { 855 case CHECK_CONDITION: 856 case COMMAND_TERMINATED: 857 case BUSY: 858 case QUEUE_FULL: 859 case RESERVATION_CONFLICT: 860 break; 861 862 default: 863 printk(KERN_ERR "scsi%d.H: incomplete data transfer detected: result=%08X command=", 864 host->host->host_no, SCpnt->result); 865 __scsi_print_command(SCpnt->cmnd); 866 acornscsi_dumpdma(host, "done"); 867 acornscsi_dumplog(host, SCpnt->device->id); 868 SCpnt->result &= 0xffff; 869 SCpnt->result |= DID_ERROR << 16; 870 } 871 } 872 } 873 874 if (!SCpnt->scsi_done) 875 panic("scsi%d.H: null scsi_done function in acornscsi_done", host->host->host_no); 876 877 clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, host->busyluns); 878 879 SCpnt->scsi_done(SCpnt); 880 } else 881 printk("scsi%d: null command in acornscsi_done", host->host->host_no); 882 883 host->scsi.phase = PHASE_IDLE; 884 } 885 886 /* ==================================================================================== 887 * DMA routines 888 */ 889 /* 890 * Purpose : update SCSI Data Pointer 891 * Notes : this will only be one SG entry or less 892 */ 893 static 894 void acornscsi_data_updateptr(AS_Host *host, struct scsi_pointer *SCp, unsigned int length) 895 { 896 SCp->ptr += length; 897 SCp->this_residual -= length; 898 899 if (SCp->this_residual == 0 && next_SCp(SCp) == 0) 900 host->dma.xfer_done = 1; 901 } 902 903 /* 904 * Prototype: void acornscsi_data_read(AS_Host *host, char *ptr, 905 * unsigned int start_addr, unsigned int length) 906 * Purpose : read data from DMA RAM 907 * Params : host - host to transfer from 908 * ptr - DRAM address 909 * start_addr - host mem address 910 * length - number of bytes to transfer 911 * Notes : this will only be one SG entry or less 912 */ 913 static 914 void acornscsi_data_read(AS_Host *host, char *ptr, 915 unsigned int start_addr, unsigned int length) 916 { 917 extern void __acornscsi_in(void __iomem *, char *buf, int len); 918 unsigned int page, offset, len = length; 919 920 page = (start_addr >> 12); 921 offset = start_addr & ((1 << 12) - 1); 922 923 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG); 924 925 while (len > 0) { 926 unsigned int this_len; 927 928 if (len + offset > (1 << 12)) 929 this_len = (1 << 12) - offset; 930 else 931 this_len = len; 932 933 __acornscsi_in(host->base + (offset << 1), ptr, this_len); 934 935 offset += this_len; 936 ptr += this_len; 937 len -= this_len; 938 939 if (offset == (1 << 12)) { 940 offset = 0; 941 page ++; 942 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG); 943 } 944 } 945 writeb(host->card.page_reg, host->fast + PAGE_REG); 946 } 947 948 /* 949 * Prototype: void acornscsi_data_write(AS_Host *host, char *ptr, 950 * unsigned int start_addr, unsigned int length) 951 * Purpose : write data to DMA RAM 952 * Params : host - host to transfer from 953 * ptr - DRAM address 954 * start_addr - host mem address 955 * length - number of bytes to transfer 956 * Notes : this will only be one SG entry or less 957 */ 958 static 959 void acornscsi_data_write(AS_Host *host, char *ptr, 960 unsigned int start_addr, unsigned int length) 961 { 962 extern void __acornscsi_out(void __iomem *, char *buf, int len); 963 unsigned int page, offset, len = length; 964 965 page = (start_addr >> 12); 966 offset = start_addr & ((1 << 12) - 1); 967 968 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG); 969 970 while (len > 0) { 971 unsigned int this_len; 972 973 if (len + offset > (1 << 12)) 974 this_len = (1 << 12) - offset; 975 else 976 this_len = len; 977 978 __acornscsi_out(host->base + (offset << 1), ptr, this_len); 979 980 offset += this_len; 981 ptr += this_len; 982 len -= this_len; 983 984 if (offset == (1 << 12)) { 985 offset = 0; 986 page ++; 987 writeb((page & 0x3f) | host->card.page_reg, host->fast + PAGE_REG); 988 } 989 } 990 writeb(host->card.page_reg, host->fast + PAGE_REG); 991 } 992 993 /* ========================================================================================= 994 * On-board DMA routines 995 */ 996 #ifdef USE_DMAC 997 /* 998 * Prototype: void acornscsi_dmastop(AS_Host *host) 999 * Purpose : stop all DMA 1000 * Params : host - host on which to stop DMA 1001 * Notes : This is called when leaving DATA IN/OUT phase, 1002 * or when interface is RESET 1003 */ 1004 static inline 1005 void acornscsi_dma_stop(AS_Host *host) 1006 { 1007 dmac_write(host, DMAC_MASKREG, MASK_ON); 1008 dmac_clearintr(host); 1009 1010 #if (DEBUG & DEBUG_DMA) 1011 DBG(host->SCpnt, acornscsi_dumpdma(host, "stop")); 1012 #endif 1013 } 1014 1015 /* 1016 * Function: void acornscsi_dma_setup(AS_Host *host, dmadir_t direction) 1017 * Purpose : setup DMA controller for data transfer 1018 * Params : host - host to setup 1019 * direction - data transfer direction 1020 * Notes : This is called when entering DATA I/O phase, not 1021 * while we're in a DATA I/O phase 1022 */ 1023 static 1024 void acornscsi_dma_setup(AS_Host *host, dmadir_t direction) 1025 { 1026 unsigned int address, length, mode; 1027 1028 host->dma.direction = direction; 1029 1030 dmac_write(host, DMAC_MASKREG, MASK_ON); 1031 1032 if (direction == DMA_OUT) { 1033 #if (DEBUG & DEBUG_NO_WRITE) 1034 if (NO_WRITE & (1 << host->SCpnt->device->id)) { 1035 printk(KERN_CRIT "scsi%d.%c: I can't handle DMA_OUT!\n", 1036 host->host->host_no, acornscsi_target(host)); 1037 return; 1038 } 1039 #endif 1040 mode = DMAC_WRITE; 1041 } else 1042 mode = DMAC_READ; 1043 1044 /* 1045 * Allocate some buffer space, limited to half the buffer size 1046 */ 1047 length = min_t(unsigned int, host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2); 1048 if (length) { 1049 host->dma.start_addr = address = host->dma.free_addr; 1050 host->dma.free_addr = (host->dma.free_addr + length) & 1051 (DMAC_BUFFER_SIZE - 1); 1052 1053 /* 1054 * Transfer data to DMA memory 1055 */ 1056 if (direction == DMA_OUT) 1057 acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr, 1058 length); 1059 1060 length -= 1; 1061 dmac_write(host, DMAC_TXCNTLO, length); 1062 dmac_write(host, DMAC_TXCNTHI, length >> 8); 1063 dmac_write(host, DMAC_TXADRLO, address); 1064 dmac_write(host, DMAC_TXADRMD, address >> 8); 1065 dmac_write(host, DMAC_TXADRHI, 0); 1066 dmac_write(host, DMAC_MODECON, mode); 1067 dmac_write(host, DMAC_MASKREG, MASK_OFF); 1068 1069 #if (DEBUG & DEBUG_DMA) 1070 DBG(host->SCpnt, acornscsi_dumpdma(host, "strt")); 1071 #endif 1072 host->dma.xfer_setup = 1; 1073 } 1074 } 1075 1076 /* 1077 * Function: void acornscsi_dma_cleanup(AS_Host *host) 1078 * Purpose : ensure that all DMA transfers are up-to-date & host->scsi.SCp is correct 1079 * Params : host - host to finish 1080 * Notes : This is called when a command is: 1081 * terminating, RESTORE_POINTERS, SAVE_POINTERS, DISCONECT 1082 * : This must not return until all transfers are completed. 1083 */ 1084 static 1085 void acornscsi_dma_cleanup(AS_Host *host) 1086 { 1087 dmac_write(host, DMAC_MASKREG, MASK_ON); 1088 dmac_clearintr(host); 1089 1090 /* 1091 * Check for a pending transfer 1092 */ 1093 if (host->dma.xfer_required) { 1094 host->dma.xfer_required = 0; 1095 if (host->dma.direction == DMA_IN) 1096 acornscsi_data_read(host, host->dma.xfer_ptr, 1097 host->dma.xfer_start, host->dma.xfer_length); 1098 } 1099 1100 /* 1101 * Has a transfer been setup? 1102 */ 1103 if (host->dma.xfer_setup) { 1104 unsigned int transferred; 1105 1106 host->dma.xfer_setup = 0; 1107 1108 #if (DEBUG & DEBUG_DMA) 1109 DBG(host->SCpnt, acornscsi_dumpdma(host, "cupi")); 1110 #endif 1111 1112 /* 1113 * Calculate number of bytes transferred from DMA. 1114 */ 1115 transferred = dmac_address(host) - host->dma.start_addr; 1116 host->dma.transferred += transferred; 1117 1118 if (host->dma.direction == DMA_IN) 1119 acornscsi_data_read(host, host->scsi.SCp.ptr, 1120 host->dma.start_addr, transferred); 1121 1122 /* 1123 * Update SCSI pointers 1124 */ 1125 acornscsi_data_updateptr(host, &host->scsi.SCp, transferred); 1126 #if (DEBUG & DEBUG_DMA) 1127 DBG(host->SCpnt, acornscsi_dumpdma(host, "cupo")); 1128 #endif 1129 } 1130 } 1131 1132 /* 1133 * Function: void acornscsi_dmacintr(AS_Host *host) 1134 * Purpose : handle interrupts from DMAC device 1135 * Params : host - host to process 1136 * Notes : If reading, we schedule the read to main memory & 1137 * allow the transfer to continue. 1138 * : If writing, we fill the onboard DMA memory from main 1139 * memory. 1140 * : Called whenever DMAC finished it's current transfer. 1141 */ 1142 static 1143 void acornscsi_dma_intr(AS_Host *host) 1144 { 1145 unsigned int address, length, transferred; 1146 1147 #if (DEBUG & DEBUG_DMA) 1148 DBG(host->SCpnt, acornscsi_dumpdma(host, "inti")); 1149 #endif 1150 1151 dmac_write(host, DMAC_MASKREG, MASK_ON); 1152 dmac_clearintr(host); 1153 1154 /* 1155 * Calculate amount transferred via DMA 1156 */ 1157 transferred = dmac_address(host) - host->dma.start_addr; 1158 host->dma.transferred += transferred; 1159 1160 /* 1161 * Schedule DMA transfer off board 1162 */ 1163 if (host->dma.direction == DMA_IN) { 1164 host->dma.xfer_start = host->dma.start_addr; 1165 host->dma.xfer_length = transferred; 1166 host->dma.xfer_ptr = host->scsi.SCp.ptr; 1167 host->dma.xfer_required = 1; 1168 } 1169 1170 acornscsi_data_updateptr(host, &host->scsi.SCp, transferred); 1171 1172 /* 1173 * Allocate some buffer space, limited to half the on-board RAM size 1174 */ 1175 length = min_t(unsigned int, host->scsi.SCp.this_residual, DMAC_BUFFER_SIZE / 2); 1176 if (length) { 1177 host->dma.start_addr = address = host->dma.free_addr; 1178 host->dma.free_addr = (host->dma.free_addr + length) & 1179 (DMAC_BUFFER_SIZE - 1); 1180 1181 /* 1182 * Transfer data to DMA memory 1183 */ 1184 if (host->dma.direction == DMA_OUT) 1185 acornscsi_data_write(host, host->scsi.SCp.ptr, host->dma.start_addr, 1186 length); 1187 1188 length -= 1; 1189 dmac_write(host, DMAC_TXCNTLO, length); 1190 dmac_write(host, DMAC_TXCNTHI, length >> 8); 1191 dmac_write(host, DMAC_TXADRLO, address); 1192 dmac_write(host, DMAC_TXADRMD, address >> 8); 1193 dmac_write(host, DMAC_TXADRHI, 0); 1194 dmac_write(host, DMAC_MASKREG, MASK_OFF); 1195 1196 #if (DEBUG & DEBUG_DMA) 1197 DBG(host->SCpnt, acornscsi_dumpdma(host, "into")); 1198 #endif 1199 } else { 1200 host->dma.xfer_setup = 0; 1201 #if 0 1202 /* 1203 * If the interface still wants more, then this is an error. 1204 * We give it another byte, but we also attempt to raise an 1205 * attention condition. We continue giving one byte until 1206 * the device recognises the attention. 1207 */ 1208 if (dmac_read(host, DMAC_STATUS) & STATUS_RQ0) { 1209 acornscsi_abortcmd(host, host->SCpnt->tag); 1210 1211 dmac_write(host, DMAC_TXCNTLO, 0); 1212 dmac_write(host, DMAC_TXCNTHI, 0); 1213 dmac_write(host, DMAC_TXADRLO, 0); 1214 dmac_write(host, DMAC_TXADRMD, 0); 1215 dmac_write(host, DMAC_TXADRHI, 0); 1216 dmac_write(host, DMAC_MASKREG, MASK_OFF); 1217 } 1218 #endif 1219 } 1220 } 1221 1222 /* 1223 * Function: void acornscsi_dma_xfer(AS_Host *host) 1224 * Purpose : transfer data between AcornSCSI and memory 1225 * Params : host - host to process 1226 */ 1227 static 1228 void acornscsi_dma_xfer(AS_Host *host) 1229 { 1230 host->dma.xfer_required = 0; 1231 1232 if (host->dma.direction == DMA_IN) 1233 acornscsi_data_read(host, host->dma.xfer_ptr, 1234 host->dma.xfer_start, host->dma.xfer_length); 1235 } 1236 1237 /* 1238 * Function: void acornscsi_dma_adjust(AS_Host *host) 1239 * Purpose : adjust DMA pointers & count for bytes transferred to 1240 * SBIC but not SCSI bus. 1241 * Params : host - host to adjust DMA count for 1242 */ 1243 static 1244 void acornscsi_dma_adjust(AS_Host *host) 1245 { 1246 if (host->dma.xfer_setup) { 1247 signed long transferred; 1248 #if (DEBUG & (DEBUG_DMA|DEBUG_WRITE)) 1249 DBG(host->SCpnt, acornscsi_dumpdma(host, "adji")); 1250 #endif 1251 /* 1252 * Calculate correct DMA address - DMA is ahead of SCSI bus while 1253 * writing. 1254 * host->scsi.SCp.scsi_xferred is the number of bytes 1255 * actually transferred to/from the SCSI bus. 1256 * host->dma.transferred is the number of bytes transferred 1257 * over DMA since host->dma.start_addr was last set. 1258 * 1259 * real_dma_addr = host->dma.start_addr + host->scsi.SCp.scsi_xferred 1260 * - host->dma.transferred 1261 */ 1262 transferred = host->scsi.SCp.scsi_xferred - host->dma.transferred; 1263 if (transferred < 0) 1264 printk("scsi%d.%c: Ack! DMA write correction %ld < 0!\n", 1265 host->host->host_no, acornscsi_target(host), transferred); 1266 else if (transferred == 0) 1267 host->dma.xfer_setup = 0; 1268 else { 1269 transferred += host->dma.start_addr; 1270 dmac_write(host, DMAC_TXADRLO, transferred); 1271 dmac_write(host, DMAC_TXADRMD, transferred >> 8); 1272 dmac_write(host, DMAC_TXADRHI, transferred >> 16); 1273 #if (DEBUG & (DEBUG_DMA|DEBUG_WRITE)) 1274 DBG(host->SCpnt, acornscsi_dumpdma(host, "adjo")); 1275 #endif 1276 } 1277 } 1278 } 1279 #endif 1280 1281 /* ========================================================================================= 1282 * Data I/O 1283 */ 1284 static int 1285 acornscsi_write_pio(AS_Host *host, char *bytes, int *ptr, int len, unsigned int max_timeout) 1286 { 1287 unsigned int asr, timeout = max_timeout; 1288 int my_ptr = *ptr; 1289 1290 while (my_ptr < len) { 1291 asr = sbic_arm_read(host, SBIC_ASR); 1292 1293 if (asr & ASR_DBR) { 1294 timeout = max_timeout; 1295 1296 sbic_arm_write(host, SBIC_DATA, bytes[my_ptr++]); 1297 } else if (asr & ASR_INT) 1298 break; 1299 else if (--timeout == 0) 1300 break; 1301 udelay(1); 1302 } 1303 1304 *ptr = my_ptr; 1305 1306 return (timeout == 0) ? -1 : 0; 1307 } 1308 1309 /* 1310 * Function: void acornscsi_sendcommand(AS_Host *host) 1311 * Purpose : send a command to a target 1312 * Params : host - host which is connected to target 1313 */ 1314 static void 1315 acornscsi_sendcommand(AS_Host *host) 1316 { 1317 struct scsi_cmnd *SCpnt = host->SCpnt; 1318 1319 sbic_arm_write(host, SBIC_TRANSCNTH, 0); 1320 sbic_arm_writenext(host, 0); 1321 sbic_arm_writenext(host, SCpnt->cmd_len - host->scsi.SCp.sent_command); 1322 1323 acornscsi_sbic_issuecmd(host, CMND_XFERINFO); 1324 1325 if (acornscsi_write_pio(host, SCpnt->cmnd, 1326 (int *)&host->scsi.SCp.sent_command, SCpnt->cmd_len, 1000000)) 1327 printk("scsi%d: timeout while sending command\n", host->host->host_no); 1328 1329 host->scsi.phase = PHASE_COMMAND; 1330 } 1331 1332 static 1333 void acornscsi_sendmessage(AS_Host *host) 1334 { 1335 unsigned int message_length = msgqueue_msglength(&host->scsi.msgs); 1336 unsigned int msgnr; 1337 struct message *msg; 1338 1339 #if (DEBUG & DEBUG_MESSAGES) 1340 printk("scsi%d.%c: sending message ", 1341 host->host->host_no, acornscsi_target(host)); 1342 #endif 1343 1344 switch (message_length) { 1345 case 0: 1346 acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT); 1347 1348 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 1"); 1349 1350 sbic_arm_write(host, SBIC_DATA, NOP); 1351 1352 host->scsi.last_message = NOP; 1353 #if (DEBUG & DEBUG_MESSAGES) 1354 printk("NOP"); 1355 #endif 1356 break; 1357 1358 case 1: 1359 acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT); 1360 msg = msgqueue_getmsg(&host->scsi.msgs, 0); 1361 1362 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "sending message 2"); 1363 1364 sbic_arm_write(host, SBIC_DATA, msg->msg[0]); 1365 1366 host->scsi.last_message = msg->msg[0]; 1367 #if (DEBUG & DEBUG_MESSAGES) 1368 spi_print_msg(msg->msg); 1369 #endif 1370 break; 1371 1372 default: 1373 /* 1374 * ANSI standard says: (SCSI-2 Rev 10c Sect 5.6.14) 1375 * 'When a target sends this (MESSAGE_REJECT) message, it 1376 * shall change to MESSAGE IN phase and send this message 1377 * prior to requesting additional message bytes from the 1378 * initiator. This provides an interlock so that the 1379 * initiator can determine which message byte is rejected. 1380 */ 1381 sbic_arm_write(host, SBIC_TRANSCNTH, 0); 1382 sbic_arm_writenext(host, 0); 1383 sbic_arm_writenext(host, message_length); 1384 acornscsi_sbic_issuecmd(host, CMND_XFERINFO); 1385 1386 msgnr = 0; 1387 while ((msg = msgqueue_getmsg(&host->scsi.msgs, msgnr++)) != NULL) { 1388 unsigned int i; 1389 #if (DEBUG & DEBUG_MESSAGES) 1390 spi_print_msg(msg); 1391 #endif 1392 i = 0; 1393 if (acornscsi_write_pio(host, msg->msg, &i, msg->length, 1000000)) 1394 printk("scsi%d: timeout while sending message\n", host->host->host_no); 1395 1396 host->scsi.last_message = msg->msg[0]; 1397 if (msg->msg[0] == EXTENDED_MESSAGE) 1398 host->scsi.last_message |= msg->msg[2] << 8; 1399 1400 if (i != msg->length) 1401 break; 1402 } 1403 break; 1404 } 1405 #if (DEBUG & DEBUG_MESSAGES) 1406 printk("\n"); 1407 #endif 1408 } 1409 1410 /* 1411 * Function: void acornscsi_readstatusbyte(AS_Host *host) 1412 * Purpose : Read status byte from connected target 1413 * Params : host - host connected to target 1414 */ 1415 static 1416 void acornscsi_readstatusbyte(AS_Host *host) 1417 { 1418 acornscsi_sbic_issuecmd(host, CMND_XFERINFO|CMND_SBT); 1419 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "reading status byte"); 1420 host->scsi.SCp.Status = sbic_arm_read(host, SBIC_DATA); 1421 } 1422 1423 /* 1424 * Function: unsigned char acornscsi_readmessagebyte(AS_Host *host) 1425 * Purpose : Read one message byte from connected target 1426 * Params : host - host connected to target 1427 */ 1428 static 1429 unsigned char acornscsi_readmessagebyte(AS_Host *host) 1430 { 1431 unsigned char message; 1432 1433 acornscsi_sbic_issuecmd(host, CMND_XFERINFO | CMND_SBT); 1434 1435 acornscsi_sbic_wait(host, ASR_DBR, ASR_DBR, 1000, "for message byte"); 1436 1437 message = sbic_arm_read(host, SBIC_DATA); 1438 1439 /* wait for MSGIN-XFER-PAUSED */ 1440 acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after message byte"); 1441 1442 sbic_arm_read(host, SBIC_SSR); 1443 1444 return message; 1445 } 1446 1447 /* 1448 * Function: void acornscsi_message(AS_Host *host) 1449 * Purpose : Read complete message from connected target & action message 1450 * Params : host - host connected to target 1451 */ 1452 static 1453 void acornscsi_message(AS_Host *host) 1454 { 1455 unsigned char message[16]; 1456 unsigned int msgidx = 0, msglen = 1; 1457 1458 do { 1459 message[msgidx] = acornscsi_readmessagebyte(host); 1460 1461 switch (msgidx) { 1462 case 0: 1463 if (message[0] == EXTENDED_MESSAGE || 1464 (message[0] >= 0x20 && message[0] <= 0x2f)) 1465 msglen = 2; 1466 break; 1467 1468 case 1: 1469 if (message[0] == EXTENDED_MESSAGE) 1470 msglen += message[msgidx]; 1471 break; 1472 } 1473 msgidx += 1; 1474 if (msgidx < msglen) { 1475 acornscsi_sbic_issuecmd(host, CMND_NEGATEACK); 1476 1477 /* wait for next msg-in */ 1478 acornscsi_sbic_wait(host, ASR_INT, ASR_INT, 1000, "for interrupt after negate ack"); 1479 sbic_arm_read(host, SBIC_SSR); 1480 } 1481 } while (msgidx < msglen); 1482 1483 #if (DEBUG & DEBUG_MESSAGES) 1484 printk("scsi%d.%c: message in: ", 1485 host->host->host_no, acornscsi_target(host)); 1486 spi_print_msg(message); 1487 printk("\n"); 1488 #endif 1489 1490 if (host->scsi.phase == PHASE_RECONNECTED) { 1491 /* 1492 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.17) 1493 * 'Whenever a target reconnects to an initiator to continue 1494 * a tagged I/O process, the SIMPLE QUEUE TAG message shall 1495 * be sent immediately following the IDENTIFY message...' 1496 */ 1497 if (message[0] == SIMPLE_QUEUE_TAG) 1498 host->scsi.reconnected.tag = message[1]; 1499 if (acornscsi_reconnect_finish(host)) 1500 host->scsi.phase = PHASE_MSGIN; 1501 } 1502 1503 switch (message[0]) { 1504 case ABORT: 1505 case ABORT_TAG: 1506 case COMMAND_COMPLETE: 1507 if (host->scsi.phase != PHASE_STATUSIN) { 1508 printk(KERN_ERR "scsi%d.%c: command complete following non-status in phase?\n", 1509 host->host->host_no, acornscsi_target(host)); 1510 acornscsi_dumplog(host, host->SCpnt->device->id); 1511 } 1512 host->scsi.phase = PHASE_DONE; 1513 host->scsi.SCp.Message = message[0]; 1514 break; 1515 1516 case SAVE_POINTERS: 1517 /* 1518 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.20) 1519 * 'The SAVE DATA POINTER message is sent from a target to 1520 * direct the initiator to copy the active data pointer to 1521 * the saved data pointer for the current I/O process. 1522 */ 1523 acornscsi_dma_cleanup(host); 1524 host->SCpnt->SCp = host->scsi.SCp; 1525 host->SCpnt->SCp.sent_command = 0; 1526 host->scsi.phase = PHASE_MSGIN; 1527 break; 1528 1529 case RESTORE_POINTERS: 1530 /* 1531 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.19) 1532 * 'The RESTORE POINTERS message is sent from a target to 1533 * direct the initiator to copy the most recently saved 1534 * command, data, and status pointers for the I/O process 1535 * to the corresponding active pointers. The command and 1536 * status pointers shall be restored to the beginning of 1537 * the present command and status areas.' 1538 */ 1539 acornscsi_dma_cleanup(host); 1540 host->scsi.SCp = host->SCpnt->SCp; 1541 host->scsi.phase = PHASE_MSGIN; 1542 break; 1543 1544 case DISCONNECT: 1545 /* 1546 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 6.4.2) 1547 * 'On those occasions when an error or exception condition occurs 1548 * and the target elects to repeat the information transfer, the 1549 * target may repeat the transfer either issuing a RESTORE POINTERS 1550 * message or by disconnecting without issuing a SAVE POINTERS 1551 * message. When reconnection is completed, the most recent 1552 * saved pointer values are restored.' 1553 */ 1554 acornscsi_dma_cleanup(host); 1555 host->scsi.phase = PHASE_DISCONNECT; 1556 break; 1557 1558 case MESSAGE_REJECT: 1559 #if 0 /* this isn't needed any more */ 1560 /* 1561 * If we were negociating sync transfer, we don't yet know if 1562 * this REJECT is for the sync transfer or for the tagged queue/wide 1563 * transfer. Re-initiate sync transfer negotiation now, and if 1564 * we got a REJECT in response to SDTR, then it'll be set to DONE. 1565 */ 1566 if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST) 1567 host->device[host->SCpnt->device->id].sync_state = SYNC_NEGOCIATE; 1568 #endif 1569 1570 /* 1571 * If we have any messages waiting to go out, then assert ATN now 1572 */ 1573 if (msgqueue_msglength(&host->scsi.msgs)) 1574 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN); 1575 1576 switch (host->scsi.last_message) { 1577 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE 1578 case HEAD_OF_QUEUE_TAG: 1579 case ORDERED_QUEUE_TAG: 1580 case SIMPLE_QUEUE_TAG: 1581 /* 1582 * ANSI standard says: (Section SCSI-2 Rev. 10c Sect 5.6.17) 1583 * If a target does not implement tagged queuing and a queue tag 1584 * message is received, it shall respond with a MESSAGE REJECT 1585 * message and accept the I/O process as if it were untagged. 1586 */ 1587 printk(KERN_NOTICE "scsi%d.%c: disabling tagged queueing\n", 1588 host->host->host_no, acornscsi_target(host)); 1589 host->SCpnt->device->simple_tags = 0; 1590 set_bit(host->SCpnt->device->id * 8 + host->SCpnt->device->lun, host->busyluns); 1591 break; 1592 #endif 1593 case EXTENDED_MESSAGE | (EXTENDED_SDTR << 8): 1594 /* 1595 * Target can't handle synchronous transfers 1596 */ 1597 printk(KERN_NOTICE "scsi%d.%c: Using asynchronous transfer\n", 1598 host->host->host_no, acornscsi_target(host)); 1599 host->device[host->SCpnt->device->id].sync_xfer = SYNCHTRANSFER_2DBA; 1600 host->device[host->SCpnt->device->id].sync_state = SYNC_ASYNCHRONOUS; 1601 sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer); 1602 break; 1603 1604 default: 1605 break; 1606 } 1607 break; 1608 1609 case QUEUE_FULL: 1610 /* TODO: target queue is full */ 1611 break; 1612 1613 case SIMPLE_QUEUE_TAG: 1614 /* tag queue reconnect... message[1] = queue tag. Print something to indicate something happened! */ 1615 printk("scsi%d.%c: reconnect queue tag %02X\n", 1616 host->host->host_no, acornscsi_target(host), 1617 message[1]); 1618 break; 1619 1620 case EXTENDED_MESSAGE: 1621 switch (message[2]) { 1622 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC 1623 case EXTENDED_SDTR: 1624 if (host->device[host->SCpnt->device->id].sync_state == SYNC_SENT_REQUEST) { 1625 /* 1626 * We requested synchronous transfers. This isn't quite right... 1627 * We can only say if this succeeded if we proceed on to execute the 1628 * command from this message. If we get a MESSAGE PARITY ERROR, 1629 * and the target retries fail, then we fallback to asynchronous mode 1630 */ 1631 host->device[host->SCpnt->device->id].sync_state = SYNC_COMPLETED; 1632 printk(KERN_NOTICE "scsi%d.%c: Using synchronous transfer, offset %d, %d ns\n", 1633 host->host->host_no, acornscsi_target(host), 1634 message[4], message[3] * 4); 1635 host->device[host->SCpnt->device->id].sync_xfer = 1636 calc_sync_xfer(message[3] * 4, message[4]); 1637 } else { 1638 unsigned char period, length; 1639 /* 1640 * Target requested synchronous transfers. The agreement is only 1641 * to be in operation AFTER the target leaves message out phase. 1642 */ 1643 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN); 1644 period = max_t(unsigned int, message[3], sdtr_period / 4); 1645 length = min_t(unsigned int, message[4], sdtr_size); 1646 msgqueue_addmsg(&host->scsi.msgs, 5, EXTENDED_MESSAGE, 3, 1647 EXTENDED_SDTR, period, length); 1648 host->device[host->SCpnt->device->id].sync_xfer = 1649 calc_sync_xfer(period * 4, length); 1650 } 1651 sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer); 1652 break; 1653 #else 1654 /* We do not accept synchronous transfers. Respond with a 1655 * MESSAGE_REJECT. 1656 */ 1657 #endif 1658 1659 case EXTENDED_WDTR: 1660 /* The WD33C93A is only 8-bit. We respond with a MESSAGE_REJECT 1661 * to a wide data transfer request. 1662 */ 1663 default: 1664 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN); 1665 msgqueue_flush(&host->scsi.msgs); 1666 msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT); 1667 break; 1668 } 1669 break; 1670 1671 #ifdef CONFIG_SCSI_ACORNSCSI_LINK 1672 case LINKED_CMD_COMPLETE: 1673 case LINKED_FLG_CMD_COMPLETE: 1674 /* 1675 * We don't support linked commands yet 1676 */ 1677 if (0) { 1678 #if (DEBUG & DEBUG_LINK) 1679 printk("scsi%d.%c: lun %d tag %d linked command complete\n", 1680 host->host->host_no, acornscsi_target(host), host->SCpnt->tag); 1681 #endif 1682 /* 1683 * A linked command should only terminate with one of these messages 1684 * if there are more linked commands available. 1685 */ 1686 if (!host->SCpnt->next_link) { 1687 printk(KERN_WARNING "scsi%d.%c: lun %d tag %d linked command complete, but no next_link\n", 1688 instance->host_no, acornscsi_target(host), host->SCpnt->tag); 1689 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN); 1690 msgqueue_addmsg(&host->scsi.msgs, 1, ABORT); 1691 } else { 1692 struct scsi_cmnd *SCpnt = host->SCpnt; 1693 1694 acornscsi_dma_cleanup(host); 1695 1696 host->SCpnt = host->SCpnt->next_link; 1697 host->SCpnt->tag = SCpnt->tag; 1698 SCpnt->result = DID_OK | host->scsi.SCp.Message << 8 | host->Scsi.SCp.Status; 1699 SCpnt->done(SCpnt); 1700 1701 /* initialise host->SCpnt->SCp */ 1702 } 1703 break; 1704 } 1705 #endif 1706 1707 default: /* reject message */ 1708 printk(KERN_ERR "scsi%d.%c: unrecognised message %02X, rejecting\n", 1709 host->host->host_no, acornscsi_target(host), 1710 message[0]); 1711 acornscsi_sbic_issuecmd(host, CMND_ASSERTATN); 1712 msgqueue_flush(&host->scsi.msgs); 1713 msgqueue_addmsg(&host->scsi.msgs, 1, MESSAGE_REJECT); 1714 host->scsi.phase = PHASE_MSGIN; 1715 break; 1716 } 1717 acornscsi_sbic_issuecmd(host, CMND_NEGATEACK); 1718 } 1719 1720 /* 1721 * Function: int acornscsi_buildmessages(AS_Host *host) 1722 * Purpose : build the connection messages for a host 1723 * Params : host - host to add messages to 1724 */ 1725 static 1726 void acornscsi_buildmessages(AS_Host *host) 1727 { 1728 #if 0 1729 /* does the device need resetting? */ 1730 if (cmd_reset) { 1731 msgqueue_addmsg(&host->scsi.msgs, 1, BUS_DEVICE_RESET); 1732 return; 1733 } 1734 #endif 1735 1736 msgqueue_addmsg(&host->scsi.msgs, 1, 1737 IDENTIFY(host->device[host->SCpnt->device->id].disconnect_ok, 1738 host->SCpnt->device->lun)); 1739 1740 #if 0 1741 /* does the device need the current command aborted */ 1742 if (cmd_aborted) { 1743 acornscsi_abortcmd(host->SCpnt->tag); 1744 return; 1745 } 1746 #endif 1747 1748 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE 1749 if (host->SCpnt->tag) { 1750 unsigned int tag_type; 1751 1752 if (host->SCpnt->cmnd[0] == REQUEST_SENSE || 1753 host->SCpnt->cmnd[0] == TEST_UNIT_READY || 1754 host->SCpnt->cmnd[0] == INQUIRY) 1755 tag_type = HEAD_OF_QUEUE_TAG; 1756 else 1757 tag_type = SIMPLE_QUEUE_TAG; 1758 msgqueue_addmsg(&host->scsi.msgs, 2, tag_type, host->SCpnt->tag); 1759 } 1760 #endif 1761 1762 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC 1763 if (host->device[host->SCpnt->device->id].sync_state == SYNC_NEGOCIATE) { 1764 host->device[host->SCpnt->device->id].sync_state = SYNC_SENT_REQUEST; 1765 msgqueue_addmsg(&host->scsi.msgs, 5, 1766 EXTENDED_MESSAGE, 3, EXTENDED_SDTR, 1767 sdtr_period / 4, sdtr_size); 1768 } 1769 #endif 1770 } 1771 1772 /* 1773 * Function: int acornscsi_starttransfer(AS_Host *host) 1774 * Purpose : transfer data to/from connected target 1775 * Params : host - host to which target is connected 1776 * Returns : 0 if failure 1777 */ 1778 static 1779 int acornscsi_starttransfer(AS_Host *host) 1780 { 1781 int residual; 1782 1783 if (!host->scsi.SCp.ptr /*&& host->scsi.SCp.this_residual*/) { 1784 printk(KERN_ERR "scsi%d.%c: null buffer passed to acornscsi_starttransfer\n", 1785 host->host->host_no, acornscsi_target(host)); 1786 return 0; 1787 } 1788 1789 residual = scsi_bufflen(host->SCpnt) - host->scsi.SCp.scsi_xferred; 1790 1791 sbic_arm_write(host, SBIC_SYNCHTRANSFER, host->device[host->SCpnt->device->id].sync_xfer); 1792 sbic_arm_writenext(host, residual >> 16); 1793 sbic_arm_writenext(host, residual >> 8); 1794 sbic_arm_writenext(host, residual); 1795 acornscsi_sbic_issuecmd(host, CMND_XFERINFO); 1796 return 1; 1797 } 1798 1799 /* ========================================================================================= 1800 * Connection & Disconnection 1801 */ 1802 /* 1803 * Function : acornscsi_reconnect(AS_Host *host) 1804 * Purpose : reconnect a previously disconnected command 1805 * Params : host - host specific data 1806 * Remarks : SCSI spec says: 1807 * 'The set of active pointers is restored from the set 1808 * of saved pointers upon reconnection of the I/O process' 1809 */ 1810 static 1811 int acornscsi_reconnect(AS_Host *host) 1812 { 1813 unsigned int target, lun, ok = 0; 1814 1815 target = sbic_arm_read(host, SBIC_SOURCEID); 1816 1817 if (!(target & 8)) 1818 printk(KERN_ERR "scsi%d: invalid source id after reselection " 1819 "- device fault?\n", 1820 host->host->host_no); 1821 1822 target &= 7; 1823 1824 if (host->SCpnt && !host->scsi.disconnectable) { 1825 printk(KERN_ERR "scsi%d.%d: reconnected while command in " 1826 "progress to target %d?\n", 1827 host->host->host_no, target, host->SCpnt->device->id); 1828 host->SCpnt = NULL; 1829 } 1830 1831 lun = sbic_arm_read(host, SBIC_DATA) & 7; 1832 1833 host->scsi.reconnected.target = target; 1834 host->scsi.reconnected.lun = lun; 1835 host->scsi.reconnected.tag = 0; 1836 1837 if (host->scsi.disconnectable && host->SCpnt && 1838 host->SCpnt->device->id == target && host->SCpnt->device->lun == lun) 1839 ok = 1; 1840 1841 if (!ok && queue_probetgtlun(&host->queues.disconnected, target, lun)) 1842 ok = 1; 1843 1844 ADD_STATUS(target, 0x81, host->scsi.phase, 0); 1845 1846 if (ok) { 1847 host->scsi.phase = PHASE_RECONNECTED; 1848 } else { 1849 /* this doesn't seem to work */ 1850 printk(KERN_ERR "scsi%d.%c: reselected with no command " 1851 "to reconnect with\n", 1852 host->host->host_no, '0' + target); 1853 acornscsi_dumplog(host, target); 1854 acornscsi_abortcmd(host, 0); 1855 if (host->SCpnt) { 1856 queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt); 1857 host->SCpnt = NULL; 1858 } 1859 } 1860 acornscsi_sbic_issuecmd(host, CMND_NEGATEACK); 1861 return !ok; 1862 } 1863 1864 /* 1865 * Function: int acornscsi_reconect_finish(AS_Host *host) 1866 * Purpose : finish reconnecting a command 1867 * Params : host - host to complete 1868 * Returns : 0 if failed 1869 */ 1870 static 1871 int acornscsi_reconnect_finish(AS_Host *host) 1872 { 1873 if (host->scsi.disconnectable && host->SCpnt) { 1874 host->scsi.disconnectable = 0; 1875 if (host->SCpnt->device->id == host->scsi.reconnected.target && 1876 host->SCpnt->device->lun == host->scsi.reconnected.lun && 1877 host->SCpnt->tag == host->scsi.reconnected.tag) { 1878 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON)) 1879 DBG(host->SCpnt, printk("scsi%d.%c: reconnected", 1880 host->host->host_no, acornscsi_target(host))); 1881 #endif 1882 } else { 1883 queue_add_cmd_tail(&host->queues.disconnected, host->SCpnt); 1884 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON)) 1885 DBG(host->SCpnt, printk("scsi%d.%c: had to move command " 1886 "to disconnected queue\n", 1887 host->host->host_no, acornscsi_target(host))); 1888 #endif 1889 host->SCpnt = NULL; 1890 } 1891 } 1892 if (!host->SCpnt) { 1893 host->SCpnt = queue_remove_tgtluntag(&host->queues.disconnected, 1894 host->scsi.reconnected.target, 1895 host->scsi.reconnected.lun, 1896 host->scsi.reconnected.tag); 1897 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON)) 1898 DBG(host->SCpnt, printk("scsi%d.%c: had to get command", 1899 host->host->host_no, acornscsi_target(host))); 1900 #endif 1901 } 1902 1903 if (!host->SCpnt) 1904 acornscsi_abortcmd(host, host->scsi.reconnected.tag); 1905 else { 1906 /* 1907 * Restore data pointer from SAVED pointers. 1908 */ 1909 host->scsi.SCp = host->SCpnt->SCp; 1910 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON)) 1911 printk(", data pointers: [%p, %X]", 1912 host->scsi.SCp.ptr, host->scsi.SCp.this_residual); 1913 #endif 1914 } 1915 #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON)) 1916 printk("\n"); 1917 #endif 1918 1919 host->dma.transferred = host->scsi.SCp.scsi_xferred; 1920 1921 return host->SCpnt != NULL; 1922 } 1923 1924 /* 1925 * Function: void acornscsi_disconnect_unexpected(AS_Host *host) 1926 * Purpose : handle an unexpected disconnect 1927 * Params : host - host on which disconnect occurred 1928 */ 1929 static 1930 void acornscsi_disconnect_unexpected(AS_Host *host) 1931 { 1932 printk(KERN_ERR "scsi%d.%c: unexpected disconnect\n", 1933 host->host->host_no, acornscsi_target(host)); 1934 #if (DEBUG & DEBUG_ABORT) 1935 acornscsi_dumplog(host, 8); 1936 #endif 1937 1938 acornscsi_done(host, &host->SCpnt, DID_ERROR); 1939 } 1940 1941 /* 1942 * Function: void acornscsi_abortcmd(AS_host *host, unsigned char tag) 1943 * Purpose : abort a currently executing command 1944 * Params : host - host with connected command to abort 1945 * tag - tag to abort 1946 */ 1947 static 1948 void acornscsi_abortcmd(AS_Host *host, unsigned char tag) 1949 { 1950 host->scsi.phase = PHASE_ABORTED; 1951 sbic_arm_write(host, SBIC_CMND, CMND_ASSERTATN); 1952 1953 msgqueue_flush(&host->scsi.msgs); 1954 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE 1955 if (tag) 1956 msgqueue_addmsg(&host->scsi.msgs, 2, ABORT_TAG, tag); 1957 else 1958 #endif 1959 msgqueue_addmsg(&host->scsi.msgs, 1, ABORT); 1960 } 1961 1962 /* ========================================================================================== 1963 * Interrupt routines. 1964 */ 1965 /* 1966 * Function: int acornscsi_sbicintr(AS_Host *host) 1967 * Purpose : handle interrupts from SCSI device 1968 * Params : host - host to process 1969 * Returns : INTR_PROCESS if expecting another SBIC interrupt 1970 * INTR_IDLE if no interrupt 1971 * INTR_NEXT_COMMAND if we have finished processing the command 1972 */ 1973 static 1974 intr_ret_t acornscsi_sbicintr(AS_Host *host, int in_irq) 1975 { 1976 unsigned int asr, ssr; 1977 1978 asr = sbic_arm_read(host, SBIC_ASR); 1979 if (!(asr & ASR_INT)) 1980 return INTR_IDLE; 1981 1982 ssr = sbic_arm_read(host, SBIC_SSR); 1983 1984 #if (DEBUG & DEBUG_PHASES) 1985 print_sbic_status(asr, ssr, host->scsi.phase); 1986 #endif 1987 1988 ADD_STATUS(8, ssr, host->scsi.phase, in_irq); 1989 1990 if (host->SCpnt && !host->scsi.disconnectable) 1991 ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, in_irq); 1992 1993 switch (ssr) { 1994 case 0x00: /* reset state - not advanced */ 1995 printk(KERN_ERR "scsi%d: reset in standard mode but wanted advanced mode.\n", 1996 host->host->host_no); 1997 /* setup sbic - WD33C93A */ 1998 sbic_arm_write(host, SBIC_OWNID, OWNID_EAF | host->host->this_id); 1999 sbic_arm_write(host, SBIC_CMND, CMND_RESET); 2000 return INTR_IDLE; 2001 2002 case 0x01: /* reset state - advanced */ 2003 sbic_arm_write(host, SBIC_CTRL, INIT_SBICDMA | CTRL_IDI); 2004 sbic_arm_write(host, SBIC_TIMEOUT, TIMEOUT_TIME); 2005 sbic_arm_write(host, SBIC_SYNCHTRANSFER, SYNCHTRANSFER_2DBA); 2006 sbic_arm_write(host, SBIC_SOURCEID, SOURCEID_ER | SOURCEID_DSP); 2007 msgqueue_flush(&host->scsi.msgs); 2008 return INTR_IDLE; 2009 2010 case 0x41: /* unexpected disconnect aborted command */ 2011 acornscsi_disconnect_unexpected(host); 2012 return INTR_NEXT_COMMAND; 2013 } 2014 2015 switch (host->scsi.phase) { 2016 case PHASE_CONNECTING: /* STATE: command removed from issue queue */ 2017 switch (ssr) { 2018 case 0x11: /* -> PHASE_CONNECTED */ 2019 /* BUS FREE -> SELECTION */ 2020 host->scsi.phase = PHASE_CONNECTED; 2021 msgqueue_flush(&host->scsi.msgs); 2022 host->dma.transferred = host->scsi.SCp.scsi_xferred; 2023 /* 33C93 gives next interrupt indicating bus phase */ 2024 asr = sbic_arm_read(host, SBIC_ASR); 2025 if (!(asr & ASR_INT)) 2026 break; 2027 ssr = sbic_arm_read(host, SBIC_SSR); 2028 ADD_STATUS(8, ssr, host->scsi.phase, 1); 2029 ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, 1); 2030 goto connected; 2031 2032 case 0x42: /* select timed out */ 2033 /* -> PHASE_IDLE */ 2034 acornscsi_done(host, &host->SCpnt, DID_NO_CONNECT); 2035 return INTR_NEXT_COMMAND; 2036 2037 case 0x81: /* -> PHASE_RECONNECTED or PHASE_ABORTED */ 2038 /* BUS FREE -> RESELECTION */ 2039 host->origSCpnt = host->SCpnt; 2040 host->SCpnt = NULL; 2041 msgqueue_flush(&host->scsi.msgs); 2042 acornscsi_reconnect(host); 2043 break; 2044 2045 default: 2046 printk(KERN_ERR "scsi%d.%c: PHASE_CONNECTING, SSR %02X?\n", 2047 host->host->host_no, acornscsi_target(host), ssr); 2048 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2049 acornscsi_abortcmd(host, host->SCpnt->tag); 2050 } 2051 return INTR_PROCESSING; 2052 2053 connected: 2054 case PHASE_CONNECTED: /* STATE: device selected ok */ 2055 switch (ssr) { 2056 #ifdef NONSTANDARD 2057 case 0x8a: /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */ 2058 /* SELECTION -> COMMAND */ 2059 acornscsi_sendcommand(host); 2060 break; 2061 2062 case 0x8b: /* -> PHASE_STATUS */ 2063 /* SELECTION -> STATUS */ 2064 acornscsi_readstatusbyte(host); 2065 host->scsi.phase = PHASE_STATUSIN; 2066 break; 2067 #endif 2068 2069 case 0x8e: /* -> PHASE_MSGOUT */ 2070 /* SELECTION ->MESSAGE OUT */ 2071 host->scsi.phase = PHASE_MSGOUT; 2072 acornscsi_buildmessages(host); 2073 acornscsi_sendmessage(host); 2074 break; 2075 2076 /* these should not happen */ 2077 case 0x85: /* target disconnected */ 2078 acornscsi_done(host, &host->SCpnt, DID_ERROR); 2079 break; 2080 2081 default: 2082 printk(KERN_ERR "scsi%d.%c: PHASE_CONNECTED, SSR %02X?\n", 2083 host->host->host_no, acornscsi_target(host), ssr); 2084 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2085 acornscsi_abortcmd(host, host->SCpnt->tag); 2086 } 2087 return INTR_PROCESSING; 2088 2089 case PHASE_MSGOUT: /* STATE: connected & sent IDENTIFY message */ 2090 /* 2091 * SCSI standard says that MESSAGE OUT phases can be followed by a 2092 * DATA phase, STATUS phase, MESSAGE IN phase or COMMAND phase 2093 */ 2094 switch (ssr) { 2095 case 0x8a: /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */ 2096 case 0x1a: /* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */ 2097 /* MESSAGE OUT -> COMMAND */ 2098 acornscsi_sendcommand(host); 2099 break; 2100 2101 case 0x8b: /* -> PHASE_STATUS */ 2102 case 0x1b: /* -> PHASE_STATUS */ 2103 /* MESSAGE OUT -> STATUS */ 2104 acornscsi_readstatusbyte(host); 2105 host->scsi.phase = PHASE_STATUSIN; 2106 break; 2107 2108 case 0x8e: /* -> PHASE_MSGOUT */ 2109 /* MESSAGE_OUT(MESSAGE_IN) ->MESSAGE OUT */ 2110 acornscsi_sendmessage(host); 2111 break; 2112 2113 case 0x4f: /* -> PHASE_MSGIN, PHASE_DISCONNECT */ 2114 case 0x1f: /* -> PHASE_MSGIN, PHASE_DISCONNECT */ 2115 /* MESSAGE OUT -> MESSAGE IN */ 2116 acornscsi_message(host); 2117 break; 2118 2119 default: 2120 printk(KERN_ERR "scsi%d.%c: PHASE_MSGOUT, SSR %02X?\n", 2121 host->host->host_no, acornscsi_target(host), ssr); 2122 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2123 } 2124 return INTR_PROCESSING; 2125 2126 case PHASE_COMMAND: /* STATE: connected & command sent */ 2127 switch (ssr) { 2128 case 0x18: /* -> PHASE_DATAOUT */ 2129 /* COMMAND -> DATA OUT */ 2130 if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len) 2131 acornscsi_abortcmd(host, host->SCpnt->tag); 2132 acornscsi_dma_setup(host, DMA_OUT); 2133 if (!acornscsi_starttransfer(host)) 2134 acornscsi_abortcmd(host, host->SCpnt->tag); 2135 host->scsi.phase = PHASE_DATAOUT; 2136 return INTR_IDLE; 2137 2138 case 0x19: /* -> PHASE_DATAIN */ 2139 /* COMMAND -> DATA IN */ 2140 if (host->scsi.SCp.sent_command != host->SCpnt->cmd_len) 2141 acornscsi_abortcmd(host, host->SCpnt->tag); 2142 acornscsi_dma_setup(host, DMA_IN); 2143 if (!acornscsi_starttransfer(host)) 2144 acornscsi_abortcmd(host, host->SCpnt->tag); 2145 host->scsi.phase = PHASE_DATAIN; 2146 return INTR_IDLE; 2147 2148 case 0x1b: /* -> PHASE_STATUS */ 2149 /* COMMAND -> STATUS */ 2150 acornscsi_readstatusbyte(host); 2151 host->scsi.phase = PHASE_STATUSIN; 2152 break; 2153 2154 case 0x1e: /* -> PHASE_MSGOUT */ 2155 /* COMMAND -> MESSAGE OUT */ 2156 acornscsi_sendmessage(host); 2157 break; 2158 2159 case 0x1f: /* -> PHASE_MSGIN, PHASE_DISCONNECT */ 2160 /* COMMAND -> MESSAGE IN */ 2161 acornscsi_message(host); 2162 break; 2163 2164 default: 2165 printk(KERN_ERR "scsi%d.%c: PHASE_COMMAND, SSR %02X?\n", 2166 host->host->host_no, acornscsi_target(host), ssr); 2167 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2168 } 2169 return INTR_PROCESSING; 2170 2171 case PHASE_DISCONNECT: /* STATE: connected, received DISCONNECT msg */ 2172 if (ssr == 0x85) { /* -> PHASE_IDLE */ 2173 host->scsi.disconnectable = 1; 2174 host->scsi.reconnected.tag = 0; 2175 host->scsi.phase = PHASE_IDLE; 2176 host->stats.disconnects += 1; 2177 } else { 2178 printk(KERN_ERR "scsi%d.%c: PHASE_DISCONNECT, SSR %02X instead of disconnect?\n", 2179 host->host->host_no, acornscsi_target(host), ssr); 2180 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2181 } 2182 return INTR_NEXT_COMMAND; 2183 2184 case PHASE_IDLE: /* STATE: disconnected */ 2185 if (ssr == 0x81) /* -> PHASE_RECONNECTED or PHASE_ABORTED */ 2186 acornscsi_reconnect(host); 2187 else { 2188 printk(KERN_ERR "scsi%d.%c: PHASE_IDLE, SSR %02X while idle?\n", 2189 host->host->host_no, acornscsi_target(host), ssr); 2190 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2191 } 2192 return INTR_PROCESSING; 2193 2194 case PHASE_RECONNECTED: /* STATE: device reconnected to initiator */ 2195 /* 2196 * Command reconnected - if MESGIN, get message - it may be 2197 * the tag. If not, get command out of disconnected queue 2198 */ 2199 /* 2200 * If we reconnected and we're not in MESSAGE IN phase after IDENTIFY, 2201 * reconnect I_T_L command 2202 */ 2203 if (ssr != 0x8f && !acornscsi_reconnect_finish(host)) 2204 return INTR_IDLE; 2205 ADD_STATUS(host->SCpnt->device->id, ssr, host->scsi.phase, in_irq); 2206 switch (ssr) { 2207 case 0x88: /* data out phase */ 2208 /* -> PHASE_DATAOUT */ 2209 /* MESSAGE IN -> DATA OUT */ 2210 acornscsi_dma_setup(host, DMA_OUT); 2211 if (!acornscsi_starttransfer(host)) 2212 acornscsi_abortcmd(host, host->SCpnt->tag); 2213 host->scsi.phase = PHASE_DATAOUT; 2214 return INTR_IDLE; 2215 2216 case 0x89: /* data in phase */ 2217 /* -> PHASE_DATAIN */ 2218 /* MESSAGE IN -> DATA IN */ 2219 acornscsi_dma_setup(host, DMA_IN); 2220 if (!acornscsi_starttransfer(host)) 2221 acornscsi_abortcmd(host, host->SCpnt->tag); 2222 host->scsi.phase = PHASE_DATAIN; 2223 return INTR_IDLE; 2224 2225 case 0x8a: /* command out */ 2226 /* MESSAGE IN -> COMMAND */ 2227 acornscsi_sendcommand(host);/* -> PHASE_COMMAND, PHASE_COMMANDPAUSED */ 2228 break; 2229 2230 case 0x8b: /* status in */ 2231 /* -> PHASE_STATUSIN */ 2232 /* MESSAGE IN -> STATUS */ 2233 acornscsi_readstatusbyte(host); 2234 host->scsi.phase = PHASE_STATUSIN; 2235 break; 2236 2237 case 0x8e: /* message out */ 2238 /* -> PHASE_MSGOUT */ 2239 /* MESSAGE IN -> MESSAGE OUT */ 2240 acornscsi_sendmessage(host); 2241 break; 2242 2243 case 0x8f: /* message in */ 2244 acornscsi_message(host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */ 2245 break; 2246 2247 default: 2248 printk(KERN_ERR "scsi%d.%c: PHASE_RECONNECTED, SSR %02X after reconnect?\n", 2249 host->host->host_no, acornscsi_target(host), ssr); 2250 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2251 } 2252 return INTR_PROCESSING; 2253 2254 case PHASE_DATAIN: /* STATE: transferred data in */ 2255 /* 2256 * This is simple - if we disconnect then the DMA address & count is 2257 * correct. 2258 */ 2259 switch (ssr) { 2260 case 0x19: /* -> PHASE_DATAIN */ 2261 case 0x89: /* -> PHASE_DATAIN */ 2262 acornscsi_abortcmd(host, host->SCpnt->tag); 2263 return INTR_IDLE; 2264 2265 case 0x1b: /* -> PHASE_STATUSIN */ 2266 case 0x4b: /* -> PHASE_STATUSIN */ 2267 case 0x8b: /* -> PHASE_STATUSIN */ 2268 /* DATA IN -> STATUS */ 2269 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) - 2270 acornscsi_sbic_xfcount(host); 2271 acornscsi_dma_stop(host); 2272 acornscsi_readstatusbyte(host); 2273 host->scsi.phase = PHASE_STATUSIN; 2274 break; 2275 2276 case 0x1e: /* -> PHASE_MSGOUT */ 2277 case 0x4e: /* -> PHASE_MSGOUT */ 2278 case 0x8e: /* -> PHASE_MSGOUT */ 2279 /* DATA IN -> MESSAGE OUT */ 2280 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) - 2281 acornscsi_sbic_xfcount(host); 2282 acornscsi_dma_stop(host); 2283 acornscsi_sendmessage(host); 2284 break; 2285 2286 case 0x1f: /* message in */ 2287 case 0x4f: /* message in */ 2288 case 0x8f: /* message in */ 2289 /* DATA IN -> MESSAGE IN */ 2290 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) - 2291 acornscsi_sbic_xfcount(host); 2292 acornscsi_dma_stop(host); 2293 acornscsi_message(host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */ 2294 break; 2295 2296 default: 2297 printk(KERN_ERR "scsi%d.%c: PHASE_DATAIN, SSR %02X?\n", 2298 host->host->host_no, acornscsi_target(host), ssr); 2299 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2300 } 2301 return INTR_PROCESSING; 2302 2303 case PHASE_DATAOUT: /* STATE: transferred data out */ 2304 /* 2305 * This is more complicated - if we disconnect, the DMA could be 12 2306 * bytes ahead of us. We need to correct this. 2307 */ 2308 switch (ssr) { 2309 case 0x18: /* -> PHASE_DATAOUT */ 2310 case 0x88: /* -> PHASE_DATAOUT */ 2311 acornscsi_abortcmd(host, host->SCpnt->tag); 2312 return INTR_IDLE; 2313 2314 case 0x1b: /* -> PHASE_STATUSIN */ 2315 case 0x4b: /* -> PHASE_STATUSIN */ 2316 case 0x8b: /* -> PHASE_STATUSIN */ 2317 /* DATA OUT -> STATUS */ 2318 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) - 2319 acornscsi_sbic_xfcount(host); 2320 acornscsi_dma_stop(host); 2321 acornscsi_dma_adjust(host); 2322 acornscsi_readstatusbyte(host); 2323 host->scsi.phase = PHASE_STATUSIN; 2324 break; 2325 2326 case 0x1e: /* -> PHASE_MSGOUT */ 2327 case 0x4e: /* -> PHASE_MSGOUT */ 2328 case 0x8e: /* -> PHASE_MSGOUT */ 2329 /* DATA OUT -> MESSAGE OUT */ 2330 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) - 2331 acornscsi_sbic_xfcount(host); 2332 acornscsi_dma_stop(host); 2333 acornscsi_dma_adjust(host); 2334 acornscsi_sendmessage(host); 2335 break; 2336 2337 case 0x1f: /* message in */ 2338 case 0x4f: /* message in */ 2339 case 0x8f: /* message in */ 2340 /* DATA OUT -> MESSAGE IN */ 2341 host->scsi.SCp.scsi_xferred = scsi_bufflen(host->SCpnt) - 2342 acornscsi_sbic_xfcount(host); 2343 acornscsi_dma_stop(host); 2344 acornscsi_dma_adjust(host); 2345 acornscsi_message(host); /* -> PHASE_MSGIN, PHASE_DISCONNECT */ 2346 break; 2347 2348 default: 2349 printk(KERN_ERR "scsi%d.%c: PHASE_DATAOUT, SSR %02X?\n", 2350 host->host->host_no, acornscsi_target(host), ssr); 2351 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2352 } 2353 return INTR_PROCESSING; 2354 2355 case PHASE_STATUSIN: /* STATE: status in complete */ 2356 switch (ssr) { 2357 case 0x1f: /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */ 2358 case 0x8f: /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */ 2359 /* STATUS -> MESSAGE IN */ 2360 acornscsi_message(host); 2361 break; 2362 2363 case 0x1e: /* -> PHASE_MSGOUT */ 2364 case 0x8e: /* -> PHASE_MSGOUT */ 2365 /* STATUS -> MESSAGE OUT */ 2366 acornscsi_sendmessage(host); 2367 break; 2368 2369 default: 2370 printk(KERN_ERR "scsi%d.%c: PHASE_STATUSIN, SSR %02X instead of MESSAGE_IN?\n", 2371 host->host->host_no, acornscsi_target(host), ssr); 2372 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2373 } 2374 return INTR_PROCESSING; 2375 2376 case PHASE_MSGIN: /* STATE: message in */ 2377 switch (ssr) { 2378 case 0x1e: /* -> PHASE_MSGOUT */ 2379 case 0x4e: /* -> PHASE_MSGOUT */ 2380 case 0x8e: /* -> PHASE_MSGOUT */ 2381 /* MESSAGE IN -> MESSAGE OUT */ 2382 acornscsi_sendmessage(host); 2383 break; 2384 2385 case 0x1f: /* -> PHASE_MSGIN, PHASE_DONE, PHASE_DISCONNECT */ 2386 case 0x2f: 2387 case 0x4f: 2388 case 0x8f: 2389 acornscsi_message(host); 2390 break; 2391 2392 case 0x85: 2393 printk("scsi%d.%c: strange message in disconnection\n", 2394 host->host->host_no, acornscsi_target(host)); 2395 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2396 acornscsi_done(host, &host->SCpnt, DID_ERROR); 2397 break; 2398 2399 default: 2400 printk(KERN_ERR "scsi%d.%c: PHASE_MSGIN, SSR %02X after message in?\n", 2401 host->host->host_no, acornscsi_target(host), ssr); 2402 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2403 } 2404 return INTR_PROCESSING; 2405 2406 case PHASE_DONE: /* STATE: received status & message */ 2407 switch (ssr) { 2408 case 0x85: /* -> PHASE_IDLE */ 2409 acornscsi_done(host, &host->SCpnt, DID_OK); 2410 return INTR_NEXT_COMMAND; 2411 2412 case 0x1e: 2413 case 0x8e: 2414 acornscsi_sendmessage(host); 2415 break; 2416 2417 default: 2418 printk(KERN_ERR "scsi%d.%c: PHASE_DONE, SSR %02X instead of disconnect?\n", 2419 host->host->host_no, acornscsi_target(host), ssr); 2420 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2421 } 2422 return INTR_PROCESSING; 2423 2424 case PHASE_ABORTED: 2425 switch (ssr) { 2426 case 0x85: 2427 if (host->SCpnt) 2428 acornscsi_done(host, &host->SCpnt, DID_ABORT); 2429 else { 2430 clear_bit(host->scsi.reconnected.target * 8 + host->scsi.reconnected.lun, 2431 host->busyluns); 2432 host->scsi.phase = PHASE_IDLE; 2433 } 2434 return INTR_NEXT_COMMAND; 2435 2436 case 0x1e: 2437 case 0x2e: 2438 case 0x4e: 2439 case 0x8e: 2440 acornscsi_sendmessage(host); 2441 break; 2442 2443 default: 2444 printk(KERN_ERR "scsi%d.%c: PHASE_ABORTED, SSR %02X?\n", 2445 host->host->host_no, acornscsi_target(host), ssr); 2446 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2447 } 2448 return INTR_PROCESSING; 2449 2450 default: 2451 printk(KERN_ERR "scsi%d.%c: unknown driver phase %d\n", 2452 host->host->host_no, acornscsi_target(host), ssr); 2453 acornscsi_dumplog(host, host->SCpnt ? host->SCpnt->device->id : 8); 2454 } 2455 return INTR_PROCESSING; 2456 } 2457 2458 /* 2459 * Prototype: void acornscsi_intr(int irq, void *dev_id) 2460 * Purpose : handle interrupts from Acorn SCSI card 2461 * Params : irq - interrupt number 2462 * dev_id - device specific data (AS_Host structure) 2463 */ 2464 static irqreturn_t 2465 acornscsi_intr(int irq, void *dev_id) 2466 { 2467 AS_Host *host = (AS_Host *)dev_id; 2468 intr_ret_t ret; 2469 int iostatus; 2470 int in_irq = 0; 2471 2472 do { 2473 ret = INTR_IDLE; 2474 2475 iostatus = readb(host->fast + INT_REG); 2476 2477 if (iostatus & 2) { 2478 acornscsi_dma_intr(host); 2479 iostatus = readb(host->fast + INT_REG); 2480 } 2481 2482 if (iostatus & 8) 2483 ret = acornscsi_sbicintr(host, in_irq); 2484 2485 /* 2486 * If we have a transfer pending, start it. 2487 * Only start it if the interface has already started transferring 2488 * it's data 2489 */ 2490 if (host->dma.xfer_required) 2491 acornscsi_dma_xfer(host); 2492 2493 if (ret == INTR_NEXT_COMMAND) 2494 ret = acornscsi_kick(host); 2495 2496 in_irq = 1; 2497 } while (ret != INTR_IDLE); 2498 2499 return IRQ_HANDLED; 2500 } 2501 2502 /*============================================================================================= 2503 * Interfaces between interrupt handler and rest of scsi code 2504 */ 2505 2506 /* 2507 * Function : acornscsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) 2508 * Purpose : queues a SCSI command 2509 * Params : cmd - SCSI command 2510 * done - function called on completion, with pointer to command descriptor 2511 * Returns : 0, or < 0 on error. 2512 */ 2513 static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt, 2514 void (*done)(struct scsi_cmnd *)) 2515 { 2516 AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata; 2517 2518 if (!done) { 2519 /* there should be some way of rejecting errors like this without panicing... */ 2520 panic("scsi%d: queuecommand called with NULL done function [cmd=%p]", 2521 host->host->host_no, SCpnt); 2522 return -EINVAL; 2523 } 2524 2525 #if (DEBUG & DEBUG_NO_WRITE) 2526 if (acornscsi_cmdtype(SCpnt->cmnd[0]) == CMD_WRITE && (NO_WRITE & (1 << SCpnt->device->id))) { 2527 printk(KERN_CRIT "scsi%d.%c: WRITE attempted with NO_WRITE flag set\n", 2528 host->host->host_no, '0' + SCpnt->device->id); 2529 SCpnt->result = DID_NO_CONNECT << 16; 2530 done(SCpnt); 2531 return 0; 2532 } 2533 #endif 2534 2535 SCpnt->scsi_done = done; 2536 SCpnt->host_scribble = NULL; 2537 SCpnt->result = 0; 2538 SCpnt->tag = 0; 2539 SCpnt->SCp.phase = (int)acornscsi_datadirection(SCpnt->cmnd[0]); 2540 SCpnt->SCp.sent_command = 0; 2541 SCpnt->SCp.scsi_xferred = 0; 2542 2543 init_SCp(SCpnt); 2544 2545 host->stats.queues += 1; 2546 2547 { 2548 unsigned long flags; 2549 2550 if (!queue_add_cmd_ordered(&host->queues.issue, SCpnt)) { 2551 SCpnt->result = DID_ERROR << 16; 2552 done(SCpnt); 2553 return 0; 2554 } 2555 local_irq_save(flags); 2556 if (host->scsi.phase == PHASE_IDLE) 2557 acornscsi_kick(host); 2558 local_irq_restore(flags); 2559 } 2560 return 0; 2561 } 2562 2563 DEF_SCSI_QCMD(acornscsi_queuecmd) 2564 2565 /* 2566 * Prototype: void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, struct scsi_cmnd **SCpntp2, int result) 2567 * Purpose : pass a result to *SCpntp1, and check if *SCpntp1 = *SCpntp2 2568 * Params : SCpntp1 - pointer to command to return 2569 * SCpntp2 - pointer to command to check 2570 * result - result to pass back to mid-level done function 2571 * Returns : *SCpntp2 = NULL if *SCpntp1 is the same command structure as *SCpntp2. 2572 */ 2573 static inline void acornscsi_reportstatus(struct scsi_cmnd **SCpntp1, 2574 struct scsi_cmnd **SCpntp2, 2575 int result) 2576 { 2577 struct scsi_cmnd *SCpnt = *SCpntp1; 2578 2579 if (SCpnt) { 2580 *SCpntp1 = NULL; 2581 2582 SCpnt->result = result; 2583 SCpnt->scsi_done(SCpnt); 2584 } 2585 2586 if (SCpnt == *SCpntp2) 2587 *SCpntp2 = NULL; 2588 } 2589 2590 enum res_abort { res_not_running, res_success, res_success_clear, res_snooze }; 2591 2592 /* 2593 * Prototype: enum res acornscsi_do_abort(struct scsi_cmnd *SCpnt) 2594 * Purpose : abort a command on this host 2595 * Params : SCpnt - command to abort 2596 * Returns : our abort status 2597 */ 2598 static enum res_abort acornscsi_do_abort(AS_Host *host, struct scsi_cmnd *SCpnt) 2599 { 2600 enum res_abort res = res_not_running; 2601 2602 if (queue_remove_cmd(&host->queues.issue, SCpnt)) { 2603 /* 2604 * The command was on the issue queue, and has not been 2605 * issued yet. We can remove the command from the queue, 2606 * and acknowledge the abort. Neither the devices nor the 2607 * interface know about the command. 2608 */ 2609 //#if (DEBUG & DEBUG_ABORT) 2610 printk("on issue queue "); 2611 //#endif 2612 res = res_success; 2613 } else if (queue_remove_cmd(&host->queues.disconnected, SCpnt)) { 2614 /* 2615 * The command was on the disconnected queue. Simply 2616 * acknowledge the abort condition, and when the target 2617 * reconnects, we will give it an ABORT message. The 2618 * target should then disconnect, and we will clear 2619 * the busylun bit. 2620 */ 2621 //#if (DEBUG & DEBUG_ABORT) 2622 printk("on disconnected queue "); 2623 //#endif 2624 res = res_success; 2625 } else if (host->SCpnt == SCpnt) { 2626 unsigned long flags; 2627 2628 //#if (DEBUG & DEBUG_ABORT) 2629 printk("executing "); 2630 //#endif 2631 2632 local_irq_save(flags); 2633 switch (host->scsi.phase) { 2634 /* 2635 * If the interface is idle, and the command is 'disconnectable', 2636 * then it is the same as on the disconnected queue. We simply 2637 * remove all traces of the command. When the target reconnects, 2638 * we will give it an ABORT message since the command could not 2639 * be found. When the target finally disconnects, we will clear 2640 * the busylun bit. 2641 */ 2642 case PHASE_IDLE: 2643 if (host->scsi.disconnectable) { 2644 host->scsi.disconnectable = 0; 2645 host->SCpnt = NULL; 2646 res = res_success; 2647 } 2648 break; 2649 2650 /* 2651 * If the command has connected and done nothing further, 2652 * simply force a disconnect. We also need to clear the 2653 * busylun bit. 2654 */ 2655 case PHASE_CONNECTED: 2656 sbic_arm_write(host, SBIC_CMND, CMND_DISCONNECT); 2657 host->SCpnt = NULL; 2658 res = res_success_clear; 2659 break; 2660 2661 default: 2662 acornscsi_abortcmd(host, host->SCpnt->tag); 2663 res = res_snooze; 2664 } 2665 local_irq_restore(flags); 2666 } else if (host->origSCpnt == SCpnt) { 2667 /* 2668 * The command will be executed next, but a command 2669 * is currently using the interface. This is similar to 2670 * being on the issue queue, except the busylun bit has 2671 * been set. 2672 */ 2673 host->origSCpnt = NULL; 2674 //#if (DEBUG & DEBUG_ABORT) 2675 printk("waiting for execution "); 2676 //#endif 2677 res = res_success_clear; 2678 } else 2679 printk("unknown "); 2680 2681 return res; 2682 } 2683 2684 /* 2685 * Prototype: int acornscsi_abort(struct scsi_cmnd *SCpnt) 2686 * Purpose : abort a command on this host 2687 * Params : SCpnt - command to abort 2688 * Returns : one of SCSI_ABORT_ macros 2689 */ 2690 int acornscsi_abort(struct scsi_cmnd *SCpnt) 2691 { 2692 AS_Host *host = (AS_Host *) SCpnt->device->host->hostdata; 2693 int result; 2694 2695 host->stats.aborts += 1; 2696 2697 #if (DEBUG & DEBUG_ABORT) 2698 { 2699 int asr, ssr; 2700 asr = sbic_arm_read(host, SBIC_ASR); 2701 ssr = sbic_arm_read(host, SBIC_SSR); 2702 2703 printk(KERN_WARNING "acornscsi_abort: "); 2704 print_sbic_status(asr, ssr, host->scsi.phase); 2705 acornscsi_dumplog(host, SCpnt->device->id); 2706 } 2707 #endif 2708 2709 printk("scsi%d: ", host->host->host_no); 2710 2711 switch (acornscsi_do_abort(host, SCpnt)) { 2712 /* 2713 * We managed to find the command and cleared it out. 2714 * We do not expect the command to be executing on the 2715 * target, but we have set the busylun bit. 2716 */ 2717 case res_success_clear: 2718 //#if (DEBUG & DEBUG_ABORT) 2719 printk("clear "); 2720 //#endif 2721 clear_bit(SCpnt->device->id * 8 + SCpnt->device->lun, host->busyluns); 2722 2723 /* 2724 * We found the command, and cleared it out. Either 2725 * the command is still known to be executing on the 2726 * target, or the busylun bit is not set. 2727 */ 2728 case res_success: 2729 //#if (DEBUG & DEBUG_ABORT) 2730 printk("success\n"); 2731 //#endif 2732 result = SUCCESS; 2733 break; 2734 2735 /* 2736 * We did find the command, but unfortunately we couldn't 2737 * unhook it from ourselves. Wait some more, and if it 2738 * still doesn't complete, reset the interface. 2739 */ 2740 case res_snooze: 2741 //#if (DEBUG & DEBUG_ABORT) 2742 printk("snooze\n"); 2743 //#endif 2744 result = FAILED; 2745 break; 2746 2747 /* 2748 * The command could not be found (either because it completed, 2749 * or it got dropped. 2750 */ 2751 default: 2752 case res_not_running: 2753 acornscsi_dumplog(host, SCpnt->device->id); 2754 result = FAILED; 2755 //#if (DEBUG & DEBUG_ABORT) 2756 printk("not running\n"); 2757 //#endif 2758 break; 2759 } 2760 2761 return result; 2762 } 2763 2764 /* 2765 * Prototype: int acornscsi_reset(struct scsi_cmnd *SCpnt) 2766 * Purpose : reset a command on this host/reset this host 2767 * Params : SCpnt - command causing reset 2768 * Returns : one of SCSI_RESET_ macros 2769 */ 2770 int acornscsi_bus_reset(struct scsi_cmnd *SCpnt) 2771 { 2772 AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata; 2773 struct scsi_cmnd *SCptr; 2774 2775 host->stats.resets += 1; 2776 2777 #if (DEBUG & DEBUG_RESET) 2778 { 2779 int asr, ssr; 2780 2781 asr = sbic_arm_read(host, SBIC_ASR); 2782 ssr = sbic_arm_read(host, SBIC_SSR); 2783 2784 printk(KERN_WARNING "acornscsi_reset: "); 2785 print_sbic_status(asr, ssr, host->scsi.phase); 2786 acornscsi_dumplog(host, SCpnt->device->id); 2787 } 2788 #endif 2789 2790 acornscsi_dma_stop(host); 2791 2792 /* 2793 * do hard reset. This resets all devices on this host, and so we 2794 * must set the reset status on all commands. 2795 */ 2796 acornscsi_resetcard(host); 2797 2798 while ((SCptr = queue_remove(&host->queues.disconnected)) != NULL) 2799 ; 2800 2801 return SUCCESS; 2802 } 2803 2804 /*============================================================================================== 2805 * initialisation & miscellaneous support 2806 */ 2807 2808 /* 2809 * Function: char *acornscsi_info(struct Scsi_Host *host) 2810 * Purpose : return a string describing this interface 2811 * Params : host - host to give information on 2812 * Returns : a constant string 2813 */ 2814 const 2815 char *acornscsi_info(struct Scsi_Host *host) 2816 { 2817 static char string[100], *p; 2818 2819 p = string; 2820 2821 p += sprintf(string, "%s at port %08lX irq %d v%d.%d.%d" 2822 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC 2823 " SYNC" 2824 #endif 2825 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE 2826 " TAG" 2827 #endif 2828 #ifdef CONFIG_SCSI_ACORNSCSI_LINK 2829 " LINK" 2830 #endif 2831 #if (DEBUG & DEBUG_NO_WRITE) 2832 " NOWRITE (" __stringify(NO_WRITE) ")" 2833 #endif 2834 , host->hostt->name, host->io_port, host->irq, 2835 VER_MAJOR, VER_MINOR, VER_PATCH); 2836 return string; 2837 } 2838 2839 static int acornscsi_show_info(struct seq_file *m, struct Scsi_Host *instance) 2840 { 2841 int devidx; 2842 struct scsi_device *scd; 2843 AS_Host *host; 2844 2845 host = (AS_Host *)instance->hostdata; 2846 2847 seq_printf(m, "AcornSCSI driver v%d.%d.%d" 2848 #ifdef CONFIG_SCSI_ACORNSCSI_SYNC 2849 " SYNC" 2850 #endif 2851 #ifdef CONFIG_SCSI_ACORNSCSI_TAGGED_QUEUE 2852 " TAG" 2853 #endif 2854 #ifdef CONFIG_SCSI_ACORNSCSI_LINK 2855 " LINK" 2856 #endif 2857 #if (DEBUG & DEBUG_NO_WRITE) 2858 " NOWRITE (" __stringify(NO_WRITE) ")" 2859 #endif 2860 "\n\n", VER_MAJOR, VER_MINOR, VER_PATCH); 2861 2862 seq_printf(m, "SBIC: WD33C93A Address: %p IRQ : %d\n", 2863 host->base + SBIC_REGIDX, host->scsi.irq); 2864 #ifdef USE_DMAC 2865 seq_printf(m, "DMAC: uPC71071 Address: %p IRQ : %d\n\n", 2866 host->base + DMAC_OFFSET, host->scsi.irq); 2867 #endif 2868 2869 seq_printf(m, "Statistics:\n" 2870 "Queued commands: %-10u Issued commands: %-10u\n" 2871 "Done commands : %-10u Reads : %-10u\n" 2872 "Writes : %-10u Others : %-10u\n" 2873 "Disconnects : %-10u Aborts : %-10u\n" 2874 "Resets : %-10u\n\nLast phases:", 2875 host->stats.queues, host->stats.removes, 2876 host->stats.fins, host->stats.reads, 2877 host->stats.writes, host->stats.miscs, 2878 host->stats.disconnects, host->stats.aborts, 2879 host->stats.resets); 2880 2881 for (devidx = 0; devidx < 9; devidx ++) { 2882 unsigned int statptr, prev; 2883 2884 seq_printf(m, "\n%c:", devidx == 8 ? 'H' : ('0' + devidx)); 2885 statptr = host->status_ptr[devidx] - 10; 2886 2887 if ((signed int)statptr < 0) 2888 statptr += STATUS_BUFFER_SIZE; 2889 2890 prev = host->status[devidx][statptr].when; 2891 2892 for (; statptr != host->status_ptr[devidx]; statptr = (statptr + 1) & (STATUS_BUFFER_SIZE - 1)) { 2893 if (host->status[devidx][statptr].when) { 2894 seq_printf(m, "%c%02X:%02X+%2ld", 2895 host->status[devidx][statptr].irq ? '-' : ' ', 2896 host->status[devidx][statptr].ph, 2897 host->status[devidx][statptr].ssr, 2898 (host->status[devidx][statptr].when - prev) < 100 ? 2899 (host->status[devidx][statptr].when - prev) : 99); 2900 prev = host->status[devidx][statptr].when; 2901 } 2902 } 2903 } 2904 2905 seq_printf(m, "\nAttached devices:\n"); 2906 2907 shost_for_each_device(scd, instance) { 2908 seq_printf(m, "Device/Lun TaggedQ Sync\n"); 2909 seq_printf(m, " %d/%d ", scd->id, scd->lun); 2910 if (scd->tagged_supported) 2911 seq_printf(m, "%3sabled(%3d) ", 2912 scd->simple_tags ? "en" : "dis", 2913 scd->current_tag); 2914 else 2915 seq_printf(m, "unsupported "); 2916 2917 if (host->device[scd->id].sync_xfer & 15) 2918 seq_printf(m, "offset %d, %d ns\n", 2919 host->device[scd->id].sync_xfer & 15, 2920 acornscsi_getperiod(host->device[scd->id].sync_xfer)); 2921 else 2922 seq_printf(m, "async\n"); 2923 2924 } 2925 return 0; 2926 } 2927 2928 static struct scsi_host_template acornscsi_template = { 2929 .module = THIS_MODULE, 2930 .show_info = acornscsi_show_info, 2931 .name = "AcornSCSI", 2932 .info = acornscsi_info, 2933 .queuecommand = acornscsi_queuecmd, 2934 .eh_abort_handler = acornscsi_abort, 2935 .eh_bus_reset_handler = acornscsi_bus_reset, 2936 .can_queue = 16, 2937 .this_id = 7, 2938 .sg_tablesize = SG_ALL, 2939 .cmd_per_lun = 2, 2940 .use_clustering = DISABLE_CLUSTERING, 2941 .proc_name = "acornscsi", 2942 }; 2943 2944 static int acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id) 2945 { 2946 struct Scsi_Host *host; 2947 AS_Host *ashost; 2948 int ret; 2949 2950 ret = ecard_request_resources(ec); 2951 if (ret) 2952 goto out; 2953 2954 host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host)); 2955 if (!host) { 2956 ret = -ENOMEM; 2957 goto out_release; 2958 } 2959 2960 ashost = (AS_Host *)host->hostdata; 2961 2962 ashost->base = ecardm_iomap(ec, ECARD_RES_MEMC, 0, 0); 2963 ashost->fast = ecardm_iomap(ec, ECARD_RES_IOCFAST, 0, 0); 2964 if (!ashost->base || !ashost->fast) 2965 goto out_put; 2966 2967 host->irq = ec->irq; 2968 ashost->host = host; 2969 ashost->scsi.irq = host->irq; 2970 2971 ec->irqaddr = ashost->fast + INT_REG; 2972 ec->irqmask = 0x0a; 2973 2974 ret = request_irq(host->irq, acornscsi_intr, 0, "acornscsi", ashost); 2975 if (ret) { 2976 printk(KERN_CRIT "scsi%d: IRQ%d not free: %d\n", 2977 host->host_no, ashost->scsi.irq, ret); 2978 goto out_put; 2979 } 2980 2981 memset(&ashost->stats, 0, sizeof (ashost->stats)); 2982 queue_initialise(&ashost->queues.issue); 2983 queue_initialise(&ashost->queues.disconnected); 2984 msgqueue_initialise(&ashost->scsi.msgs); 2985 2986 acornscsi_resetcard(ashost); 2987 2988 ret = scsi_add_host(host, &ec->dev); 2989 if (ret) 2990 goto out_irq; 2991 2992 scsi_scan_host(host); 2993 goto out; 2994 2995 out_irq: 2996 free_irq(host->irq, ashost); 2997 msgqueue_free(&ashost->scsi.msgs); 2998 queue_free(&ashost->queues.disconnected); 2999 queue_free(&ashost->queues.issue); 3000 out_put: 3001 ecardm_iounmap(ec, ashost->fast); 3002 ecardm_iounmap(ec, ashost->base); 3003 scsi_host_put(host); 3004 out_release: 3005 ecard_release_resources(ec); 3006 out: 3007 return ret; 3008 } 3009 3010 static void acornscsi_remove(struct expansion_card *ec) 3011 { 3012 struct Scsi_Host *host = ecard_get_drvdata(ec); 3013 AS_Host *ashost = (AS_Host *)host->hostdata; 3014 3015 ecard_set_drvdata(ec, NULL); 3016 scsi_remove_host(host); 3017 3018 /* 3019 * Put card into RESET state 3020 */ 3021 writeb(0x80, ashost->fast + PAGE_REG); 3022 3023 free_irq(host->irq, ashost); 3024 3025 msgqueue_free(&ashost->scsi.msgs); 3026 queue_free(&ashost->queues.disconnected); 3027 queue_free(&ashost->queues.issue); 3028 ecardm_iounmap(ec, ashost->fast); 3029 ecardm_iounmap(ec, ashost->base); 3030 scsi_host_put(host); 3031 ecard_release_resources(ec); 3032 } 3033 3034 static const struct ecard_id acornscsi_cids[] = { 3035 { MANU_ACORN, PROD_ACORN_SCSI }, 3036 { 0xffff, 0xffff }, 3037 }; 3038 3039 static struct ecard_driver acornscsi_driver = { 3040 .probe = acornscsi_probe, 3041 .remove = acornscsi_remove, 3042 .id_table = acornscsi_cids, 3043 .drv = { 3044 .name = "acornscsi", 3045 }, 3046 }; 3047 3048 static int __init acornscsi_init(void) 3049 { 3050 return ecard_register_driver(&acornscsi_driver); 3051 } 3052 3053 static void __exit acornscsi_exit(void) 3054 { 3055 ecard_remove_driver(&acornscsi_driver); 3056 } 3057 3058 module_init(acornscsi_init); 3059 module_exit(acornscsi_exit); 3060 3061 MODULE_AUTHOR("Russell King"); 3062 MODULE_DESCRIPTION("AcornSCSI driver"); 3063 MODULE_LICENSE("GPL"); 3064