ncr.c revision 27512
1/************************************************************************** 2** 3** $Id: ncr.c,v 1.98 1997/06/11 22:36:02 se Exp $ 4** 5** Device driver for the NCR 53C810 PCI-SCSI-Controller. 6** 7** FreeBSD / NetBSD 8** 9**------------------------------------------------------------------------- 10** 11** Written for 386bsd and FreeBSD by 12** Wolfgang Stanglmeier <wolf@cologne.de> 13** Stefan Esser <se@mi.Uni-Koeln.de> 14** 15** Ported to NetBSD by 16** Charles M. Hannum <mycroft@gnu.ai.mit.edu> 17** 18**------------------------------------------------------------------------- 19** 20** Copyright (c) 1994 Wolfgang Stanglmeier. All rights reserved. 21** 22** Redistribution and use in source and binary forms, with or without 23** modification, are permitted provided that the following conditions 24** are met: 25** 1. Redistributions of source code must retain the above copyright 26** notice, this list of conditions and the following disclaimer. 27** 2. Redistributions in binary form must reproduce the above copyright 28** notice, this list of conditions and the following disclaimer in the 29** documentation and/or other materials provided with the distribution. 30** 3. The name of the author may not be used to endorse or promote products 31** derived from this software without specific prior written permission. 32** 33** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 34** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 35** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 36** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 37** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 38** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 39** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 40** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 41** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 42** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 43** 44*************************************************************************** 45*/ 46 47#define NCR_DATE "pl24 96/12/14" 48 49#define NCR_VERSION (2) 50#define MAX_UNITS (16) 51 52#define NCR_GETCC_WITHMSG 53 54#if defined (__FreeBSD__) && defined(KERNEL) 55#include "opt_ncr.h" 56#endif /* defined (__FreeBSD__) && defined(KERNEL) */ 57 58#ifdef FAILSAFE 59#ifndef SCSI_NCR_DFLT_TAGS 60#define SCSI_NCR_DFLT_TAGS (0) 61#endif /* SCSI_NCR_DFLT_TAGS */ 62#define CDROM_ASYNC 63#endif /* FAILSAFE */ 64 65/*========================================================== 66** 67** Configuration and Debugging 68** 69** May be overwritten in <arch/conf/xxxx> 70** 71**========================================================== 72*/ 73 74/* 75** SCSI address of this device. 76** The boot routines should have set it. 77** If not, use this. 78*/ 79 80#ifndef SCSI_NCR_MYADDR 81#define SCSI_NCR_MYADDR (7) 82#endif /* SCSI_NCR_MYADDR */ 83 84/* 85** The maximal synchronous frequency in kHz. 86** (0=asynchronous) 87*/ 88 89#ifndef SCSI_NCR_MAX_SYNC 90#define SCSI_NCR_MAX_SYNC (10000) 91#endif /* SCSI_NCR_MAX_SYNC */ 92 93/* 94** The maximal bus with (in log2 byte) 95** (0=8 bit, 1=16 bit) 96*/ 97 98#ifndef SCSI_NCR_MAX_WIDE 99#define SCSI_NCR_MAX_WIDE (1) 100#endif /* SCSI_NCR_MAX_WIDE */ 101 102/* 103** The maximum number of tags per logic unit. 104** Used only for disk devices that support tags. 105*/ 106 107#ifndef SCSI_NCR_DFLT_TAGS 108#define SCSI_NCR_DFLT_TAGS (4) 109#endif /* SCSI_NCR_DFLT_TAGS */ 110 111/*========================================================== 112** 113** Configuration and Debugging 114** 115**========================================================== 116*/ 117 118/* 119** Number of targets supported by the driver. 120** n permits target numbers 0..n-1. 121** Default is 7, meaning targets #0..#6. 122** #7 .. is myself. 123*/ 124 125#define MAX_TARGET (16) 126 127/* 128** Number of logic units supported by the driver. 129** n enables logic unit numbers 0..n-1. 130** The common SCSI devices require only 131** one lun, so take 1 as the default. 132*/ 133 134#ifndef MAX_LUN 135#define MAX_LUN (8) 136#endif /* MAX_LUN */ 137 138/* 139** The maximum number of jobs scheduled for starting. 140** There should be one slot per target, and one slot 141** for each tag of each target in use. 142** The calculation below is actually quite silly ... 143*/ 144 145#define MAX_START (MAX_TARGET + 7 * SCSI_NCR_DFLT_TAGS) 146 147/* 148** The maximum number of segments a transfer is split into. 149*/ 150 151#define MAX_SCATTER (33) 152 153/* 154** The maximum transfer length (should be >= 64k). 155** MUST NOT be greater than (MAX_SCATTER-1) * PAGE_SIZE. 156*/ 157 158#define MAX_SIZE ((MAX_SCATTER-1) * (long) PAGE_SIZE) 159 160/* 161** other 162*/ 163 164#define NCR_SNOOP_TIMEOUT (1000000) 165 166/*========================================================== 167** 168** Include files 169** 170**========================================================== 171*/ 172 173#ifdef __NetBSD__ 174#ifdef _KERNEL 175#define KERNEL 176#endif 177#endif 178#include <stddef.h> 179 180#include <sys/types.h> 181#include <sys/param.h> 182#include <sys/time.h> 183#include <sys/proc.h> 184 185#ifdef KERNEL 186#include <sys/systm.h> 187#include <sys/malloc.h> 188#include <sys/buf.h> 189#include <sys/kernel.h> 190#ifdef __NetBSD__ 191#define bootverbose 1 192#endif 193#include <sys/sysctl.h> 194#ifndef __NetBSD__ 195#include <machine/clock.h> 196#endif 197#include <vm/vm.h> 198#include <vm/vm_param.h> 199#include <vm/pmap.h> 200#include <vm/vm_extern.h> 201#endif /* KERNEL */ 202 203 204#ifndef __NetBSD__ 205#include <pci/pcivar.h> 206#include <pci/pcireg.h> 207#include <pci/ncrreg.h> 208#else 209#include <sys/device.h> 210#include <dev/pci/ncr_reg.h> 211#include <dev/pci/pcivar.h> 212#include <dev/pci/pcireg.h> 213#define DELAY(x) delay(x) 214#endif /* __NetBSD */ 215 216#include <scsi/scsi_all.h> 217#include <scsi/scsiconf.h> 218 219 220/*========================================================== 221** 222** Debugging tags 223** 224**========================================================== 225*/ 226 227#define DEBUG_ALLOC (0x0001) 228#define DEBUG_PHASE (0x0002) 229#define DEBUG_POLL (0x0004) 230#define DEBUG_QUEUE (0x0008) 231#define DEBUG_RESULT (0x0010) 232#define DEBUG_SCATTER (0x0020) 233#define DEBUG_SCRIPT (0x0040) 234#define DEBUG_TINY (0x0080) 235#define DEBUG_TIMING (0x0100) 236#define DEBUG_NEGO (0x0200) 237#define DEBUG_TAGS (0x0400) 238#define DEBUG_FREEZE (0x0800) 239#define DEBUG_RESTART (0x1000) 240 241/* 242** Enable/Disable debug messages. 243** Can be changed at runtime too. 244*/ 245 246#ifdef SCSI_NCR_DEBUG 247 #define DEBUG_FLAGS ncr_debug 248#else /* SCSI_NCR_DEBUG */ 249 #define SCSI_NCR_DEBUG 0 250 #define DEBUG_FLAGS 0 251#endif /* SCSI_NCR_DEBUG */ 252 253 254 255/*========================================================== 256** 257** assert () 258** 259**========================================================== 260** 261** modified copy from 386bsd:/usr/include/sys/assert.h 262** 263**---------------------------------------------------------- 264*/ 265 266#define assert(expression) { \ 267 if (!(expression)) { \ 268 (void)printf(\ 269 "assertion \"%s\" failed: file \"%s\", line %d\n", \ 270 #expression, \ 271 __FILE__, __LINE__); \ 272 } \ 273} 274 275/*========================================================== 276** 277** Access to the controller chip. 278** 279**========================================================== 280*/ 281 282#ifdef NCR_IOMAPPED 283 284#define INB(r) inb (np->port + offsetof(struct ncr_reg, r)) 285#define INW(r) inw (np->port + offsetof(struct ncr_reg, r)) 286#define INL(r) inl (np->port + offsetof(struct ncr_reg, r)) 287 288#define OUTB(r, val) outb (np->port+offsetof(struct ncr_reg,r),(val)) 289#define OUTW(r, val) outw (np->port+offsetof(struct ncr_reg,r),(val)) 290#define OUTL(r, val) outl (np->port+offsetof(struct ncr_reg,r),(val)) 291 292#else 293 294#define INB(r) (np->reg->r) 295#define INW(r) (np->reg->r) 296#define INL(r) (np->reg->r) 297 298#define OUTB(r, val) np->reg->r = (val) 299#define OUTW(r, val) np->reg->r = (val) 300#define OUTL(r, val) np->reg->r = (val) 301 302#endif 303 304/*========================================================== 305** 306** Command control block states. 307** 308**========================================================== 309*/ 310 311#define HS_IDLE (0) 312#define HS_BUSY (1) 313#define HS_NEGOTIATE (2) /* sync/wide data transfer*/ 314#define HS_DISCONNECT (3) /* Disconnected by target */ 315 316#define HS_COMPLETE (4) 317#define HS_SEL_TIMEOUT (5) /* Selection timeout */ 318#define HS_RESET (6) /* SCSI reset */ 319#define HS_ABORTED (7) /* Transfer aborted */ 320#define HS_TIMEOUT (8) /* Software timeout */ 321#define HS_FAIL (9) /* SCSI or PCI bus errors */ 322#define HS_UNEXPECTED (10) /* Unexpected disconnect */ 323 324#define HS_DONEMASK (0xfc) 325 326/*========================================================== 327** 328** Software Interrupt Codes 329** 330**========================================================== 331*/ 332 333#define SIR_SENSE_RESTART (1) 334#define SIR_SENSE_FAILED (2) 335#define SIR_STALL_RESTART (3) 336#define SIR_STALL_QUEUE (4) 337#define SIR_NEGO_SYNC (5) 338#define SIR_NEGO_WIDE (6) 339#define SIR_NEGO_FAILED (7) 340#define SIR_NEGO_PROTO (8) 341#define SIR_REJECT_RECEIVED (9) 342#define SIR_REJECT_SENT (10) 343#define SIR_IGN_RESIDUE (11) 344#define SIR_MISSING_SAVE (12) 345#define SIR_MAX (12) 346 347/*========================================================== 348** 349** Extended error codes. 350** xerr_status field of struct ccb. 351** 352**========================================================== 353*/ 354 355#define XE_OK (0) 356#define XE_EXTRA_DATA (1) /* unexpected data phase */ 357#define XE_BAD_PHASE (2) /* illegal phase (4/5) */ 358 359/*========================================================== 360** 361** Negotiation status. 362** nego_status field of struct ccb. 363** 364**========================================================== 365*/ 366 367#define NS_SYNC (1) 368#define NS_WIDE (2) 369 370/*========================================================== 371** 372** "Special features" of targets. 373** quirks field of struct tcb. 374** actualquirks field of struct ccb. 375** 376**========================================================== 377*/ 378 379#define QUIRK_AUTOSAVE (0x01) 380#define QUIRK_NOMSG (0x02) 381#define QUIRK_NOSYNC (0x10) 382#define QUIRK_NOWIDE16 (0x20) 383#define QUIRK_NOTAGS (0x40) 384#define QUIRK_UPDATE (0x80) 385 386/*========================================================== 387** 388** Capability bits in Inquire response byte 7. 389** 390**========================================================== 391*/ 392 393#define INQ7_QUEUE (0x02) 394#define INQ7_SYNC (0x10) 395#define INQ7_WIDE16 (0x20) 396 397/*========================================================== 398** 399** Misc. 400** 401**========================================================== 402*/ 403 404#define CCB_MAGIC (0xf2691ad2) 405#define MAX_TAGS (16) /* hard limit */ 406 407/*========================================================== 408** 409** OS dependencies. 410** 411**========================================================== 412*/ 413 414#define PRINT_ADDR(xp) sc_print_addr(xp->sc_link) 415 416/*========================================================== 417** 418** Declaration of structs. 419** 420**========================================================== 421*/ 422 423struct tcb; 424struct lcb; 425struct ccb; 426struct ncb; 427struct script; 428 429typedef struct ncb * ncb_p; 430typedef struct tcb * tcb_p; 431typedef struct lcb * lcb_p; 432typedef struct ccb * ccb_p; 433 434struct link { 435 u_long l_cmd; 436 u_long l_paddr; 437}; 438 439struct usrcmd { 440 u_long target; 441 u_long lun; 442 u_long data; 443 u_long cmd; 444}; 445 446#define UC_SETSYNC 10 447#define UC_SETTAGS 11 448#define UC_SETDEBUG 12 449#define UC_SETORDER 13 450#define UC_SETWIDE 14 451#define UC_SETFLAG 15 452 453#define UF_TRACE (0x01) 454 455/*--------------------------------------- 456** 457** Timestamps for profiling 458** 459**--------------------------------------- 460*/ 461 462struct tstamp { 463 struct timeval start; 464 struct timeval end; 465 struct timeval select; 466 struct timeval command; 467 struct timeval data; 468 struct timeval status; 469 struct timeval disconnect; 470 struct timeval reselect; 471}; 472 473/* 474** profiling data (per device) 475*/ 476 477struct profile { 478 u_long num_trans; 479 u_long num_bytes; 480 u_long num_disc; 481 u_long num_break; 482 u_long num_int; 483 u_long num_fly; 484 u_long ms_setup; 485 u_long ms_data; 486 u_long ms_disc; 487 u_long ms_post; 488}; 489 490/*========================================================== 491** 492** Declaration of structs: target control block 493** 494**========================================================== 495*/ 496 497struct tcb { 498 /* 499 ** during reselection the ncr jumps to this point 500 ** with SFBR set to the encoded target number 501 ** with bit 7 set. 502 ** if it's not this target, jump to the next. 503 ** 504 ** JUMP IF (SFBR != #target#) 505 ** @(next tcb) 506 */ 507 508 struct link jump_tcb; 509 510 /* 511 ** load the actual values for the sxfer and the scntl3 512 ** register (sync/wide mode). 513 ** 514 ** SCR_COPY (1); 515 ** @(sval field of this tcb) 516 ** @(sxfer register) 517 ** SCR_COPY (1); 518 ** @(wval field of this tcb) 519 ** @(scntl3 register) 520 */ 521 522 ncrcmd getscr[6]; 523 524 /* 525 ** if next message is "identify" 526 ** then load the message to SFBR, 527 ** else load 0 to SFBR. 528 ** 529 ** CALL 530 ** <RESEL_LUN> 531 */ 532 533 struct link call_lun; 534 535 /* 536 ** now look for the right lun. 537 ** 538 ** JUMP 539 ** @(first ccb of this lun) 540 */ 541 542 struct link jump_lcb; 543 544 /* 545 ** pointer to interrupted getcc ccb 546 */ 547 548 ccb_p hold_cp; 549 550 /* 551 ** statistical data 552 */ 553 554 u_long transfers; 555 u_long bytes; 556 557 /* 558 ** user settable limits for sync transfer 559 ** and tagged commands. 560 */ 561 562 u_char usrsync; 563 u_char usrtags; 564 u_char usrwide; 565 u_char usrflag; 566 567 /* 568 ** negotiation of wide and synch transfer. 569 ** device quirks. 570 */ 571 572/*0*/ u_char minsync; 573/*1*/ u_char sval; 574/*2*/ u_short period; 575/*0*/ u_char maxoffs; 576 577/*1*/ u_char quirks; 578 579/*2*/ u_char widedone; 580/*3*/ u_char wval; 581 /* 582 ** inquire data 583 */ 584#define MAX_INQUIRE 36 585 u_char inqdata[MAX_INQUIRE]; 586 587 /* 588 ** the lcb's of this tcb 589 */ 590 591 lcb_p lp[MAX_LUN]; 592}; 593 594/*========================================================== 595** 596** Declaration of structs: lun control block 597** 598**========================================================== 599*/ 600 601struct lcb { 602 /* 603 ** during reselection the ncr jumps to this point 604 ** with SFBR set to the "Identify" message. 605 ** if it's not this lun, jump to the next. 606 ** 607 ** JUMP IF (SFBR != #lun#) 608 ** @(next lcb of this target) 609 */ 610 611 struct link jump_lcb; 612 613 /* 614 ** if next message is "simple tag", 615 ** then load the tag to SFBR, 616 ** else load 0 to SFBR. 617 ** 618 ** CALL 619 ** <RESEL_TAG> 620 */ 621 622 struct link call_tag; 623 624 /* 625 ** now look for the right ccb. 626 ** 627 ** JUMP 628 ** @(first ccb of this lun) 629 */ 630 631 struct link jump_ccb; 632 633 /* 634 ** start of the ccb chain 635 */ 636 637 ccb_p next_ccb; 638 639 /* 640 ** Control of tagged queueing 641 */ 642 643 u_char reqccbs; 644 u_char actccbs; 645 u_char reqlink; 646 u_char actlink; 647 u_char usetags; 648 u_char lasttag; 649}; 650 651/*========================================================== 652** 653** Declaration of structs: COMMAND control block 654** 655**========================================================== 656** 657** This substructure is copied from the ccb to a 658** global address after selection (or reselection) 659** and copied back before disconnect. 660** 661** These fields are accessible to the script processor. 662** 663**---------------------------------------------------------- 664*/ 665 666struct head { 667 /* 668 ** Execution of a ccb starts at this point. 669 ** It's a jump to the "SELECT" label 670 ** of the script. 671 ** 672 ** After successful selection the script 673 ** processor overwrites it with a jump to 674 ** the IDLE label of the script. 675 */ 676 677 struct link launch; 678 679 /* 680 ** Saved data pointer. 681 ** Points to the position in the script 682 ** responsible for the actual transfer 683 ** of data. 684 ** It's written after reception of a 685 ** "SAVE_DATA_POINTER" message. 686 ** The goalpointer points after 687 ** the last transfer command. 688 */ 689 690 u_long savep; 691 u_long lastp; 692 u_long goalp; 693 694 /* 695 ** The virtual address of the ccb 696 ** containing this header. 697 */ 698 699 ccb_p cp; 700 701 /* 702 ** space for some timestamps to gather 703 ** profiling data about devices and this driver. 704 */ 705 706 struct tstamp stamp; 707 708 /* 709 ** status fields. 710 */ 711 712 u_char status[8]; 713}; 714 715/* 716** The status bytes are used by the host and the script processor. 717** 718** The first four byte are copied to the scratchb register 719** (declared as scr0..scr3 in ncr_reg.h) just after the select/reselect, 720** and copied back just after disconnecting. 721** Inside the script the XX_REG are used. 722** 723** The last four bytes are used inside the script by "COPY" commands. 724** Because source and destination must have the same alignment 725** in a longword, the fields HAVE to be at the choosen offsets. 726** xerr_st (4) 0 (0x34) scratcha 727** sync_st (5) 1 (0x05) sxfer 728** wide_st (7) 3 (0x03) scntl3 729*/ 730 731/* 732** First four bytes (script) 733*/ 734#define QU_REG scr0 735#define HS_REG scr1 736#define HS_PRT nc_scr1 737#define SS_REG scr2 738#define PS_REG scr3 739 740/* 741** First four bytes (host) 742*/ 743#define actualquirks phys.header.status[0] 744#define host_status phys.header.status[1] 745#define scsi_status phys.header.status[2] 746#define parity_status phys.header.status[3] 747 748/* 749** Last four bytes (script) 750*/ 751#define xerr_st header.status[4] /* MUST be ==0 mod 4 */ 752#define sync_st header.status[5] /* MUST be ==1 mod 4 */ 753#define nego_st header.status[6] 754#define wide_st header.status[7] /* MUST be ==3 mod 4 */ 755 756/* 757** Last four bytes (host) 758*/ 759#define xerr_status phys.xerr_st 760#define sync_status phys.sync_st 761#define nego_status phys.nego_st 762#define wide_status phys.wide_st 763 764/*========================================================== 765** 766** Declaration of structs: Data structure block 767** 768**========================================================== 769** 770** During execution of a ccb by the script processor, 771** the DSA (data structure address) register points 772** to this substructure of the ccb. 773** This substructure contains the header with 774** the script-processor-changable data and 775** data blocks for the indirect move commands. 776** 777**---------------------------------------------------------- 778*/ 779 780struct dsb { 781 782 /* 783 ** Header. 784 ** Has to be the first entry, 785 ** because it's jumped to by the 786 ** script processor 787 */ 788 789 struct head header; 790 791 /* 792 ** Table data for Script 793 */ 794 795 struct scr_tblsel select; 796 struct scr_tblmove smsg ; 797 struct scr_tblmove smsg2 ; 798 struct scr_tblmove cmd ; 799 struct scr_tblmove scmd ; 800 struct scr_tblmove sense ; 801 struct scr_tblmove data [MAX_SCATTER]; 802}; 803 804/*========================================================== 805** 806** Declaration of structs: Command control block. 807** 808**========================================================== 809** 810** During execution of a ccb by the script processor, 811** the DSA (data structure address) register points 812** to this substructure of the ccb. 813** This substructure contains the header with 814** the script-processor-changable data and then 815** data blocks for the indirect move commands. 816** 817**---------------------------------------------------------- 818*/ 819 820 821struct ccb { 822 /* 823 ** during reselection the ncr jumps to this point. 824 ** If a "SIMPLE_TAG" message was received, 825 ** then SFBR is set to the tag. 826 ** else SFBR is set to 0 827 ** If looking for another tag, jump to the next ccb. 828 ** 829 ** JUMP IF (SFBR != #TAG#) 830 ** @(next ccb of this lun) 831 */ 832 833 struct link jump_ccb; 834 835 /* 836 ** After execution of this call, the return address 837 ** (in the TEMP register) points to the following 838 ** data structure block. 839 ** So copy it to the DSA register, and start 840 ** processing of this data structure. 841 ** 842 ** CALL 843 ** <RESEL_TMP> 844 */ 845 846 struct link call_tmp; 847 848 /* 849 ** This is the data structure which is 850 ** to be executed by the script processor. 851 */ 852 853 struct dsb phys; 854 855 /* 856 ** If a data transfer phase is terminated too early 857 ** (after reception of a message (i.e. DISCONNECT)), 858 ** we have to prepare a mini script to transfer 859 ** the rest of the data. 860 */ 861 862 u_long patch[8]; 863 864 /* 865 ** The general SCSI driver provides a 866 ** pointer to a control block. 867 */ 868 869 struct scsi_xfer *xfer; 870 871 /* 872 ** We prepare a message to be sent after selection, 873 ** and a second one to be sent after getcc selection. 874 ** Contents are IDENTIFY and SIMPLE_TAG. 875 ** While negotiating sync or wide transfer, 876 ** a SDTM or WDTM message is appended. 877 */ 878 879 u_char scsi_smsg [8]; 880 u_char scsi_smsg2[8]; 881 882 /* 883 ** Lock this ccb. 884 ** Flag is used while looking for a free ccb. 885 */ 886 887 u_long magic; 888 889 /* 890 ** Physical address of this instance of ccb 891 */ 892 893 u_long p_ccb; 894 895 /* 896 ** Completion time out for this job. 897 ** It's set to time of start + allowed number of seconds. 898 */ 899 900 u_long tlimit; 901 902 /* 903 ** All ccbs of one hostadapter are chained. 904 */ 905 906 ccb_p link_ccb; 907 908 /* 909 ** All ccbs of one target/lun are chained. 910 */ 911 912 ccb_p next_ccb; 913 914 /* 915 ** Sense command 916 */ 917 918 u_char sensecmd[6]; 919 920 /* 921 ** Tag for this transfer. 922 ** It's patched into jump_ccb. 923 ** If it's not zero, a SIMPLE_TAG 924 ** message is included in smsg. 925 */ 926 927 u_char tag; 928}; 929 930#define CCB_PHYS(cp,lbl) (cp->p_ccb + offsetof(struct ccb, lbl)) 931 932/*========================================================== 933** 934** Declaration of structs: NCR device descriptor 935** 936**========================================================== 937*/ 938 939struct ncb { 940#ifdef __NetBSD__ 941 struct device sc_dev; 942 void *sc_ih; 943#else /* !__NetBSD__ */ 944 int unit; 945#endif /* __NetBSD__ */ 946 947 /*----------------------------------------------- 948 ** Scripts .. 949 **----------------------------------------------- 950 ** 951 ** During reselection the ncr jumps to this point. 952 ** The SFBR register is loaded with the encoded target id. 953 ** 954 ** Jump to the first target. 955 ** 956 ** JUMP 957 ** @(next tcb) 958 */ 959 struct link jump_tcb; 960 961 /*----------------------------------------------- 962 ** Configuration .. 963 **----------------------------------------------- 964 ** 965 ** virtual and physical addresses 966 ** of the 53c810 chip. 967 */ 968 vm_offset_t vaddr; 969 vm_offset_t paddr; 970 971 /* 972 ** pointer to the chip's registers. 973 */ 974 volatile 975 struct ncr_reg* reg; 976 977 /* 978 ** A copy of the script, relocated for this ncb. 979 */ 980 struct script *script; 981 982 /* 983 ** Physical address of this instance of ncb->script 984 */ 985 u_long p_script; 986 987 /* 988 ** The SCSI address of the host adapter. 989 */ 990 u_char myaddr; 991 992 /* 993 ** timing parameters 994 */ 995 u_char ns_sync; 996 u_char maxoffs; 997 998 /* 999 ** BIOS supplied PCI bus options 1000 */ 1001 u_char rv_scntl3; 1002 u_char rv_dcntl; 1003 u_char rv_dmode; 1004 u_char rv_ctest3; 1005 u_char rv_ctest5; 1006 1007 /*----------------------------------------------- 1008 ** Link to the generic SCSI driver 1009 **----------------------------------------------- 1010 */ 1011 1012 struct scsi_link sc_link; 1013 1014 /*----------------------------------------------- 1015 ** Job control 1016 **----------------------------------------------- 1017 ** 1018 ** Commands from user 1019 */ 1020 struct usrcmd user; 1021 u_char order; 1022 1023 /* 1024 ** Target data 1025 */ 1026 struct tcb target[MAX_TARGET]; 1027 1028 /* 1029 ** Start queue. 1030 */ 1031 u_long squeue [MAX_START]; 1032 u_short squeueput; 1033 u_short actccbs; 1034 1035 /* 1036 ** Timeout handler 1037 */ 1038 u_long heartbeat; 1039 u_short ticks; 1040 u_short latetime; 1041 u_long lasttime; 1042 1043 /*----------------------------------------------- 1044 ** Debug and profiling 1045 **----------------------------------------------- 1046 ** 1047 ** register dump 1048 */ 1049 struct ncr_reg regdump; 1050 struct timeval regtime; 1051 1052 /* 1053 ** Profiling data 1054 */ 1055 struct profile profile; 1056 u_long disc_phys; 1057 u_long disc_ref; 1058 1059 /* 1060 ** The global header. 1061 ** Accessible to both the host and the 1062 ** script-processor. 1063 */ 1064 struct head header; 1065 1066 /* 1067 ** The global control block. 1068 ** It's used only during the configuration phase. 1069 ** A target control block will be created 1070 ** after the first successful transfer. 1071 */ 1072 struct ccb ccb; 1073 1074 /* 1075 ** message buffers. 1076 ** Should be longword aligned, 1077 ** because they're written with a 1078 ** COPY script command. 1079 */ 1080 u_char msgout[8]; 1081 u_char msgin [8]; 1082 u_long lastmsg; 1083 1084 /* 1085 ** Buffer for STATUS_IN phase. 1086 */ 1087 u_char scratch; 1088 1089 /* 1090 ** controller chip dependent maximal transfer width. 1091 */ 1092 u_char maxwide; 1093 1094 /* 1095 ** option for M_IDENTIFY message: enables disconnecting 1096 */ 1097 u_char disc; 1098 1099#ifdef NCR_IOMAPPED 1100 /* 1101 ** address of the ncr control registers in io space 1102 */ 1103 u_short port; 1104#endif 1105}; 1106 1107#define NCB_SCRIPT_PHYS(np,lbl) (np->p_script + offsetof (struct script, lbl)) 1108 1109/*========================================================== 1110** 1111** 1112** Script for NCR-Processor. 1113** 1114** Use ncr_script_fill() to create the variable parts. 1115** Use ncr_script_copy_and_bind() to make a copy and 1116** bind to physical addresses. 1117** 1118** 1119**========================================================== 1120** 1121** We have to know the offsets of all labels before 1122** we reach them (for forward jumps). 1123** Therefore we declare a struct here. 1124** If you make changes inside the script, 1125** DONT FORGET TO CHANGE THE LENGTHS HERE! 1126** 1127**---------------------------------------------------------- 1128*/ 1129 1130struct script { 1131 ncrcmd start [ 7]; 1132 ncrcmd start0 [ 2]; 1133 ncrcmd start1 [ 3]; 1134 ncrcmd startpos [ 1]; 1135 ncrcmd tryloop [MAX_START*5+2]; 1136 ncrcmd trysel [ 8]; 1137 ncrcmd skip [ 8]; 1138 ncrcmd skip2 [ 3]; 1139 ncrcmd idle [ 2]; 1140 ncrcmd select [ 22]; 1141 ncrcmd prepare [ 4]; 1142 ncrcmd loadpos [ 14]; 1143 ncrcmd prepare2 [ 24]; 1144 ncrcmd setmsg [ 5]; 1145 ncrcmd clrack [ 2]; 1146 ncrcmd dispatch [ 33]; 1147 ncrcmd no_data [ 17]; 1148 ncrcmd checkatn [ 10]; 1149 ncrcmd command [ 15]; 1150 ncrcmd status [ 27]; 1151 ncrcmd msg_in [ 26]; 1152 ncrcmd msg_bad [ 6]; 1153 ncrcmd msg_parity [ 6]; 1154 ncrcmd msg_reject [ 8]; 1155 ncrcmd msg_ign_residue [ 32]; 1156 ncrcmd msg_extended [ 18]; 1157 ncrcmd msg_ext_2 [ 18]; 1158 ncrcmd msg_wdtr [ 27]; 1159 ncrcmd msg_ext_3 [ 18]; 1160 ncrcmd msg_sdtr [ 27]; 1161 ncrcmd complete [ 13]; 1162 ncrcmd cleanup [ 12]; 1163 ncrcmd cleanup0 [ 11]; 1164 ncrcmd signal [ 10]; 1165 ncrcmd save_dp [ 5]; 1166 ncrcmd restore_dp [ 5]; 1167 ncrcmd disconnect [ 12]; 1168 ncrcmd disconnect0 [ 5]; 1169 ncrcmd disconnect1 [ 23]; 1170 ncrcmd msg_out [ 9]; 1171 ncrcmd msg_out_done [ 7]; 1172 ncrcmd msg_out_abort [ 10]; 1173 ncrcmd getcc [ 4]; 1174 ncrcmd getcc1 [ 5]; 1175#ifdef NCR_GETCC_WITHMSG 1176 ncrcmd getcc2 [ 33]; 1177#else 1178 ncrcmd getcc2 [ 14]; 1179#endif 1180 ncrcmd getcc3 [ 10]; 1181 ncrcmd badgetcc [ 6]; 1182 ncrcmd reselect [ 12]; 1183 ncrcmd reselect2 [ 6]; 1184 ncrcmd resel_tmp [ 5]; 1185 ncrcmd resel_lun [ 18]; 1186 ncrcmd resel_tag [ 24]; 1187 ncrcmd data_in [MAX_SCATTER * 4 + 7]; 1188 ncrcmd data_out [MAX_SCATTER * 4 + 7]; 1189 ncrcmd aborttag [ 4]; 1190 ncrcmd abort [ 22]; 1191 ncrcmd snooptest [ 9]; 1192 ncrcmd snoopend [ 2]; 1193}; 1194 1195/*========================================================== 1196** 1197** 1198** Function headers. 1199** 1200** 1201**========================================================== 1202*/ 1203 1204#ifdef KERNEL 1205static void ncr_alloc_ccb (ncb_p np, u_long target, u_long lun); 1206static void ncr_complete (ncb_p np, ccb_p cp); 1207static int ncr_delta (struct timeval * from, struct timeval * to); 1208static void ncr_exception (ncb_p np); 1209static void ncr_free_ccb (ncb_p np, ccb_p cp, int flags); 1210static void ncr_getclock (ncb_p np); 1211static ccb_p ncr_get_ccb (ncb_p np, u_long flags, u_long t,u_long l); 1212static u_int32_t ncr_info (int unit); 1213static void ncr_init (ncb_p np, char * msg, u_long code); 1214static void ncr_intr (void *vnp); 1215static void ncr_int_ma (ncb_p np, u_char dstat); 1216static void ncr_int_sir (ncb_p np); 1217static void ncr_int_sto (ncb_p np); 1218static void ncr_min_phys (struct buf *bp); 1219static void ncr_negotiate (struct ncb* np, struct tcb* tp); 1220static void ncr_opennings (ncb_p np, lcb_p lp, struct scsi_xfer * xp); 1221static void ncb_profile (ncb_p np, ccb_p cp); 1222static void ncr_script_copy_and_bind 1223 (struct script * script, ncb_p np); 1224static void ncr_script_fill (struct script * scr); 1225static int ncr_scatter (struct dsb* phys, vm_offset_t vaddr, 1226 vm_size_t datalen); 1227static void ncr_setmaxtags (tcb_p tp, u_long usrtags); 1228static void ncr_setsync (ncb_p np, ccb_p cp, u_char sxfer); 1229static void ncr_settags (tcb_p tp, lcb_p lp, u_long usrtags); 1230static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide); 1231static int ncr_show_msg (u_char * msg); 1232static int ncr_snooptest (ncb_p np); 1233static int32_t ncr_start (struct scsi_xfer *xp); 1234static void ncr_timeout (void *arg); 1235static void ncr_usercmd (ncb_p np); 1236static void ncr_wakeup (ncb_p np, u_long code); 1237 1238#ifdef __NetBSD__ 1239static int ncr_probe (struct device *, void *, void *); 1240static void ncr_attach (struct device *, struct device *, void *); 1241#else /* !__NetBSD */ 1242static char* ncr_probe (pcici_t tag, pcidi_t type); 1243static void ncr_attach (pcici_t tag, int unit); 1244#endif /* __NetBSD__ */ 1245 1246#endif /* KERNEL */ 1247 1248/*========================================================== 1249** 1250** 1251** Global static data. 1252** 1253** 1254**========================================================== 1255*/ 1256 1257 1258static char ident[] = 1259 "\n$Id: ncr.c,v 1.98 1997/06/11 22:36:02 se Exp $\n"; 1260 1261static const u_long ncr_version = NCR_VERSION * 11 1262 + (u_long) sizeof (struct ncb) * 7 1263 + (u_long) sizeof (struct ccb) * 5 1264 + (u_long) sizeof (struct lcb) * 3 1265 + (u_long) sizeof (struct tcb) * 2; 1266 1267#ifdef KERNEL 1268static const int nncr=MAX_UNITS; /* XXX to be replaced by SYSCTL */ 1269ncb_p ncrp [MAX_UNITS]; /* XXX to be replaced by SYSCTL */ 1270 1271static int ncr_debug = SCSI_NCR_DEBUG; 1272SYSCTL_INT(_debug, OID_AUTO, ncr_debug, CTLFLAG_RW, &ncr_debug, 0, ""); 1273 1274static int ncr_cache; /* to be aligned _NOT_ static */ 1275 1276/*========================================================== 1277** 1278** 1279** Global static data: auto configure 1280** 1281** 1282**========================================================== 1283*/ 1284 1285#define NCR_810_ID (0x00011000ul) 1286#define NCR_815_ID (0x00041000ul) 1287#define NCR_820_ID (0x00021000ul) 1288#define NCR_825_ID (0x00031000ul) 1289#define NCR_860_ID (0x00061000ul) 1290#define NCR_875_ID (0x000f1000ul) 1291#define NCR_875_ID2 (0x008f1000ul) 1292#define NCR_885_ID (0x000d1000ul) 1293#define NCR_895_ID (0x000c1000ul) 1294#define NCR_896_ID (0x000b1000ul) 1295 1296#ifdef __NetBSD__ 1297 1298struct cfdriver ncrcd = { 1299 NULL, "ncr", ncr_probe, ncr_attach, DV_DISK, sizeof(struct ncb) 1300}; 1301 1302#else /* !__NetBSD__ */ 1303 1304static u_long ncr_count; 1305 1306static struct pci_device ncr_device = { 1307 "ncr", 1308 ncr_probe, 1309 ncr_attach, 1310 &ncr_count, 1311 NULL 1312}; 1313 1314DATA_SET (pcidevice_set, ncr_device); 1315 1316#endif /* !__NetBSD__ */ 1317 1318static struct scsi_adapter ncr_switch = 1319{ 1320 ncr_start, 1321 ncr_min_phys, 1322 0, 1323 0, 1324#ifndef __NetBSD__ 1325 ncr_info, 1326 "ncr", 1327#endif /* !__NetBSD__ */ 1328}; 1329 1330static struct scsi_device ncr_dev = 1331{ 1332 NULL, /* Use default error handler */ 1333 NULL, /* have a queue, served by this */ 1334 NULL, /* have no async handler */ 1335 NULL, /* Use default 'done' routine */ 1336#ifndef __NetBSD__ 1337 "ncr", 1338#endif /* !__NetBSD__ */ 1339}; 1340 1341#ifdef __NetBSD__ 1342 1343#define ncr_name(np) (np->sc_dev.dv_xname) 1344 1345#else /* !__NetBSD__ */ 1346 1347static char *ncr_name (ncb_p np) 1348{ 1349 static char name[10]; 1350 sprintf(name, "ncr%d", np->unit); 1351 return (name); 1352} 1353#endif 1354 1355/*========================================================== 1356** 1357** 1358** Scripts for NCR-Processor. 1359** 1360** Use ncr_script_bind for binding to physical addresses. 1361** 1362** 1363**========================================================== 1364** 1365** NADDR generates a reference to a field of the controller data. 1366** PADDR generates a reference to another part of the script. 1367** RADDR generates a reference to a script processor register. 1368** FADDR generates a reference to a script processor register 1369** with offset. 1370** 1371**---------------------------------------------------------- 1372*/ 1373 1374#define RELOC_SOFTC 0x40000000 1375#define RELOC_LABEL 0x50000000 1376#define RELOC_REGISTER 0x60000000 1377#define RELOC_MASK 0xf0000000 1378 1379#define NADDR(label) (RELOC_SOFTC | offsetof(struct ncb, label)) 1380#define PADDR(label) (RELOC_LABEL | offsetof(struct script, label)) 1381#define RADDR(label) (RELOC_REGISTER | REG(label)) 1382#define FADDR(label,ofs)(RELOC_REGISTER | ((REG(label))+(ofs))) 1383 1384static struct script script0 = { 1385/*--------------------------< START >-----------------------*/ { 1386 /* 1387 ** Claim to be still alive ... 1388 */ 1389 SCR_COPY (sizeof (((struct ncb *)0)->heartbeat)), 1390 (ncrcmd) &time.tv_sec, 1391 NADDR (heartbeat), 1392 /* 1393 ** Make data structure address invalid. 1394 ** clear SIGP. 1395 */ 1396 SCR_LOAD_REG (dsa, 0xff), 1397 0, 1398 SCR_FROM_REG (ctest2), 1399 0, 1400}/*-------------------------< START0 >----------------------*/,{ 1401 /* 1402 ** Hook for interrupted GetConditionCode. 1403 ** Will be patched to ... IFTRUE by 1404 ** the interrupt handler. 1405 */ 1406 SCR_INT ^ IFFALSE (0), 1407 SIR_SENSE_RESTART, 1408 1409}/*-------------------------< START1 >----------------------*/,{ 1410 /* 1411 ** Hook for stalled start queue. 1412 ** Will be patched to IFTRUE by the interrupt handler. 1413 */ 1414 SCR_INT ^ IFFALSE (0), 1415 SIR_STALL_RESTART, 1416 /* 1417 ** Then jump to a certain point in tryloop. 1418 ** Due to the lack of indirect addressing the code 1419 ** is self modifying here. 1420 */ 1421 SCR_JUMP, 1422}/*-------------------------< STARTPOS >--------------------*/,{ 1423 PADDR(tryloop), 1424}/*-------------------------< TRYLOOP >---------------------*/,{ 1425/* 1426** Load an entry of the start queue into dsa 1427** and try to start it by jumping to TRYSEL. 1428** 1429** Because the size depends on the 1430** #define MAX_START parameter, it is filled 1431** in at runtime. 1432** 1433**----------------------------------------------------------- 1434** 1435** ##===========< I=0; i<MAX_START >=========== 1436** || SCR_COPY (4), 1437** || NADDR (squeue[i]), 1438** || RADDR (dsa), 1439** || SCR_CALL, 1440** || PADDR (trysel), 1441** ##========================================== 1442** 1443** SCR_JUMP, 1444** PADDR(tryloop), 1445** 1446**----------------------------------------------------------- 1447*/ 14480 1449 1450}/*-------------------------< TRYSEL >----------------------*/,{ 1451 /* 1452 ** Now: 1453 ** DSA: Address of a Data Structure 1454 ** or Address of the IDLE-Label. 1455 ** 1456 ** TEMP: Address of a script, which tries to 1457 ** start the NEXT entry. 1458 ** 1459 ** Save the TEMP register into the SCRATCHA register. 1460 ** Then copy the DSA to TEMP and RETURN. 1461 ** This is kind of an indirect jump. 1462 ** (The script processor has NO stack, so the 1463 ** CALL is actually a jump and link, and the 1464 ** RETURN is an indirect jump.) 1465 ** 1466 ** If the slot was empty, DSA contains the address 1467 ** of the IDLE part of this script. The processor 1468 ** jumps to IDLE and waits for a reselect. 1469 ** It will wake up and try the same slot again 1470 ** after the SIGP bit becomes set by the host. 1471 ** 1472 ** If the slot was not empty, DSA contains 1473 ** the address of the phys-part of a ccb. 1474 ** The processor jumps to this address. 1475 ** phys starts with head, 1476 ** head starts with launch, 1477 ** so actually the processor jumps to 1478 ** the lauch part. 1479 ** If the entry is scheduled for execution, 1480 ** then launch contains a jump to SELECT. 1481 ** If it's not scheduled, it contains a jump to IDLE. 1482 */ 1483 SCR_COPY (4), 1484 RADDR (temp), 1485 RADDR (scratcha), 1486 SCR_COPY (4), 1487 RADDR (dsa), 1488 RADDR (temp), 1489 SCR_RETURN, 1490 0 1491 1492}/*-------------------------< SKIP >------------------------*/,{ 1493 /* 1494 ** This entry has been canceled. 1495 ** Next time use the next slot. 1496 */ 1497 SCR_COPY (4), 1498 RADDR (scratcha), 1499 PADDR (startpos), 1500 /* 1501 ** patch the launch field. 1502 ** should look like an idle process. 1503 */ 1504 SCR_COPY (4), 1505 RADDR (dsa), 1506 PADDR (skip2), 1507 SCR_COPY (8), 1508 PADDR (idle), 1509}/*-------------------------< SKIP2 >-----------------------*/,{ 1510 0, 1511 SCR_JUMP, 1512 PADDR(start), 1513}/*-------------------------< IDLE >------------------------*/,{ 1514 /* 1515 ** Nothing to do? 1516 ** Wait for reselect. 1517 */ 1518 SCR_JUMP, 1519 PADDR(reselect), 1520 1521}/*-------------------------< SELECT >----------------------*/,{ 1522 /* 1523 ** DSA contains the address of a scheduled 1524 ** data structure. 1525 ** 1526 ** SCRATCHA contains the address of the script, 1527 ** which starts the next entry. 1528 ** 1529 ** Set Initiator mode. 1530 ** 1531 ** (Target mode is left as an exercise for the reader) 1532 */ 1533 1534 SCR_CLR (SCR_TRG), 1535 0, 1536 SCR_LOAD_REG (HS_REG, 0xff), 1537 0, 1538 1539 /* 1540 ** And try to select this target. 1541 */ 1542 SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select), 1543 PADDR (reselect), 1544 1545 /* 1546 ** Now there are 4 possibilities: 1547 ** 1548 ** (1) The ncr looses arbitration. 1549 ** This is ok, because it will try again, 1550 ** when the bus becomes idle. 1551 ** (But beware of the timeout function!) 1552 ** 1553 ** (2) The ncr is reselected. 1554 ** Then the script processor takes the jump 1555 ** to the RESELECT label. 1556 ** 1557 ** (3) The ncr completes the selection. 1558 ** Then it will execute the next statement. 1559 ** 1560 ** (4) There is a selection timeout. 1561 ** Then the ncr should interrupt the host and stop. 1562 ** Unfortunately, it seems to continue execution 1563 ** of the script. But it will fail with an 1564 ** IID-interrupt on the next WHEN. 1565 */ 1566 1567 SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)), 1568 0, 1569 1570 /* 1571 ** Save target id to ctest0 register 1572 */ 1573 1574 SCR_FROM_REG (sdid), 1575 0, 1576 SCR_TO_REG (ctest0), 1577 0, 1578 /* 1579 ** Send the IDENTIFY and SIMPLE_TAG messages 1580 ** (and the M_X_SYNC_REQ message) 1581 */ 1582 SCR_MOVE_TBL ^ SCR_MSG_OUT, 1583 offsetof (struct dsb, smsg), 1584#ifdef undef /* XXX better fail than try to deal with this ... */ 1585 SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_OUT)), 1586 -16, 1587#endif 1588 SCR_CLR (SCR_ATN), 1589 0, 1590 SCR_COPY (1), 1591 RADDR (sfbr), 1592 NADDR (lastmsg), 1593 /* 1594 ** Selection complete. 1595 ** Next time use the next slot. 1596 */ 1597 SCR_COPY (4), 1598 RADDR (scratcha), 1599 PADDR (startpos), 1600}/*-------------------------< PREPARE >----------------------*/,{ 1601 /* 1602 ** The ncr doesn't have an indirect load 1603 ** or store command. So we have to 1604 ** copy part of the control block to a 1605 ** fixed place, where we can access it. 1606 ** 1607 ** We patch the address part of a 1608 ** COPY command with the DSA-register. 1609 */ 1610 SCR_COPY (4), 1611 RADDR (dsa), 1612 PADDR (loadpos), 1613 /* 1614 ** then we do the actual copy. 1615 */ 1616 SCR_COPY (sizeof (struct head)), 1617 /* 1618 ** continued after the next label ... 1619 */ 1620 1621}/*-------------------------< LOADPOS >---------------------*/,{ 1622 0, 1623 NADDR (header), 1624 /* 1625 ** Mark this ccb as not scheduled. 1626 */ 1627 SCR_COPY (8), 1628 PADDR (idle), 1629 NADDR (header.launch), 1630 /* 1631 ** Set a time stamp for this selection 1632 */ 1633 SCR_COPY (sizeof (struct timeval)), 1634 (ncrcmd) &time, 1635 NADDR (header.stamp.select), 1636 /* 1637 ** load the savep (saved pointer) into 1638 ** the TEMP register (actual pointer) 1639 */ 1640 SCR_COPY (4), 1641 NADDR (header.savep), 1642 RADDR (temp), 1643 /* 1644 ** Initialize the status registers 1645 */ 1646 SCR_COPY (4), 1647 NADDR (header.status), 1648 RADDR (scr0), 1649 1650}/*-------------------------< PREPARE2 >---------------------*/,{ 1651 /* 1652 ** Load the synchronous mode register 1653 */ 1654 SCR_COPY (1), 1655 NADDR (sync_st), 1656 RADDR (sxfer), 1657 /* 1658 ** Load the wide mode and timing register 1659 */ 1660 SCR_COPY (1), 1661 NADDR (wide_st), 1662 RADDR (scntl3), 1663 /* 1664 ** Initialize the msgout buffer with a NOOP message. 1665 */ 1666 SCR_LOAD_REG (scratcha, M_NOOP), 1667 0, 1668 SCR_COPY (1), 1669 RADDR (scratcha), 1670 NADDR (msgout), 1671 SCR_COPY (1), 1672 RADDR (scratcha), 1673 NADDR (msgin), 1674 /* 1675 ** Message in phase ? 1676 */ 1677 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 1678 PADDR (dispatch), 1679 /* 1680 ** Extended or reject message ? 1681 */ 1682 SCR_FROM_REG (sbdl), 1683 0, 1684 SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)), 1685 PADDR (msg_in), 1686 SCR_JUMP ^ IFTRUE (DATA (M_REJECT)), 1687 PADDR (msg_reject), 1688 /* 1689 ** normal processing 1690 */ 1691 SCR_JUMP, 1692 PADDR (dispatch), 1693}/*-------------------------< SETMSG >----------------------*/,{ 1694 SCR_COPY (1), 1695 RADDR (scratcha), 1696 NADDR (msgout), 1697 SCR_SET (SCR_ATN), 1698 0, 1699}/*-------------------------< CLRACK >----------------------*/,{ 1700 /* 1701 ** Terminate possible pending message phase. 1702 */ 1703 SCR_CLR (SCR_ACK), 1704 0, 1705 1706}/*-----------------------< DISPATCH >----------------------*/,{ 1707 SCR_FROM_REG (HS_REG), 1708 0, 1709 SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)), 1710 SIR_NEGO_FAILED, 1711 /* 1712 ** remove bogus output signals 1713 */ 1714 SCR_REG_REG (socl, SCR_AND, CACK|CATN), 1715 0, 1716 SCR_RETURN ^ IFTRUE (WHEN (SCR_DATA_OUT)), 1717 0, 1718 SCR_RETURN ^ IFTRUE (IF (SCR_DATA_IN)), 1719 0, 1720 SCR_JUMP ^ IFTRUE (IF (SCR_MSG_OUT)), 1721 PADDR (msg_out), 1722 SCR_JUMP ^ IFTRUE (IF (SCR_MSG_IN)), 1723 PADDR (msg_in), 1724 SCR_JUMP ^ IFTRUE (IF (SCR_COMMAND)), 1725 PADDR (command), 1726 SCR_JUMP ^ IFTRUE (IF (SCR_STATUS)), 1727 PADDR (status), 1728 /* 1729 ** Discard one illegal phase byte, if required. 1730 */ 1731 SCR_LOAD_REG (scratcha, XE_BAD_PHASE), 1732 0, 1733 SCR_COPY (1), 1734 RADDR (scratcha), 1735 NADDR (xerr_st), 1736 SCR_JUMPR ^ IFFALSE (IF (SCR_ILG_OUT)), 1737 8, 1738 SCR_MOVE_ABS (1) ^ SCR_ILG_OUT, 1739 NADDR (scratch), 1740 SCR_JUMPR ^ IFFALSE (IF (SCR_ILG_IN)), 1741 8, 1742 SCR_MOVE_ABS (1) ^ SCR_ILG_IN, 1743 NADDR (scratch), 1744 SCR_JUMP, 1745 PADDR (dispatch), 1746 1747}/*-------------------------< NO_DATA >--------------------*/,{ 1748 /* 1749 ** The target wants to tranfer too much data 1750 ** or in the wrong direction. 1751 ** Remember that in extended error. 1752 */ 1753 SCR_LOAD_REG (scratcha, XE_EXTRA_DATA), 1754 0, 1755 SCR_COPY (1), 1756 RADDR (scratcha), 1757 NADDR (xerr_st), 1758 /* 1759 ** Discard one data byte, if required. 1760 */ 1761 SCR_JUMPR ^ IFFALSE (WHEN (SCR_DATA_OUT)), 1762 8, 1763 SCR_MOVE_ABS (1) ^ SCR_DATA_OUT, 1764 NADDR (scratch), 1765 SCR_JUMPR ^ IFFALSE (IF (SCR_DATA_IN)), 1766 8, 1767 SCR_MOVE_ABS (1) ^ SCR_DATA_IN, 1768 NADDR (scratch), 1769 /* 1770 ** .. and repeat as required. 1771 */ 1772 SCR_CALL, 1773 PADDR (dispatch), 1774 SCR_JUMP, 1775 PADDR (no_data), 1776}/*-------------------------< CHECKATN >--------------------*/,{ 1777 /* 1778 ** If AAP (bit 1 of scntl0 register) is set 1779 ** and a parity error is detected, 1780 ** the script processor asserts ATN. 1781 ** 1782 ** The target should switch to a MSG_OUT phase 1783 ** to get the message. 1784 */ 1785 SCR_FROM_REG (socl), 1786 0, 1787 SCR_JUMP ^ IFFALSE (MASK (CATN, CATN)), 1788 PADDR (dispatch), 1789 /* 1790 ** count it 1791 */ 1792 SCR_REG_REG (PS_REG, SCR_ADD, 1), 1793 0, 1794 /* 1795 ** Prepare a M_ID_ERROR message 1796 ** (initiator detected error). 1797 ** The target should retry the transfer. 1798 */ 1799 SCR_LOAD_REG (scratcha, M_ID_ERROR), 1800 0, 1801 SCR_JUMP, 1802 PADDR (setmsg), 1803 1804}/*-------------------------< COMMAND >--------------------*/,{ 1805 /* 1806 ** If this is not a GETCC transfer ... 1807 */ 1808 SCR_FROM_REG (SS_REG), 1809 0, 1810/*<<<*/ SCR_JUMPR ^ IFTRUE (DATA (S_CHECK_COND)), 1811 28, 1812 /* 1813 ** ... set a timestamp ... 1814 */ 1815 SCR_COPY (sizeof (struct timeval)), 1816 (ncrcmd) &time, 1817 NADDR (header.stamp.command), 1818 /* 1819 ** ... and send the command 1820 */ 1821 SCR_MOVE_TBL ^ SCR_COMMAND, 1822 offsetof (struct dsb, cmd), 1823 SCR_JUMP, 1824 PADDR (dispatch), 1825 /* 1826 ** Send the GETCC command 1827 */ 1828/*>>>*/ SCR_MOVE_TBL ^ SCR_COMMAND, 1829 offsetof (struct dsb, scmd), 1830 SCR_JUMP, 1831 PADDR (dispatch), 1832 1833}/*-------------------------< STATUS >--------------------*/,{ 1834 /* 1835 ** set the timestamp. 1836 */ 1837 SCR_COPY (sizeof (struct timeval)), 1838 (ncrcmd) &time, 1839 NADDR (header.stamp.status), 1840 /* 1841 ** If this is a GETCC transfer, 1842 */ 1843 SCR_FROM_REG (SS_REG), 1844 0, 1845/*<<<*/ SCR_JUMPR ^ IFFALSE (DATA (S_CHECK_COND)), 1846 40, 1847 /* 1848 ** get the status 1849 */ 1850 SCR_MOVE_ABS (1) ^ SCR_STATUS, 1851 NADDR (scratch), 1852 /* 1853 ** Save status to scsi_status. 1854 ** Mark as complete. 1855 ** And wait for disconnect. 1856 */ 1857 SCR_TO_REG (SS_REG), 1858 0, 1859 SCR_REG_REG (SS_REG, SCR_OR, S_SENSE), 1860 0, 1861 SCR_LOAD_REG (HS_REG, HS_COMPLETE), 1862 0, 1863 SCR_JUMP, 1864 PADDR (checkatn), 1865 /* 1866 ** If it was no GETCC transfer, 1867 ** save the status to scsi_status. 1868 */ 1869/*>>>*/ SCR_MOVE_ABS (1) ^ SCR_STATUS, 1870 NADDR (scratch), 1871 SCR_TO_REG (SS_REG), 1872 0, 1873 /* 1874 ** if it was no check condition ... 1875 */ 1876 SCR_JUMP ^ IFTRUE (DATA (S_CHECK_COND)), 1877 PADDR (checkatn), 1878 /* 1879 ** ... mark as complete. 1880 */ 1881 SCR_LOAD_REG (HS_REG, HS_COMPLETE), 1882 0, 1883 SCR_JUMP, 1884 PADDR (checkatn), 1885 1886}/*-------------------------< MSG_IN >--------------------*/,{ 1887 /* 1888 ** Get the first byte of the message 1889 ** and save it to SCRATCHA. 1890 ** 1891 ** The script processor doesn't negate the 1892 ** ACK signal after this transfer. 1893 */ 1894 SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 1895 NADDR (msgin[0]), 1896 /* 1897 ** Check for message parity error. 1898 */ 1899 SCR_TO_REG (scratcha), 1900 0, 1901 SCR_FROM_REG (socl), 1902 0, 1903 SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), 1904 PADDR (msg_parity), 1905 SCR_FROM_REG (scratcha), 1906 0, 1907 /* 1908 ** Parity was ok, handle this message. 1909 */ 1910 SCR_JUMP ^ IFTRUE (DATA (M_COMPLETE)), 1911 PADDR (complete), 1912 SCR_JUMP ^ IFTRUE (DATA (M_SAVE_DP)), 1913 PADDR (save_dp), 1914 SCR_JUMP ^ IFTRUE (DATA (M_RESTORE_DP)), 1915 PADDR (restore_dp), 1916 SCR_JUMP ^ IFTRUE (DATA (M_DISCONNECT)), 1917 PADDR (disconnect), 1918 SCR_JUMP ^ IFTRUE (DATA (M_EXTENDED)), 1919 PADDR (msg_extended), 1920 SCR_JUMP ^ IFTRUE (DATA (M_NOOP)), 1921 PADDR (clrack), 1922 SCR_JUMP ^ IFTRUE (DATA (M_REJECT)), 1923 PADDR (msg_reject), 1924 SCR_JUMP ^ IFTRUE (DATA (M_IGN_RESIDUE)), 1925 PADDR (msg_ign_residue), 1926 /* 1927 ** Rest of the messages left as 1928 ** an exercise ... 1929 ** 1930 ** Unimplemented messages: 1931 ** fall through to MSG_BAD. 1932 */ 1933}/*-------------------------< MSG_BAD >------------------*/,{ 1934 /* 1935 ** unimplemented message - reject it. 1936 */ 1937 SCR_INT, 1938 SIR_REJECT_SENT, 1939 SCR_LOAD_REG (scratcha, M_REJECT), 1940 0, 1941 SCR_JUMP, 1942 PADDR (setmsg), 1943 1944}/*-------------------------< MSG_PARITY >---------------*/,{ 1945 /* 1946 ** count it 1947 */ 1948 SCR_REG_REG (PS_REG, SCR_ADD, 0x01), 1949 0, 1950 /* 1951 ** send a "message parity error" message. 1952 */ 1953 SCR_LOAD_REG (scratcha, M_PARITY), 1954 0, 1955 SCR_JUMP, 1956 PADDR (setmsg), 1957}/*-------------------------< MSG_REJECT >---------------*/,{ 1958 /* 1959 ** If a negotiation was in progress, 1960 ** negotiation failed. 1961 */ 1962 SCR_FROM_REG (HS_REG), 1963 0, 1964 SCR_INT ^ IFTRUE (DATA (HS_NEGOTIATE)), 1965 SIR_NEGO_FAILED, 1966 /* 1967 ** else make host log this message 1968 */ 1969 SCR_INT ^ IFFALSE (DATA (HS_NEGOTIATE)), 1970 SIR_REJECT_RECEIVED, 1971 SCR_JUMP, 1972 PADDR (clrack), 1973 1974}/*-------------------------< MSG_IGN_RESIDUE >----------*/,{ 1975 /* 1976 ** Terminate cycle 1977 */ 1978 SCR_CLR (SCR_ACK), 1979 0, 1980 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 1981 PADDR (dispatch), 1982 /* 1983 ** get residue size. 1984 */ 1985 SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 1986 NADDR (msgin[1]), 1987 /* 1988 ** Check for message parity error. 1989 */ 1990 SCR_TO_REG (scratcha), 1991 0, 1992 SCR_FROM_REG (socl), 1993 0, 1994 SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), 1995 PADDR (msg_parity), 1996 SCR_FROM_REG (scratcha), 1997 0, 1998 /* 1999 ** Size is 0 .. ignore message. 2000 */ 2001 SCR_JUMP ^ IFTRUE (DATA (0)), 2002 PADDR (clrack), 2003 /* 2004 ** Size is not 1 .. have to interrupt. 2005 */ 2006/*<<<*/ SCR_JUMPR ^ IFFALSE (DATA (1)), 2007 40, 2008 /* 2009 ** Check for residue byte in swide register 2010 */ 2011 SCR_FROM_REG (scntl2), 2012 0, 2013/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (WSR, WSR)), 2014 16, 2015 /* 2016 ** There IS data in the swide register. 2017 ** Discard it. 2018 */ 2019 SCR_REG_REG (scntl2, SCR_OR, WSR), 2020 0, 2021 SCR_JUMP, 2022 PADDR (clrack), 2023 /* 2024 ** Load again the size to the sfbr register. 2025 */ 2026/*>>>*/ SCR_FROM_REG (scratcha), 2027 0, 2028/*>>>*/ SCR_INT, 2029 SIR_IGN_RESIDUE, 2030 SCR_JUMP, 2031 PADDR (clrack), 2032 2033}/*-------------------------< MSG_EXTENDED >-------------*/,{ 2034 /* 2035 ** Terminate cycle 2036 */ 2037 SCR_CLR (SCR_ACK), 2038 0, 2039 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 2040 PADDR (dispatch), 2041 /* 2042 ** get length. 2043 */ 2044 SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 2045 NADDR (msgin[1]), 2046 /* 2047 ** Check for message parity error. 2048 */ 2049 SCR_TO_REG (scratcha), 2050 0, 2051 SCR_FROM_REG (socl), 2052 0, 2053 SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), 2054 PADDR (msg_parity), 2055 SCR_FROM_REG (scratcha), 2056 0, 2057 /* 2058 */ 2059 SCR_JUMP ^ IFTRUE (DATA (3)), 2060 PADDR (msg_ext_3), 2061 SCR_JUMP ^ IFFALSE (DATA (2)), 2062 PADDR (msg_bad), 2063}/*-------------------------< MSG_EXT_2 >----------------*/,{ 2064 SCR_CLR (SCR_ACK), 2065 0, 2066 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 2067 PADDR (dispatch), 2068 /* 2069 ** get extended message code. 2070 */ 2071 SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 2072 NADDR (msgin[2]), 2073 /* 2074 ** Check for message parity error. 2075 */ 2076 SCR_TO_REG (scratcha), 2077 0, 2078 SCR_FROM_REG (socl), 2079 0, 2080 SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), 2081 PADDR (msg_parity), 2082 SCR_FROM_REG (scratcha), 2083 0, 2084 SCR_JUMP ^ IFTRUE (DATA (M_X_WIDE_REQ)), 2085 PADDR (msg_wdtr), 2086 /* 2087 ** unknown extended message 2088 */ 2089 SCR_JUMP, 2090 PADDR (msg_bad) 2091}/*-------------------------< MSG_WDTR >-----------------*/,{ 2092 SCR_CLR (SCR_ACK), 2093 0, 2094 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 2095 PADDR (dispatch), 2096 /* 2097 ** get data bus width 2098 */ 2099 SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 2100 NADDR (msgin[3]), 2101 SCR_FROM_REG (socl), 2102 0, 2103 SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), 2104 PADDR (msg_parity), 2105 /* 2106 ** let the host do the real work. 2107 */ 2108 SCR_INT, 2109 SIR_NEGO_WIDE, 2110 /* 2111 ** let the target fetch our answer. 2112 */ 2113 SCR_SET (SCR_ATN), 2114 0, 2115 SCR_CLR (SCR_ACK), 2116 0, 2117 2118 SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)), 2119 SIR_NEGO_PROTO, 2120 /* 2121 ** Send the M_X_WIDE_REQ 2122 */ 2123 SCR_MOVE_ABS (4) ^ SCR_MSG_OUT, 2124 NADDR (msgout), 2125 SCR_CLR (SCR_ATN), 2126 0, 2127 SCR_COPY (1), 2128 RADDR (sfbr), 2129 NADDR (lastmsg), 2130 SCR_JUMP, 2131 PADDR (msg_out_done), 2132 2133}/*-------------------------< MSG_EXT_3 >----------------*/,{ 2134 SCR_CLR (SCR_ACK), 2135 0, 2136 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 2137 PADDR (dispatch), 2138 /* 2139 ** get extended message code. 2140 */ 2141 SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 2142 NADDR (msgin[2]), 2143 /* 2144 ** Check for message parity error. 2145 */ 2146 SCR_TO_REG (scratcha), 2147 0, 2148 SCR_FROM_REG (socl), 2149 0, 2150 SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), 2151 PADDR (msg_parity), 2152 SCR_FROM_REG (scratcha), 2153 0, 2154 SCR_JUMP ^ IFTRUE (DATA (M_X_SYNC_REQ)), 2155 PADDR (msg_sdtr), 2156 /* 2157 ** unknown extended message 2158 */ 2159 SCR_JUMP, 2160 PADDR (msg_bad) 2161 2162}/*-------------------------< MSG_SDTR >-----------------*/,{ 2163 SCR_CLR (SCR_ACK), 2164 0, 2165 SCR_JUMP ^ IFFALSE (WHEN (SCR_MSG_IN)), 2166 PADDR (dispatch), 2167 /* 2168 ** get period and offset 2169 */ 2170 SCR_MOVE_ABS (2) ^ SCR_MSG_IN, 2171 NADDR (msgin[3]), 2172 SCR_FROM_REG (socl), 2173 0, 2174 SCR_JUMP ^ IFTRUE (MASK (CATN, CATN)), 2175 PADDR (msg_parity), 2176 /* 2177 ** let the host do the real work. 2178 */ 2179 SCR_INT, 2180 SIR_NEGO_SYNC, 2181 /* 2182 ** let the target fetch our answer. 2183 */ 2184 SCR_SET (SCR_ATN), 2185 0, 2186 SCR_CLR (SCR_ACK), 2187 0, 2188 2189 SCR_INT ^ IFFALSE (WHEN (SCR_MSG_OUT)), 2190 SIR_NEGO_PROTO, 2191 /* 2192 ** Send the M_X_SYNC_REQ 2193 */ 2194 SCR_MOVE_ABS (5) ^ SCR_MSG_OUT, 2195 NADDR (msgout), 2196 SCR_CLR (SCR_ATN), 2197 0, 2198 SCR_COPY (1), 2199 RADDR (sfbr), 2200 NADDR (lastmsg), 2201 SCR_JUMP, 2202 PADDR (msg_out_done), 2203 2204}/*-------------------------< COMPLETE >-----------------*/,{ 2205 /* 2206 ** Complete message. 2207 ** 2208 ** If it's not the get condition code, 2209 ** copy TEMP register to LASTP in header. 2210 */ 2211 SCR_FROM_REG (SS_REG), 2212 0, 2213/*<<<*/ SCR_JUMPR ^ IFTRUE (MASK (S_SENSE, S_SENSE)), 2214 12, 2215 SCR_COPY (4), 2216 RADDR (temp), 2217 NADDR (header.lastp), 2218/*>>>*/ /* 2219 ** When we terminate the cycle by clearing ACK, 2220 ** the target may disconnect immediately. 2221 ** 2222 ** We don't want to be told of an 2223 ** "unexpected disconnect", 2224 ** so we disable this feature. 2225 */ 2226 SCR_REG_REG (scntl2, SCR_AND, 0x7f), 2227 0, 2228 /* 2229 ** Terminate cycle ... 2230 */ 2231 SCR_CLR (SCR_ACK|SCR_ATN), 2232 0, 2233 /* 2234 ** ... and wait for the disconnect. 2235 */ 2236 SCR_WAIT_DISC, 2237 0, 2238}/*-------------------------< CLEANUP >-------------------*/,{ 2239 /* 2240 ** dsa: Pointer to ccb 2241 ** or xxxxxxFF (no ccb) 2242 ** 2243 ** HS_REG: Host-Status (<>0!) 2244 */ 2245 SCR_FROM_REG (dsa), 2246 0, 2247 SCR_JUMP ^ IFTRUE (DATA (0xff)), 2248 PADDR (signal), 2249 /* 2250 ** dsa is valid. 2251 ** save the status registers 2252 */ 2253 SCR_COPY (4), 2254 RADDR (scr0), 2255 NADDR (header.status), 2256 /* 2257 ** and copy back the header to the ccb. 2258 */ 2259 SCR_COPY (4), 2260 RADDR (dsa), 2261 PADDR (cleanup0), 2262 SCR_COPY (sizeof (struct head)), 2263 NADDR (header), 2264}/*-------------------------< CLEANUP0 >--------------------*/,{ 2265 0, 2266 2267 /* 2268 ** If command resulted in "check condition" 2269 ** status and is not yet completed, 2270 ** try to get the condition code. 2271 */ 2272 SCR_FROM_REG (HS_REG), 2273 0, 2274/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (0, HS_DONEMASK)), 2275 16, 2276 SCR_FROM_REG (SS_REG), 2277 0, 2278 SCR_JUMP ^ IFTRUE (DATA (S_CHECK_COND)), 2279 PADDR(getcc2), 2280 /* 2281 ** And make the DSA register invalid. 2282 */ 2283/*>>>*/ SCR_LOAD_REG (dsa, 0xff), /* invalid */ 2284 0, 2285}/*-------------------------< SIGNAL >----------------------*/,{ 2286 /* 2287 ** if status = queue full, 2288 ** reinsert in startqueue and stall queue. 2289 */ 2290 SCR_FROM_REG (SS_REG), 2291 0, 2292 SCR_INT ^ IFTRUE (DATA (S_QUEUE_FULL)), 2293 SIR_STALL_QUEUE, 2294 /* 2295 ** if job completed ... 2296 */ 2297 SCR_FROM_REG (HS_REG), 2298 0, 2299 /* 2300 ** ... signal completion to the host 2301 */ 2302 SCR_INT_FLY ^ IFFALSE (MASK (0, HS_DONEMASK)), 2303 0, 2304 /* 2305 ** Auf zu neuen Schandtaten! 2306 */ 2307 SCR_JUMP, 2308 PADDR(start), 2309 2310}/*-------------------------< SAVE_DP >------------------*/,{ 2311 /* 2312 ** SAVE_DP message: 2313 ** Copy TEMP register to SAVEP in header. 2314 */ 2315 SCR_COPY (4), 2316 RADDR (temp), 2317 NADDR (header.savep), 2318 SCR_JUMP, 2319 PADDR (clrack), 2320}/*-------------------------< RESTORE_DP >---------------*/,{ 2321 /* 2322 ** RESTORE_DP message: 2323 ** Copy SAVEP in header to TEMP register. 2324 */ 2325 SCR_COPY (4), 2326 NADDR (header.savep), 2327 RADDR (temp), 2328 SCR_JUMP, 2329 PADDR (clrack), 2330 2331}/*-------------------------< DISCONNECT >---------------*/,{ 2332 /* 2333 ** If QUIRK_AUTOSAVE is set, 2334 ** do an "save pointer" operation. 2335 */ 2336 SCR_FROM_REG (QU_REG), 2337 0, 2338/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (QUIRK_AUTOSAVE, QUIRK_AUTOSAVE)), 2339 12, 2340 /* 2341 ** like SAVE_DP message: 2342 ** Copy TEMP register to SAVEP in header. 2343 */ 2344 SCR_COPY (4), 2345 RADDR (temp), 2346 NADDR (header.savep), 2347/*>>>*/ /* 2348 ** Check if temp==savep or temp==goalp: 2349 ** if not, log a missing save pointer message. 2350 ** In fact, it's a comparison mod 256. 2351 ** 2352 ** Hmmm, I hadn't thought that I would be urged to 2353 ** write this kind of ugly self modifying code. 2354 ** 2355 ** It's unbelievable, but the ncr53c8xx isn't able 2356 ** to subtract one register from another. 2357 */ 2358 SCR_FROM_REG (temp), 2359 0, 2360 /* 2361 ** You are not expected to understand this .. 2362 ** 2363 ** CAUTION: only little endian architectures supported! XXX 2364 */ 2365 SCR_COPY (1), 2366 NADDR (header.savep), 2367 PADDR (disconnect0), 2368}/*-------------------------< DISCONNECT0 >--------------*/,{ 2369/*<<<*/ SCR_JUMPR ^ IFTRUE (DATA (1)), 2370 20, 2371 /* 2372 ** neither this 2373 */ 2374 SCR_COPY (1), 2375 NADDR (header.goalp), 2376 PADDR (disconnect1), 2377}/*-------------------------< DISCONNECT1 >--------------*/,{ 2378 SCR_INT ^ IFFALSE (DATA (1)), 2379 SIR_MISSING_SAVE, 2380/*>>>*/ 2381 2382 /* 2383 ** DISCONNECTing ... 2384 ** 2385 ** disable the "unexpected disconnect" feature, 2386 ** and remove the ACK signal. 2387 */ 2388 SCR_REG_REG (scntl2, SCR_AND, 0x7f), 2389 0, 2390 SCR_CLR (SCR_ACK|SCR_ATN), 2391 0, 2392 /* 2393 ** Wait for the disconnect. 2394 */ 2395 SCR_WAIT_DISC, 2396 0, 2397 /* 2398 ** Profiling: 2399 ** Set a time stamp, 2400 ** and count the disconnects. 2401 */ 2402 SCR_COPY (sizeof (struct timeval)), 2403 (ncrcmd) &time, 2404 NADDR (header.stamp.disconnect), 2405 SCR_COPY (4), 2406 NADDR (disc_phys), 2407 RADDR (temp), 2408 SCR_REG_REG (temp, SCR_ADD, 0x01), 2409 0, 2410 SCR_COPY (4), 2411 RADDR (temp), 2412 NADDR (disc_phys), 2413 /* 2414 ** Status is: DISCONNECTED. 2415 */ 2416 SCR_LOAD_REG (HS_REG, HS_DISCONNECT), 2417 0, 2418 SCR_JUMP, 2419 PADDR (cleanup), 2420 2421}/*-------------------------< MSG_OUT >-------------------*/,{ 2422 /* 2423 ** The target requests a message. 2424 */ 2425 SCR_MOVE_ABS (1) ^ SCR_MSG_OUT, 2426 NADDR (msgout), 2427 SCR_COPY (1), 2428 RADDR (sfbr), 2429 NADDR (lastmsg), 2430 /* 2431 ** If it was no ABORT message ... 2432 */ 2433 SCR_JUMP ^ IFTRUE (DATA (M_ABORT)), 2434 PADDR (msg_out_abort), 2435 /* 2436 ** ... wait for the next phase 2437 ** if it's a message out, send it again, ... 2438 */ 2439 SCR_JUMP ^ IFTRUE (WHEN (SCR_MSG_OUT)), 2440 PADDR (msg_out), 2441}/*-------------------------< MSG_OUT_DONE >--------------*/,{ 2442 /* 2443 ** ... else clear the message ... 2444 */ 2445 SCR_LOAD_REG (scratcha, M_NOOP), 2446 0, 2447 SCR_COPY (4), 2448 RADDR (scratcha), 2449 NADDR (msgout), 2450 /* 2451 ** ... and process the next phase 2452 */ 2453 SCR_JUMP, 2454 PADDR (dispatch), 2455}/*-------------------------< MSG_OUT_ABORT >-------------*/,{ 2456 /* 2457 ** After ABORT message, 2458 ** 2459 ** expect an immediate disconnect, ... 2460 */ 2461 SCR_REG_REG (scntl2, SCR_AND, 0x7f), 2462 0, 2463 SCR_CLR (SCR_ACK|SCR_ATN), 2464 0, 2465 SCR_WAIT_DISC, 2466 0, 2467 /* 2468 ** ... and set the status to "ABORTED" 2469 */ 2470 SCR_LOAD_REG (HS_REG, HS_ABORTED), 2471 0, 2472 SCR_JUMP, 2473 PADDR (cleanup), 2474 2475}/*-------------------------< GETCC >-----------------------*/,{ 2476 /* 2477 ** The ncr doesn't have an indirect load 2478 ** or store command. So we have to 2479 ** copy part of the control block to a 2480 ** fixed place, where we can modify it. 2481 ** 2482 ** We patch the address part of a COPY command 2483 ** with the address of the dsa register ... 2484 */ 2485 SCR_COPY (4), 2486 RADDR (dsa), 2487 PADDR (getcc1), 2488 /* 2489 ** ... then we do the actual copy. 2490 */ 2491 SCR_COPY (sizeof (struct head)), 2492}/*-------------------------< GETCC1 >----------------------*/,{ 2493 0, 2494 NADDR (header), 2495 /* 2496 ** Initialize the status registers 2497 */ 2498 SCR_COPY (4), 2499 NADDR (header.status), 2500 RADDR (scr0), 2501}/*-------------------------< GETCC2 >----------------------*/,{ 2502 /* 2503 ** Get the condition code from a target. 2504 ** 2505 ** DSA points to a data structure. 2506 ** Set TEMP to the script location 2507 ** that receives the condition code. 2508 ** 2509 ** Because there is no script command 2510 ** to load a longword into a register, 2511 ** we use a CALL command. 2512 */ 2513/*<<<*/ SCR_CALLR, 2514 24, 2515 /* 2516 ** Get the condition code. 2517 */ 2518 SCR_MOVE_TBL ^ SCR_DATA_IN, 2519 offsetof (struct dsb, sense), 2520 /* 2521 ** No data phase may follow! 2522 */ 2523 SCR_CALL, 2524 PADDR (checkatn), 2525 SCR_JUMP, 2526 PADDR (no_data), 2527/*>>>*/ 2528 2529 /* 2530 ** The CALL jumps to this point. 2531 ** Prepare for a RESTORE_POINTER message. 2532 ** Save the TEMP register into the saved pointer. 2533 */ 2534 SCR_COPY (4), 2535 RADDR (temp), 2536 NADDR (header.savep), 2537 /* 2538 ** Load scratcha, because in case of a selection timeout, 2539 ** the host will expect a new value for startpos in 2540 ** the scratcha register. 2541 */ 2542 SCR_COPY (4), 2543 PADDR (startpos), 2544 RADDR (scratcha), 2545#ifdef NCR_GETCC_WITHMSG 2546 /* 2547 ** If QUIRK_NOMSG is set, select without ATN. 2548 ** and don't send a message. 2549 */ 2550 SCR_FROM_REG (QU_REG), 2551 0, 2552 SCR_JUMP ^ IFTRUE (MASK (QUIRK_NOMSG, QUIRK_NOMSG)), 2553 PADDR(getcc3), 2554 /* 2555 ** Then try to connect to the target. 2556 ** If we are reselected, special treatment 2557 ** of the current job is required before 2558 ** accepting the reselection. 2559 */ 2560 SCR_SEL_TBL_ATN ^ offsetof (struct dsb, select), 2561 PADDR(badgetcc), 2562 /* 2563 ** save target id. 2564 */ 2565 SCR_FROM_REG (sdid), 2566 0, 2567 SCR_TO_REG (ctest0), 2568 0, 2569 /* 2570 ** Send the IDENTIFY message. 2571 ** In case of short transfer, remove ATN. 2572 */ 2573 SCR_MOVE_TBL ^ SCR_MSG_OUT, 2574 offsetof (struct dsb, smsg2), 2575 SCR_CLR (SCR_ATN), 2576 0, 2577 /* 2578 ** save the first byte of the message. 2579 */ 2580 SCR_COPY (1), 2581 RADDR (sfbr), 2582 NADDR (lastmsg), 2583 SCR_JUMP, 2584 PADDR (prepare2), 2585 2586#endif 2587}/*-------------------------< GETCC3 >----------------------*/,{ 2588 /* 2589 ** Try to connect to the target. 2590 ** If we are reselected, special treatment 2591 ** of the current job is required before 2592 ** accepting the reselection. 2593 ** 2594 ** Silly target won't accept a message. 2595 ** Select without ATN. 2596 */ 2597 SCR_SEL_TBL ^ offsetof (struct dsb, select), 2598 PADDR(badgetcc), 2599 /* 2600 ** save target id. 2601 */ 2602 SCR_FROM_REG (sdid), 2603 0, 2604 SCR_TO_REG (ctest0), 2605 0, 2606 /* 2607 ** Force error if selection timeout 2608 */ 2609 SCR_JUMPR ^ IFTRUE (WHEN (SCR_MSG_IN)), 2610 0, 2611 /* 2612 ** don't negotiate. 2613 */ 2614 SCR_JUMP, 2615 PADDR (prepare2), 2616 2617}/*------------------------< BADGETCC >---------------------*/,{ 2618 /* 2619 ** If SIGP was set, clear it and try again. 2620 */ 2621 SCR_FROM_REG (ctest2), 2622 0, 2623 SCR_JUMP ^ IFTRUE (MASK (CSIGP,CSIGP)), 2624 PADDR (getcc2), 2625 SCR_INT, 2626 SIR_SENSE_FAILED, 2627}/*-------------------------< RESELECT >--------------------*/,{ 2628 /* 2629 ** make the DSA invalid. 2630 */ 2631 SCR_LOAD_REG (dsa, 0xff), 2632 0, 2633 SCR_CLR (SCR_TRG), 2634 0, 2635 /* 2636 ** Sleep waiting for a reselection. 2637 ** If SIGP is set, special treatment. 2638 ** 2639 ** Zu allem bereit .. 2640 */ 2641 SCR_WAIT_RESEL, 2642 PADDR(reselect2), 2643 /* 2644 ** ... zu nichts zu gebrauchen ? 2645 ** 2646 ** load the target id into the SFBR 2647 ** and jump to the control block. 2648 ** 2649 ** Look at the declarations of 2650 ** - struct ncb 2651 ** - struct tcb 2652 ** - struct lcb 2653 ** - struct ccb 2654 ** to understand what's going on. 2655 */ 2656 SCR_REG_SFBR (ssid, SCR_AND, 0x8F), 2657 0, 2658 SCR_TO_REG (ctest0), 2659 0, 2660 SCR_JUMP, 2661 NADDR (jump_tcb), 2662}/*-------------------------< RESELECT2 >-------------------*/,{ 2663 /* 2664 ** If it's not connected :( 2665 ** -> interrupted by SIGP bit. 2666 ** Jump to start. 2667 */ 2668 SCR_FROM_REG (ctest2), 2669 0, 2670 SCR_JUMP ^ IFTRUE (MASK (CSIGP,CSIGP)), 2671 PADDR (start), 2672 SCR_JUMP, 2673 PADDR (reselect), 2674 2675}/*-------------------------< RESEL_TMP >-------------------*/,{ 2676 /* 2677 ** The return address in TEMP 2678 ** is in fact the data structure address, 2679 ** so copy it to the DSA register. 2680 */ 2681 SCR_COPY (4), 2682 RADDR (temp), 2683 RADDR (dsa), 2684 SCR_JUMP, 2685 PADDR (prepare), 2686 2687}/*-------------------------< RESEL_LUN >-------------------*/,{ 2688 /* 2689 ** come back to this point 2690 ** to get an IDENTIFY message 2691 ** Wait for a msg_in phase. 2692 */ 2693/*<<<*/ SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)), 2694 48, 2695 /* 2696 ** message phase 2697 ** It's not a sony, it's a trick: 2698 ** read the data without acknowledging it. 2699 */ 2700 SCR_FROM_REG (sbdl), 2701 0, 2702/*<<<*/ SCR_JUMPR ^ IFFALSE (MASK (M_IDENTIFY, 0x98)), 2703 32, 2704 /* 2705 ** It WAS an Identify message. 2706 ** get it and ack it! 2707 */ 2708 SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 2709 NADDR (msgin), 2710 SCR_CLR (SCR_ACK), 2711 0, 2712 /* 2713 ** Mask out the lun. 2714 */ 2715 SCR_REG_REG (sfbr, SCR_AND, 0x07), 2716 0, 2717 SCR_RETURN, 2718 0, 2719 /* 2720 ** No message phase or no IDENTIFY message: 2721 ** return 0. 2722 */ 2723/*>>>*/ SCR_LOAD_SFBR (0), 2724 0, 2725 SCR_RETURN, 2726 0, 2727 2728}/*-------------------------< RESEL_TAG >-------------------*/,{ 2729 /* 2730 ** come back to this point 2731 ** to get a SIMPLE_TAG message 2732 ** Wait for a MSG_IN phase. 2733 */ 2734/*<<<*/ SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)), 2735 64, 2736 /* 2737 ** message phase 2738 ** It's a trick - read the data 2739 ** without acknowledging it. 2740 */ 2741 SCR_FROM_REG (sbdl), 2742 0, 2743/*<<<*/ SCR_JUMPR ^ IFFALSE (DATA (M_SIMPLE_TAG)), 2744 48, 2745 /* 2746 ** It WAS a SIMPLE_TAG message. 2747 ** get it and ack it! 2748 */ 2749 SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 2750 NADDR (msgin), 2751 SCR_CLR (SCR_ACK), 2752 0, 2753 /* 2754 ** Wait for the second byte (the tag) 2755 */ 2756/*<<<*/ SCR_JUMPR ^ IFFALSE (WHEN (SCR_MSG_IN)), 2757 24, 2758 /* 2759 ** Get it and ack it! 2760 */ 2761 SCR_MOVE_ABS (1) ^ SCR_MSG_IN, 2762 NADDR (msgin), 2763 SCR_CLR (SCR_ACK|SCR_CARRY), 2764 0, 2765 SCR_RETURN, 2766 0, 2767 /* 2768 ** No message phase or no SIMPLE_TAG message 2769 ** or no second byte: return 0. 2770 */ 2771/*>>>*/ SCR_LOAD_SFBR (0), 2772 0, 2773 SCR_SET (SCR_CARRY), 2774 0, 2775 SCR_RETURN, 2776 0, 2777 2778}/*-------------------------< DATA_IN >--------------------*/,{ 2779/* 2780** Because the size depends on the 2781** #define MAX_SCATTER parameter, 2782** it is filled in at runtime. 2783** 2784** SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)), 2785** PADDR (no_data), 2786** SCR_COPY (sizeof (struct timeval)), 2787** (ncrcmd) &time, 2788** NADDR (header.stamp.data), 2789** SCR_MOVE_TBL ^ SCR_DATA_IN, 2790** offsetof (struct dsb, data[ 0]), 2791** 2792** ##===========< i=1; i<MAX_SCATTER >========= 2793** || SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_IN)), 2794** || PADDR (checkatn), 2795** || SCR_MOVE_TBL ^ SCR_DATA_IN, 2796** || offsetof (struct dsb, data[ i]), 2797** ##========================================== 2798** 2799** SCR_CALL, 2800** PADDR (checkatn), 2801** SCR_JUMP, 2802** PADDR (no_data), 2803*/ 28040 2805}/*-------------------------< DATA_OUT >-------------------*/,{ 2806/* 2807** Because the size depends on the 2808** #define MAX_SCATTER parameter, 2809** it is filled in at runtime. 2810** 2811** SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)), 2812** PADDR (no_data), 2813** SCR_COPY (sizeof (struct timeval)), 2814** (ncrcmd) &time, 2815** NADDR (header.stamp.data), 2816** SCR_MOVE_TBL ^ SCR_DATA_OUT, 2817** offsetof (struct dsb, data[ 0]), 2818** 2819** ##===========< i=1; i<MAX_SCATTER >========= 2820** || SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_OUT)), 2821** || PADDR (dispatch), 2822** || SCR_MOVE_TBL ^ SCR_DATA_OUT, 2823** || offsetof (struct dsb, data[ i]), 2824** ##========================================== 2825** 2826** SCR_CALL, 2827** PADDR (dispatch), 2828** SCR_JUMP, 2829** PADDR (no_data), 2830** 2831**--------------------------------------------------------- 2832*/ 2833(u_long)&ident 2834 2835}/*-------------------------< ABORTTAG >-------------------*/,{ 2836 /* 2837 ** Abort a bad reselection. 2838 ** Set the message to ABORT vs. ABORT_TAG 2839 */ 2840 SCR_LOAD_REG (scratcha, M_ABORT_TAG), 2841 0, 2842 SCR_JUMPR ^ IFFALSE (CARRYSET), 2843 8, 2844}/*-------------------------< ABORT >----------------------*/,{ 2845 SCR_LOAD_REG (scratcha, M_ABORT), 2846 0, 2847 SCR_COPY (1), 2848 RADDR (scratcha), 2849 NADDR (msgout), 2850 SCR_SET (SCR_ATN), 2851 0, 2852 SCR_CLR (SCR_ACK), 2853 0, 2854 /* 2855 ** and send it. 2856 ** we expect an immediate disconnect 2857 */ 2858 SCR_REG_REG (scntl2, SCR_AND, 0x7f), 2859 0, 2860 SCR_MOVE_ABS (1) ^ SCR_MSG_OUT, 2861 NADDR (msgout), 2862 SCR_COPY (1), 2863 RADDR (sfbr), 2864 NADDR (lastmsg), 2865 SCR_CLR (SCR_ACK|SCR_ATN), 2866 0, 2867 SCR_WAIT_DISC, 2868 0, 2869 SCR_JUMP, 2870 PADDR (start), 2871}/*-------------------------< SNOOPTEST >-------------------*/,{ 2872 /* 2873 ** Read the variable. 2874 */ 2875 SCR_COPY (4), 2876 (ncrcmd) &ncr_cache, 2877 RADDR (scratcha), 2878 /* 2879 ** Write the variable. 2880 */ 2881 SCR_COPY (4), 2882 RADDR (temp), 2883 (ncrcmd) &ncr_cache, 2884 /* 2885 ** Read back the variable. 2886 */ 2887 SCR_COPY (4), 2888 (ncrcmd) &ncr_cache, 2889 RADDR (temp), 2890}/*-------------------------< SNOOPEND >-------------------*/,{ 2891 /* 2892 ** And stop. 2893 */ 2894 SCR_INT, 2895 99, 2896}/*--------------------------------------------------------*/ 2897}; 2898 2899/*========================================================== 2900** 2901** 2902** Fill in #define dependent parts of the script 2903** 2904** 2905**========================================================== 2906*/ 2907 2908void ncr_script_fill (struct script * scr) 2909{ 2910 int i; 2911 ncrcmd *p; 2912 2913 p = scr->tryloop; 2914 for (i=0; i<MAX_START; i++) { 2915 *p++ =SCR_COPY (4); 2916 *p++ =NADDR (squeue[i]); 2917 *p++ =RADDR (dsa); 2918 *p++ =SCR_CALL; 2919 *p++ =PADDR (trysel); 2920 }; 2921 *p++ =SCR_JUMP; 2922 *p++ =PADDR(tryloop); 2923 2924 assert ((u_long)p == (u_long)&scr->tryloop + sizeof (scr->tryloop)); 2925 2926 p = scr->data_in; 2927 2928 *p++ =SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_IN)); 2929 *p++ =PADDR (no_data); 2930 *p++ =SCR_COPY (sizeof (struct timeval)); 2931 *p++ =(ncrcmd) &time; 2932 *p++ =NADDR (header.stamp.data); 2933 *p++ =SCR_MOVE_TBL ^ SCR_DATA_IN; 2934 *p++ =offsetof (struct dsb, data[ 0]); 2935 2936 for (i=1; i<MAX_SCATTER; i++) { 2937 *p++ =SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_IN)); 2938 *p++ =PADDR (checkatn); 2939 *p++ =SCR_MOVE_TBL ^ SCR_DATA_IN; 2940 *p++ =offsetof (struct dsb, data[i]); 2941 }; 2942 2943 *p++ =SCR_CALL; 2944 *p++ =PADDR (checkatn); 2945 *p++ =SCR_JUMP; 2946 *p++ =PADDR (no_data); 2947 2948 assert ((u_long)p == (u_long)&scr->data_in + sizeof (scr->data_in)); 2949 2950 p = scr->data_out; 2951 2952 *p++ =SCR_JUMP ^ IFFALSE (WHEN (SCR_DATA_OUT)); 2953 *p++ =PADDR (no_data); 2954 *p++ =SCR_COPY (sizeof (struct timeval)); 2955 *p++ =(ncrcmd) &time; 2956 *p++ =NADDR (header.stamp.data); 2957 *p++ =SCR_MOVE_TBL ^ SCR_DATA_OUT; 2958 *p++ =offsetof (struct dsb, data[ 0]); 2959 2960 for (i=1; i<MAX_SCATTER; i++) { 2961 *p++ =SCR_CALL ^ IFFALSE (WHEN (SCR_DATA_OUT)); 2962 *p++ =PADDR (dispatch); 2963 *p++ =SCR_MOVE_TBL ^ SCR_DATA_OUT; 2964 *p++ =offsetof (struct dsb, data[i]); 2965 }; 2966 2967 *p++ =SCR_CALL; 2968 *p++ =PADDR (dispatch); 2969 *p++ =SCR_JUMP; 2970 *p++ =PADDR (no_data); 2971 2972 assert ((u_long)p == (u_long)&scr->data_out + sizeof (scr->data_out)); 2973} 2974 2975/*========================================================== 2976** 2977** 2978** Copy and rebind a script. 2979** 2980** 2981**========================================================== 2982*/ 2983 2984static void ncr_script_copy_and_bind (struct script *script, ncb_p np) 2985{ 2986 ncrcmd opcode, new, old; 2987 ncrcmd *src, *dst, *start, *end; 2988 int relocs; 2989 2990#ifndef __NetBSD__ 2991 np->script = (struct script*) vm_page_alloc_contig 2992 (round_page(sizeof (struct script)), 0x100000, 0xffffffff, PAGE_SIZE); 2993#else /* !__NetBSD___ */ 2994 np->script = (struct script *) 2995 malloc (sizeof (struct script), M_DEVBUF, M_WAITOK); 2996#endif /* __NetBSD__ */ 2997 2998 np->p_script = vtophys(np->script); 2999 3000 src = script->start; 3001 dst = np->script->start; 3002 3003 start = src; 3004 end = src + (sizeof (struct script) / 4); 3005 3006 while (src < end) { 3007 3008 *dst++ = opcode = *src++; 3009 3010 /* 3011 ** If we forget to change the length 3012 ** in struct script, a field will be 3013 ** padded with 0. This is an illegal 3014 ** command. 3015 */ 3016 3017 if (opcode == 0) { 3018 printf ("%s: ERROR0 IN SCRIPT at %d.\n", 3019 ncr_name(np), src-start-1); 3020 DELAY (1000000); 3021 }; 3022 3023 if (DEBUG_FLAGS & DEBUG_SCRIPT) 3024 printf ("%x: <%x>\n", 3025 (unsigned)(src-1), (unsigned)opcode); 3026 3027 /* 3028 ** We don't have to decode ALL commands 3029 */ 3030 switch (opcode >> 28) { 3031 3032 case 0xc: 3033 /* 3034 ** COPY has TWO arguments. 3035 */ 3036 relocs = 2; 3037 if ((src[0] ^ src[1]) & 3) { 3038 printf ("%s: ERROR1 IN SCRIPT at %d.\n", 3039 ncr_name(np), src-start-1); 3040 DELAY (1000000); 3041 }; 3042 break; 3043 3044 case 0x0: 3045 /* 3046 ** MOVE (absolute address) 3047 */ 3048 relocs = 1; 3049 break; 3050 3051 case 0x8: 3052 /* 3053 ** JUMP / CALL 3054 ** dont't relocate if relative :-) 3055 */ 3056 if (opcode & 0x00800000) 3057 relocs = 0; 3058 else 3059 relocs = 1; 3060 break; 3061 3062 case 0x4: 3063 case 0x5: 3064 case 0x6: 3065 case 0x7: 3066 relocs = 1; 3067 break; 3068 3069 default: 3070 relocs = 0; 3071 break; 3072 }; 3073 3074 if (relocs) { 3075 while (relocs--) { 3076 old = *src++; 3077 3078 switch (old & RELOC_MASK) { 3079 case RELOC_REGISTER: 3080 new = (old & ~RELOC_MASK) + np->paddr; 3081 break; 3082 case RELOC_LABEL: 3083 new = (old & ~RELOC_MASK) + np->p_script; 3084 break; 3085 case RELOC_SOFTC: 3086 new = (old & ~RELOC_MASK) + vtophys(np); 3087 break; 3088 case 0: 3089 /* Don't relocate a 0 address. */ 3090 if (old == 0) { 3091 new = old; 3092 break; 3093 } 3094 /* fall through */ 3095 default: 3096 new = vtophys(old); 3097 break; 3098 } 3099 3100 *dst++ = new; 3101 } 3102 } else 3103 *dst++ = *src++; 3104 3105 }; 3106} 3107 3108/*========================================================== 3109** 3110** 3111** Auto configuration. 3112** 3113** 3114**========================================================== 3115*/ 3116 3117/*---------------------------------------------------------- 3118** 3119** Reduce the transfer length to the max value 3120** we can transfer safely. 3121** 3122** Reading a block greater then MAX_SIZE from the 3123** raw (character) device exercises a memory leak 3124** in the vm subsystem. This is common to ALL devices. 3125** We have submitted a description of this bug to 3126** <FreeBSD-bugs@freefall.cdrom.com>. 3127** It should be fixed in the current release. 3128** 3129**---------------------------------------------------------- 3130*/ 3131 3132void ncr_min_phys (struct buf *bp) 3133{ 3134 if ((unsigned long)bp->b_bcount > MAX_SIZE) bp->b_bcount = MAX_SIZE; 3135} 3136 3137/*---------------------------------------------------------- 3138** 3139** Maximal number of outstanding requests per target. 3140** 3141**---------------------------------------------------------- 3142*/ 3143 3144u_int32_t ncr_info (int unit) 3145{ 3146 return (1); /* may be changed later */ 3147} 3148 3149/*---------------------------------------------------------- 3150** 3151** Probe the hostadapter. 3152** 3153**---------------------------------------------------------- 3154*/ 3155 3156#ifdef __NetBSD__ 3157 3158int 3159ncr_probe(parent, match, aux) 3160 struct device *parent; 3161 void *match, *aux; 3162{ 3163 struct cfdata *cf = match; 3164 struct pci_attach_args *pa = aux; 3165 3166#if 0 3167 if (!pci_targmatch(cf, pa)) 3168 return 0; 3169#endif 3170 if (pa->pa_id != NCR_810_ID && 3171 pa->pa_id != NCR_815_ID && 3172 pa->pa_id != NCR_825_ID && 3173 pa->pa_id != NCR_860_ID && 3174 pa->pa_id != NCR_875_ID && 3175 pa->pa_id != NCR_875_ID2 && 3176 pa->pa_id != NCR_885_ID && 3177 pa->pa_id != NCR_895_ID && 3178 pa->pa_id != NCR_896_ID) 3179 return 0; 3180 3181 return 1; 3182} 3183 3184#else /* !__NetBSD__ */ 3185 3186 3187static char* ncr_probe (pcici_t tag, pcidi_t type) 3188{ 3189 u_char rev = pci_conf_read (tag, PCI_CLASS_REG) & 0xff; 3190 switch (type) { 3191 3192 case NCR_810_ID: 3193 return (rev & 0xf0) == 0x00 3194 ? ("ncr 53c810 scsi") 3195 : ("ncr 53c810a scsi"); 3196 3197 case NCR_815_ID: 3198 return ("ncr 53c815 scsi"); 3199 3200 case NCR_825_ID: 3201 return (rev & 0xf0) == 0x00 3202 ? ("ncr 53c825 wide scsi") 3203 : ("ncr 53c825a wide scsi"); 3204 3205 case NCR_860_ID: 3206 return ("ncr 53c860 ultra scsi"); 3207 3208 case NCR_875_ID: 3209 case NCR_875_ID2: 3210 return ("ncr 53c875 ultra wide scsi"); 3211 case NCR_885_ID: 3212 return ("ncr 53c885 ultra wide scsi"); 3213 case NCR_895_ID: 3214 return ("ncr 53c895 ultra wide scsi"); 3215 case NCR_896_ID: 3216 return ("ncr 53c896 ultra wide scsi"); 3217 } 3218 return (NULL); 3219} 3220 3221#endif /* !__NetBSD__ */ 3222 3223 3224/*========================================================== 3225** 3226** 3227** Auto configuration: attach and init a host adapter. 3228** 3229** 3230**========================================================== 3231*/ 3232 3233#define MIN_ASYNC_PD 40 3234#define MIN_SYNC_PD 20 3235 3236#ifdef __NetBSD__ 3237 3238int 3239ncr_print() 3240{ 3241} 3242 3243void 3244ncr_attach(parent, self, aux) 3245 struct device *parent, *self; 3246 void *aux; 3247{ 3248 struct pci_attach_args *pa = aux; 3249 int retval; 3250 ncb_p np = (void *)self; 3251 3252 /* 3253 ** XXX NetBSD 3254 ** Perhaps try to figure what which model chip it is and print that 3255 ** out. 3256 */ 3257 printf("\n"); 3258 3259 /* 3260 ** Try to map the controller chip to 3261 ** virtual and physical memory. 3262 */ 3263 3264 retval = pci_map_mem(pa->pa_tag, 0x14, &np->vaddr, &np->paddr); 3265 if (retval) 3266 return; 3267 3268 np->sc_ih = pci_map_int(pa->pa_tag, PCI_IPL_BIO, ncr_intr, np); 3269 if (np->sc_ih == NULL) 3270 return; 3271 3272 3273#else /* !__NetBSD__ */ 3274 3275static void ncr_attach (pcici_t config_id, int unit) 3276{ 3277 ncb_p np = (struct ncb*) 0; 3278#if ! (__FreeBSD__ >= 2) 3279 extern unsigned bio_imask; 3280#endif 3281 3282#if (__FreeBSD__ >= 2) 3283 struct scsibus_data *scbus; 3284#endif 3285 3286 /* 3287 ** allocate structure 3288 */ 3289 3290 if (!np) { 3291 np = (ncb_p) malloc (sizeof (struct ncb), M_DEVBUF, M_WAITOK); 3292 if (!np) return; 3293 ncrp[unit]=np; 3294 } 3295 3296 /* 3297 ** initialize structure. 3298 */ 3299 3300 bzero (np, sizeof (*np)); 3301 np->unit = unit; 3302 3303 /* 3304 ** Try to map the controller chip to 3305 ** virtual and physical memory. 3306 */ 3307 3308 if (!pci_map_mem (config_id, 0x14, &np->vaddr, &np->paddr)) 3309 return; 3310 3311 /* 3312 ** Make the controller's registers available. 3313 ** Now the INB INW INL OUTB OUTW OUTL macros 3314 ** can be used safely. 3315 */ 3316 3317 np->reg = (struct ncr_reg*) np->vaddr; 3318 3319#ifdef NCR_IOMAPPED 3320 /* 3321 ** Try to map the controller chip into iospace. 3322 */ 3323 3324 if (!pci_map_port (config_id, 0x10, &np->port)) 3325 return; 3326#endif 3327 3328#endif /* !__NetBSD__ */ 3329 3330 /* 3331 ** Save some controller register default values 3332 */ 3333 3334 np->rv_dmode = INB (nc_dmode); 3335 np->rv_dcntl = INB (nc_dcntl) | CLSE | PFEN | NOCOM; 3336 np->rv_ctest3 = INB (nc_ctest3); 3337 np->rv_ctest5 = 0; 3338 np->rv_scntl3 = 0x13; /* default: 40MHz clock */ 3339 3340 /* 3341 ** Do chip dependent initialization. 3342 */ 3343 3344 np->maxwide = 0; 3345 np->ns_sync = 25; /* in units of 4ns */ 3346 np->maxoffs = 8; 3347 3348 /* 3349 ** Get the frequency of the chip's clock. 3350 ** Find the right value for scntl3. 3351 */ 3352 3353#ifdef __NetBSD__ 3354 switch (pa->pa_id) { 3355#else /* !__NetBSD__ */ 3356 switch (pci_conf_read (config_id, PCI_ID_REG)) { 3357#endif /* __NetBSD__ */ 3358 case NCR_825_ID: 3359 { 3360#ifndef __NetBSD__ 3361 u_char rev = pci_conf_read (config_id, PCI_CLASS_REG) & 0xff; 3362 if ((rev & 0xf0) == 0x10) 3363 np->maxoffs = 16; 3364#endif /* !__NetBSD__ */ 3365 np->maxwide = 1; 3366 break; 3367 } 3368 case NCR_860_ID: 3369 np->rv_scntl3 = 0x35; /* always assume 80MHz clock for 860 */ 3370 /*np->ns_sync = 12;*/ /* in units of 4ns */ 3371 break; 3372 case NCR_875_ID: 3373 case NCR_875_ID2: 3374 case NCR_885_ID: 3375 case NCR_895_ID: 3376 case NCR_896_ID: 3377 np->maxwide = 1; 3378 /*np->ns_sync = 12;*/ /* in units of 4ns */ 3379 np->maxoffs = 16; 3380#ifdef NCR_TEKRAM_EEPROM 3381 if (bootverbose) 3382 { 3383 printf ("%s: Tekram EEPROM read %s\n", 3384 ncr_name(np), 3385 read_tekram_eeprom (np, NULL) ? 3386 "succeeded" : "failed"); 3387 } 3388#endif /* NCR_TEKRAM_EEPROM */ 3389 ncr_getclock(np); 3390 break; 3391 } 3392 3393 /* 3394 ** Patch script to physical addresses 3395 */ 3396 3397 ncr_script_fill (&script0); 3398 ncr_script_copy_and_bind (&script0, np); 3399 np->ccb.p_ccb = vtophys (&np->ccb); 3400 3401 /* 3402 ** init data structure 3403 */ 3404 3405 np->jump_tcb.l_cmd = SCR_JUMP; 3406 np->jump_tcb.l_paddr = NCB_SCRIPT_PHYS (np, abort); 3407 3408 /* 3409 ** Get SCSI addr of host adapter (set by bios?). 3410 */ 3411 3412 np->myaddr = INB(nc_scid) & 0x07; 3413 if (!np->myaddr) np->myaddr = SCSI_NCR_MYADDR; 3414 3415#ifdef NCR_DUMP_REG 3416 /* 3417 ** Log the initial register contents 3418 */ 3419 { 3420 int reg; 3421#ifdef __NetBSD__ 3422 u_long config_id = pa->pa_tag; 3423#endif /* __NetBSD__ */ 3424 for (reg=0; reg<256; reg+=4) { 3425 if (reg%16==0) printf ("reg[%2x]", reg); 3426 printf (" %08x", (int)pci_conf_read (config_id, reg)); 3427 if (reg%16==12) printf ("\n"); 3428 } 3429 } 3430#endif /* NCR_DUMP_REG */ 3431 3432 /* 3433 ** Reset chip. 3434 */ 3435 3436 OUTB (nc_istat, SRST); 3437 DELAY (1000); 3438 OUTB (nc_istat, 0 ); 3439 3440 3441 /* 3442 ** Now check the cache handling of the pci chipset. 3443 */ 3444 3445 if (ncr_snooptest (np)) { 3446 printf ("CACHE INCORRECTLY CONFIGURED.\n"); 3447 return; 3448 }; 3449 3450#ifndef __NetBSD__ 3451 /* 3452 ** Install the interrupt handler. 3453 */ 3454 3455 if (!pci_map_int (config_id, ncr_intr, np, &bio_imask)) 3456 printf ("\tinterruptless mode: reduced performance.\n"); 3457#endif /* __NetBSD__ */ 3458 3459 /* 3460 ** After SCSI devices have been opened, we cannot 3461 ** reset the bus safely, so we do it here. 3462 ** Interrupt handler does the real work. 3463 */ 3464 3465 OUTB (nc_scntl1, CRST); 3466 DELAY (1000); 3467 3468 /* 3469 ** Process the reset exception, 3470 ** if interrupts are not enabled yet. 3471 ** Then enable disconnects. 3472 */ 3473 ncr_exception (np); 3474 np->disc = 1; 3475 3476 /* 3477 ** Now let the generic SCSI driver 3478 ** look for the SCSI devices on the bus .. 3479 */ 3480 3481#ifdef __NetBSD__ 3482 np->sc_link.adapter_softc = np; 3483 np->sc_link.adapter_target = np->myaddr; 3484 np->sc_link.openings = 1; 3485#else /* !__NetBSD__ */ 3486 np->sc_link.adapter_unit = unit; 3487 np->sc_link.adapter_softc = np; 3488 np->sc_link.adapter_targ = np->myaddr; 3489 np->sc_link.fordriver = 0; 3490#endif /* !__NetBSD__ */ 3491 np->sc_link.adapter = &ncr_switch; 3492 np->sc_link.device = &ncr_dev; 3493 np->sc_link.flags = 0; 3494 3495#ifdef __NetBSD__ 3496 config_found(self, &np->sc_link, ncr_print); 3497#else /* !__NetBSD__ */ 3498#if (__FreeBSD__ >= 2) 3499 scbus = scsi_alloc_bus(); 3500 if(!scbus) 3501 return; 3502 scbus->adapter_link = &np->sc_link; 3503 3504 if(np->maxwide) 3505 scbus->maxtarg = 15; 3506 3507 if (bootverbose) { 3508 unsigned t_from = 0; 3509 unsigned t_to = scbus->maxtarg; 3510 unsigned myaddr = np->myaddr; 3511 3512 char *txt_and = ""; 3513 printf ("%s scanning for targets ", ncr_name (np)); 3514 if (t_from < myaddr) { 3515 printf ("%d..%d ", t_from, myaddr -1); 3516 txt_and = "and "; 3517 } 3518 if (myaddr < t_to) 3519 printf ("%s%d..%d ", txt_and, myaddr +1, t_to); 3520 printf ("(V%d " NCR_DATE ")\n", NCR_VERSION); 3521 } 3522 3523 scsi_attachdevs (scbus); 3524 scbus = NULL; /* Upper-level SCSI code owns this now */ 3525#else 3526 scsi_attachdevs (&np->sc_link); 3527#endif /* !__FreeBSD__ >= 2 */ 3528#endif /* !__NetBSD__ */ 3529 3530 /* 3531 ** start the timeout daemon 3532 */ 3533 ncr_timeout (np); 3534 np->lasttime=0; 3535 3536 /* 3537 ** use SIMPLE TAG messages by default 3538 */ 3539 3540 np->order = M_SIMPLE_TAG; 3541 3542 /* 3543 ** Done. 3544 */ 3545 3546 return; 3547} 3548 3549/*========================================================== 3550** 3551** 3552** Process pending device interrupts. 3553** 3554** 3555**========================================================== 3556*/ 3557 3558static void 3559ncr_intr(vnp) 3560 void *vnp; 3561{ 3562 ncb_p np = vnp; 3563 int oldspl = splbio(); 3564 3565 if (DEBUG_FLAGS & DEBUG_TINY) printf ("["); 3566 3567 if (INB(nc_istat) & (INTF|SIP|DIP)) { 3568 /* 3569 ** Repeat until no outstanding ints 3570 */ 3571 do { 3572 ncr_exception (np); 3573 } while (INB(nc_istat) & (INTF|SIP|DIP)); 3574 3575 np->ticks = 100; 3576 }; 3577 3578 if (DEBUG_FLAGS & DEBUG_TINY) printf ("]\n"); 3579 3580 splx (oldspl); 3581} 3582 3583/*========================================================== 3584** 3585** 3586** Start execution of a SCSI command. 3587** This is called from the generic SCSI driver. 3588** 3589** 3590**========================================================== 3591*/ 3592 3593static int32_t ncr_start (struct scsi_xfer * xp) 3594{ 3595 ncb_p np = (ncb_p) xp->sc_link->adapter_softc; 3596 3597 struct scsi_generic * cmd = xp->cmd; 3598 ccb_p cp; 3599 lcb_p lp; 3600 tcb_p tp = &np->target[xp->sc_link->target]; 3601 3602 int i, oldspl, segments, flags = xp->flags; 3603 u_char qidx, nego, idmsg, *msgptr; 3604 u_long msglen, msglen2; 3605 3606 /*--------------------------------------------- 3607 ** 3608 ** Reset SCSI bus 3609 ** 3610 ** Interrupt handler does the real work. 3611 ** 3612 **--------------------------------------------- 3613 */ 3614 3615 if (flags & SCSI_RESET) { 3616 OUTB (nc_scntl1, CRST); 3617 DELAY (1000); 3618 return(COMPLETE); 3619 }; 3620 3621 /*--------------------------------------------- 3622 ** 3623 ** Some shortcuts ... 3624 ** 3625 **--------------------------------------------- 3626 */ 3627 3628 if ((xp->sc_link->target == np->myaddr ) || 3629 (xp->sc_link->target >= MAX_TARGET) || 3630 (xp->sc_link->lun >= MAX_LUN ) || 3631 (flags & SCSI_DATA_UIO)) { 3632 xp->error = XS_DRIVER_STUFFUP; 3633 return(COMPLETE); 3634 }; 3635 3636 /*--------------------------------------------- 3637 ** 3638 ** Diskaccess to partial blocks? 3639 ** 3640 **--------------------------------------------- 3641 */ 3642 3643 if ((xp->datalen & 0x1ff) && !(tp->inqdata[0] & 0x1f)) { 3644 switch (cmd->opcode) { 3645 case 0x28: /* READ_BIG (10) */ 3646 case 0xa8: /* READ_HUGE (12) */ 3647 case 0x2a: /* WRITE_BIG (10) */ 3648 case 0xaa: /* WRITE_HUGE(12) */ 3649 PRINT_ADDR(xp); 3650 printf ("access to partial disk block refused.\n"); 3651 xp->error = XS_DRIVER_STUFFUP; 3652 return(COMPLETE); 3653 }; 3654 }; 3655 3656 if ((unsigned)xp->datalen > 128*1024*1024) { 3657 PRINT_ADDR(xp); 3658 printf ("trying to transfer %8x bytes, mem addr = %8x\n", 3659 xp->datalen, xp->data); 3660 { 3661 int i; 3662 PRINT_ADDR(xp); 3663 printf ("command: %2x (", cmd->opcode); 3664 for (i = 0; i<11; i++) 3665 printf (" %2x", cmd->bytes[i]); 3666 printf (")\n"); 3667 } 3668 } 3669 3670 if (DEBUG_FLAGS & DEBUG_TINY) { 3671 PRINT_ADDR(xp); 3672 printf ("CMD=%x F=%x A=%x L=%x ", 3673 cmd->opcode, (unsigned)xp->flags, 3674 (unsigned) xp->data, (unsigned) xp->datalen); 3675 } 3676 3677 /*-------------------------------------------- 3678 ** 3679 ** Sanity checks ... 3680 ** copied from Elischer's Adaptec driver. 3681 ** 3682 **-------------------------------------------- 3683 */ 3684 3685 flags = xp->flags; 3686 if (!(flags & INUSE)) { 3687 printf("%s: ?INUSE?\n", ncr_name (np)); 3688 xp->flags |= INUSE; 3689 }; 3690 3691 if(flags & ITSDONE) { 3692 printf("%s: ?ITSDONE?\n", ncr_name (np)); 3693 xp->flags &= ~ITSDONE; 3694 }; 3695 3696 if (xp->bp) 3697 flags |= (SCSI_NOSLEEP); /* just to be sure */ 3698 3699 /*--------------------------------------------------- 3700 ** 3701 ** Assign a ccb / bind xp 3702 ** 3703 **---------------------------------------------------- 3704 */ 3705 3706 oldspl = splbio(); 3707 3708 if (!(cp=ncr_get_ccb (np, flags, xp->sc_link->target, xp->sc_link->lun))) { 3709 printf ("%s: no ccb.\n", ncr_name (np)); 3710 xp->error = XS_DRIVER_STUFFUP; 3711 splx(oldspl); 3712 return(TRY_AGAIN_LATER); 3713 }; 3714 cp->xfer = xp; 3715 3716 /*--------------------------------------------------- 3717 ** 3718 ** timestamp 3719 ** 3720 **---------------------------------------------------- 3721 */ 3722 3723 bzero (&cp->phys.header.stamp, sizeof (struct tstamp)); 3724 gettime(&cp->phys.header.stamp.start); 3725 3726 /*---------------------------------------------------- 3727 ** 3728 ** Get device quirks from a speciality table. 3729 ** 3730 **---------------------------------------------------- 3731 */ 3732 3733 if (tp->quirks & QUIRK_UPDATE) { 3734 int q = xp->sc_link->quirks; 3735 tp->quirks = QUIRK_NOMSG; 3736 if (q & SD_Q_NO_TAGS) 3737 tp->quirks |= QUIRK_NOTAGS; 3738 if (q & SD_Q_NO_SYNC) 3739 tp->quirks |= QUIRK_NOSYNC; 3740 if (q & SD_Q_NO_WIDE) 3741 tp->quirks |= QUIRK_NOWIDE16; 3742 if (bootverbose && tp->quirks) { 3743 PRINT_ADDR(xp); 3744 printf ("NCR quirks=0x%x\n", tp->quirks); 3745 }; 3746 /* 3747 ** set number of tags 3748 */ 3749 ncr_setmaxtags (tp, tp->usrtags); 3750 }; 3751 3752 /*--------------------------------------------------- 3753 ** 3754 ** negotiation required? 3755 ** 3756 **---------------------------------------------------- 3757 */ 3758 3759 nego = 0; 3760 3761 if (tp->inqdata[7]) { 3762 /* 3763 ** negotiate wide transfers ? 3764 */ 3765 3766 if (!tp->widedone) { 3767 if (tp->inqdata[7] & INQ7_WIDE16) { 3768 nego = NS_WIDE; 3769 } else 3770 tp->widedone=1; 3771 }; 3772 3773 /* 3774 ** negotiate synchronous transfers? 3775 */ 3776 3777 if (!nego && !tp->period) { 3778 if (SCSI_NCR_MAX_SYNC 3779#if defined (CDROM_ASYNC) 3780 && ((tp->inqdata[0] & 0x1f) != 5) 3781#endif 3782 && (tp->inqdata[7] & INQ7_SYNC)) { 3783 nego = NS_SYNC; 3784 } else { 3785 tp->period =0xffff; 3786 tp->sval = 0xe0; 3787 PRINT_ADDR(xp); 3788 printf ("asynchronous.\n"); 3789 }; 3790 }; 3791 }; 3792 3793 /*--------------------------------------------------- 3794 ** 3795 ** choose a new tag ... 3796 ** 3797 **---------------------------------------------------- 3798 */ 3799 3800 if ((lp = tp->lp[xp->sc_link->lun]) && (lp->usetags)) { 3801 /* 3802 ** assign a tag to this ccb! 3803 */ 3804 while (!cp->tag) { 3805 ccb_p cp2 = lp->next_ccb; 3806 lp->lasttag = lp->lasttag % 255 + 1; 3807 while (cp2 && cp2->tag != lp->lasttag) 3808 cp2 = cp2->next_ccb; 3809 if (cp2) continue; 3810 cp->tag=lp->lasttag; 3811 if (DEBUG_FLAGS & DEBUG_TAGS) { 3812 PRINT_ADDR(xp); 3813 printf ("using tag #%d.\n", cp->tag); 3814 }; 3815 }; 3816 } else { 3817 cp->tag=0; 3818 }; 3819 3820 /*---------------------------------------------------- 3821 ** 3822 ** Build the identify / tag / sdtr message 3823 ** 3824 **---------------------------------------------------- 3825 */ 3826 3827 idmsg = M_IDENTIFY | xp->sc_link->lun; 3828 if ((cp!=&np->ccb) && (np->disc)) 3829 idmsg |= 0x40; 3830 3831 msgptr = cp->scsi_smsg; 3832 msglen = 0; 3833 msgptr[msglen++] = idmsg; 3834 3835 if (cp->tag) { 3836 char tag; 3837 3838 tag = np->order; 3839 if (tag == 0) { 3840 /* 3841 ** Ordered write ops, unordered read ops. 3842 */ 3843 switch (cmd->opcode) { 3844 case 0x08: /* READ_SMALL (6) */ 3845 case 0x28: /* READ_BIG (10) */ 3846 case 0xa8: /* READ_HUGE (12) */ 3847 tag = M_SIMPLE_TAG; 3848 break; 3849 default: 3850 tag = M_ORDERED_TAG; 3851 } 3852 } 3853 msgptr[msglen++] = tag; 3854 msgptr[msglen++] = cp -> tag; 3855 } 3856 3857 switch (nego) { 3858 case NS_SYNC: 3859 msgptr[msglen++] = M_EXTENDED; 3860 msgptr[msglen++] = 3; 3861 msgptr[msglen++] = M_X_SYNC_REQ; 3862 msgptr[msglen++] = tp->minsync; 3863 msgptr[msglen++] = tp->maxoffs; 3864 if (DEBUG_FLAGS & DEBUG_NEGO) { 3865 PRINT_ADDR(cp->xfer); 3866 printf ("sync msgout: "); 3867 ncr_show_msg (&cp->scsi_smsg [msglen-5]); 3868 printf (".\n"); 3869 }; 3870 break; 3871 case NS_WIDE: 3872 msgptr[msglen++] = M_EXTENDED; 3873 msgptr[msglen++] = 2; 3874 msgptr[msglen++] = M_X_WIDE_REQ; 3875 msgptr[msglen++] = tp->usrwide; 3876 if (DEBUG_FLAGS & DEBUG_NEGO) { 3877 PRINT_ADDR(cp->xfer); 3878 printf ("wide msgout: "); 3879 ncr_show_msg (&cp->scsi_smsg [msglen-4]); 3880 printf (".\n"); 3881 }; 3882 break; 3883 }; 3884 3885 /*---------------------------------------------------- 3886 ** 3887 ** Build the identify message for getcc. 3888 ** 3889 **---------------------------------------------------- 3890 */ 3891 3892 cp -> scsi_smsg2 [0] = idmsg; 3893 msglen2 = 1; 3894 3895 /*---------------------------------------------------- 3896 ** 3897 ** Build the data descriptors 3898 ** 3899 **---------------------------------------------------- 3900 */ 3901 3902 segments = ncr_scatter (&cp->phys, (vm_offset_t) xp->data, 3903 (vm_size_t) xp->datalen); 3904 3905 if (segments < 0) { 3906 xp->error = XS_DRIVER_STUFFUP; 3907 ncr_free_ccb(np, cp, flags); 3908 splx(oldspl); 3909 return(COMPLETE); 3910 }; 3911 3912 /*---------------------------------------------------- 3913 ** 3914 ** Set the SAVED_POINTER. 3915 ** 3916 **---------------------------------------------------- 3917 */ 3918 3919 if (flags & SCSI_DATA_IN) { 3920 cp->phys.header.savep = NCB_SCRIPT_PHYS (np, data_in); 3921 cp->phys.header.goalp = cp->phys.header.savep +20 +segments*16; 3922 } else if (flags & SCSI_DATA_OUT) { 3923 cp->phys.header.savep = NCB_SCRIPT_PHYS (np, data_out); 3924 cp->phys.header.goalp = cp->phys.header.savep +20 +segments*16; 3925 } else { 3926 cp->phys.header.savep = NCB_SCRIPT_PHYS (np, no_data); 3927 cp->phys.header.goalp = cp->phys.header.savep; 3928 }; 3929 cp->phys.header.lastp = cp->phys.header.savep; 3930 3931 3932 /*---------------------------------------------------- 3933 ** 3934 ** fill in ccb 3935 ** 3936 **---------------------------------------------------- 3937 ** 3938 ** 3939 ** physical -> virtual backlink 3940 ** Generic SCSI command 3941 */ 3942 cp->phys.header.cp = cp; 3943 /* 3944 ** Startqueue 3945 */ 3946 cp->phys.header.launch.l_paddr = NCB_SCRIPT_PHYS (np, select); 3947 cp->phys.header.launch.l_cmd = SCR_JUMP; 3948 /* 3949 ** select 3950 */ 3951 cp->phys.select.sel_id = xp->sc_link->target; 3952 cp->phys.select.sel_scntl3 = tp->wval; 3953 cp->phys.select.sel_sxfer = tp->sval; 3954 /* 3955 ** message 3956 */ 3957 cp->phys.smsg.addr = CCB_PHYS (cp, scsi_smsg); 3958 cp->phys.smsg.size = msglen; 3959 3960 cp->phys.smsg2.addr = CCB_PHYS (cp, scsi_smsg2); 3961 cp->phys.smsg2.size = msglen2; 3962 /* 3963 ** command 3964 */ 3965 cp->phys.cmd.addr = vtophys (cmd); 3966 cp->phys.cmd.size = xp->cmdlen; 3967 /* 3968 ** sense command 3969 */ 3970 cp->phys.scmd.addr = CCB_PHYS (cp, sensecmd); 3971 cp->phys.scmd.size = 6; 3972 /* 3973 ** patch requested size into sense command 3974 */ 3975 cp->sensecmd[0] = 0x03; 3976 cp->sensecmd[1] = xp->sc_link->lun << 5; 3977 cp->sensecmd[4] = sizeof(struct scsi_sense_data); 3978 if (xp->req_sense_length) 3979 cp->sensecmd[4] = xp->req_sense_length; 3980 /* 3981 ** sense data 3982 */ 3983 cp->phys.sense.addr = vtophys (&cp->xfer->sense); 3984 cp->phys.sense.size = sizeof(struct scsi_sense_data); 3985 /* 3986 ** status 3987 */ 3988 cp->actualquirks = tp->quirks; 3989 cp->host_status = nego ? HS_NEGOTIATE : HS_BUSY; 3990 cp->scsi_status = S_ILLEGAL; 3991 cp->parity_status = 0; 3992 3993 cp->xerr_status = XE_OK; 3994 cp->sync_status = tp->sval; 3995 cp->nego_status = nego; 3996 cp->wide_status = tp->wval; 3997 3998 /*---------------------------------------------------- 3999 ** 4000 ** Critical region: start this job. 4001 ** 4002 **---------------------------------------------------- 4003 */ 4004 4005 /* 4006 ** reselect pattern and activate this job. 4007 */ 4008 4009 cp->jump_ccb.l_cmd = (SCR_JUMP ^ IFFALSE (DATA (cp->tag))); 4010 cp->tlimit = time.tv_sec + xp->timeout / 1000 + 2; 4011 cp->magic = CCB_MAGIC; 4012 4013 /* 4014 ** insert into start queue. 4015 */ 4016 4017 qidx = np->squeueput + 1; 4018 if (qidx >= MAX_START) qidx=0; 4019 np->squeue [qidx ] = NCB_SCRIPT_PHYS (np, idle); 4020 np->squeue [np->squeueput] = CCB_PHYS (cp, phys); 4021 np->squeueput = qidx; 4022 4023 if(DEBUG_FLAGS & DEBUG_QUEUE) 4024 printf ("%s: queuepos=%d tryoffset=%d.\n", ncr_name (np), 4025 np->squeueput, 4026 (unsigned)(np->script->startpos[0]- 4027 (NCB_SCRIPT_PHYS (np, tryloop)))); 4028 4029 /* 4030 ** Script processor may be waiting for reselect. 4031 ** Wake it up. 4032 */ 4033 OUTB (nc_istat, SIGP); 4034 4035 /* 4036 ** and reenable interrupts 4037 */ 4038 splx (oldspl); 4039 4040 /* 4041 ** If interrupts are enabled, return now. 4042 ** Command is successfully queued. 4043 */ 4044 4045#ifdef __NetBSD__ 4046 if (!(flags & SCSI_POLL)) { 4047#else /* !__NetBSD__ */ 4048 if (!(flags & SCSI_NOMASK)) { 4049#endif /* __NetBSD__ */ 4050 if (np->lasttime) { 4051 if(DEBUG_FLAGS & DEBUG_TINY) printf ("Q"); 4052 return(SUCCESSFULLY_QUEUED); 4053 }; 4054 }; 4055 4056 /*---------------------------------------------------- 4057 ** 4058 ** Interrupts not yet enabled - have to poll. 4059 ** 4060 **---------------------------------------------------- 4061 */ 4062 4063 if (DEBUG_FLAGS & DEBUG_POLL) printf("P"); 4064 4065 for (i=xp->timeout; i && !(xp->flags & ITSDONE);i--) { 4066 if ((DEBUG_FLAGS & DEBUG_POLL) && (cp->host_status)) 4067 printf ("%c", (cp->host_status & 0xf) + '0'); 4068 DELAY (1000); 4069 ncr_exception (np); 4070 }; 4071 4072 /* 4073 ** Abort if command not done. 4074 */ 4075 if (!(xp->flags & ITSDONE)) { 4076 printf ("%s: aborting job ...\n", ncr_name (np)); 4077 OUTB (nc_istat, CABRT); 4078 DELAY (100000); 4079 OUTB (nc_istat, SIGP); 4080 ncr_exception (np); 4081 }; 4082 4083 if (!(xp->flags & ITSDONE)) { 4084 printf ("%s: abortion failed at %x.\n", 4085 ncr_name (np), (unsigned) INL(nc_dsp)); 4086 ncr_init (np, "timeout", HS_TIMEOUT); 4087 }; 4088 4089 if (!(xp->flags & ITSDONE)) { 4090 cp-> host_status = HS_SEL_TIMEOUT; 4091 ncr_complete (np, cp); 4092 }; 4093 4094 if (DEBUG_FLAGS & DEBUG_RESULT) { 4095 printf ("%s: result: %x %x.\n", 4096 ncr_name (np), cp->host_status, cp->scsi_status); 4097 }; 4098#ifdef __NetBSD__ 4099 if (!(flags & SCSI_POLL)) 4100#else /* !__NetBSD__ */ 4101 if (!(flags & SCSI_NOMASK)) 4102#endif /* __NetBSD__ */ 4103 return (SUCCESSFULLY_QUEUED); 4104 switch (xp->error) { 4105 case 0 : return (COMPLETE); 4106 case XS_BUSY: return (TRY_AGAIN_LATER); 4107 }; 4108 return (COMPLETE); 4109} 4110 4111/*========================================================== 4112** 4113** 4114** Complete execution of a SCSI command. 4115** Signal completion to the generic SCSI driver. 4116** 4117** 4118**========================================================== 4119*/ 4120 4121void ncr_complete (ncb_p np, ccb_p cp) 4122{ 4123 struct scsi_xfer * xp; 4124 tcb_p tp; 4125 lcb_p lp; 4126 4127 /* 4128 ** Sanity check 4129 */ 4130 4131 if (!cp || (cp->magic!=CCB_MAGIC) || !cp->xfer) return; 4132 cp->magic = 1; 4133 cp->tlimit= 0; 4134 4135 /* 4136 ** No Reselect anymore. 4137 */ 4138 cp->jump_ccb.l_cmd = (SCR_JUMP); 4139 4140 /* 4141 ** No starting. 4142 */ 4143 cp->phys.header.launch.l_paddr= NCB_SCRIPT_PHYS (np, idle); 4144 4145 /* 4146 ** timestamp 4147 */ 4148 ncb_profile (np, cp); 4149 4150 if (DEBUG_FLAGS & DEBUG_TINY) 4151 printf ("CCB=%x STAT=%x/%x\n", (unsigned)cp & 0xfff, 4152 cp->host_status,cp->scsi_status); 4153 4154 xp = cp->xfer; 4155 cp->xfer = NULL; 4156 tp = &np->target[xp->sc_link->target]; 4157 lp = tp->lp[xp->sc_link->lun]; 4158 4159 /* 4160 ** Check for parity errors. 4161 */ 4162 4163 if (cp->parity_status) { 4164 PRINT_ADDR(xp); 4165 printf ("%d parity error(s), fallback.\n", cp->parity_status); 4166 /* 4167 ** fallback to asynch transfer. 4168 */ 4169 tp->usrsync=255; 4170 tp->period = 0; 4171 }; 4172 4173 /* 4174 ** Check for extended errors. 4175 */ 4176 4177 if (cp->xerr_status != XE_OK) { 4178 PRINT_ADDR(xp); 4179 switch (cp->xerr_status) { 4180 case XE_EXTRA_DATA: 4181 printf ("extraneous data discarded.\n"); 4182 break; 4183 case XE_BAD_PHASE: 4184 printf ("illegal scsi phase (4/5).\n"); 4185 break; 4186 default: 4187 printf ("extended error %d.\n", cp->xerr_status); 4188 break; 4189 }; 4190 if (cp->host_status==HS_COMPLETE) 4191 cp->host_status = HS_FAIL; 4192 }; 4193 4194 /* 4195 ** Check the status. 4196 */ 4197#ifdef __NetBSD__ 4198 if (xp->error != XS_NOERROR) { 4199 4200 /* 4201 ** Don't override the error value. 4202 */ 4203 } else 4204#endif /* __NetBSD__ */ 4205 if ( (cp->host_status == HS_COMPLETE) 4206 && (cp->scsi_status == S_GOOD)) { 4207 4208 /* 4209 ** All went well. 4210 */ 4211 4212 xp->resid = 0; 4213 4214 /* 4215 ** if (cp->phys.header.lastp != cp->phys.header.goalp)... 4216 ** 4217 ** @RESID@ 4218 ** Could dig out the correct value for resid, 4219 ** but it would be quite complicated. 4220 ** 4221 ** The ah1542.c driver sets it to 0 too ... 4222 */ 4223 4224 /* 4225 ** Try to assign a ccb to this nexus 4226 */ 4227 ncr_alloc_ccb (np, xp->sc_link->target, xp->sc_link->lun); 4228 4229 /* 4230 ** On inquire cmd (0x12) save some data. 4231 */ 4232 if (xp->cmd->opcode == 0x12 && xp->sc_link->lun == 0) { 4233 bcopy ( xp->data, 4234 &tp->inqdata, 4235 sizeof (tp->inqdata)); 4236 /* 4237 ** prepare negotiation of synch and wide. 4238 */ 4239 ncr_negotiate (np, tp); 4240 4241 /* 4242 ** force quirks update before next command start 4243 */ 4244 tp->quirks |= QUIRK_UPDATE; 4245 }; 4246 4247 /* 4248 ** Announce changes to the generic driver 4249 */ 4250 if (lp) { 4251 if (lp->reqlink != lp->actlink) 4252 ncr_opennings (np, lp, xp); 4253 }; 4254 4255 tp->bytes += xp->datalen; 4256 tp->transfers ++; 4257#ifndef __NetBSD__ 4258 } else if (xp->flags & SCSI_ERR_OK) { 4259 4260 /* 4261 ** Not correct, but errors expected. 4262 */ 4263 xp->resid = 0; 4264#endif /* !__NetBSD__ */ 4265 } else if ((cp->host_status == HS_COMPLETE) 4266 && (cp->scsi_status == (S_SENSE|S_GOOD))) { 4267 4268 /* 4269 ** Check condition code 4270 */ 4271 xp->error = XS_SENSE; 4272 4273 if (DEBUG_FLAGS & (DEBUG_RESULT|DEBUG_TINY)) { 4274 u_char * p = (u_char*) & xp->sense; 4275 int i; 4276 printf ("\n%s: sense data:", ncr_name (np)); 4277 for (i=0; i<14; i++) printf (" %x", *p++); 4278 printf (".\n"); 4279 }; 4280 4281 } else if ((cp->host_status == HS_COMPLETE) 4282 && (cp->scsi_status == S_BUSY)) { 4283 4284 /* 4285 ** Target is busy. 4286 */ 4287 xp->error = XS_BUSY; 4288 4289 } else if (cp->host_status == HS_SEL_TIMEOUT) { 4290 4291 /* 4292 ** Device failed selection 4293 */ 4294 xp->error = XS_SELTIMEOUT; 4295 } else if(cp->host_status == HS_TIMEOUT) { 4296 4297 /* 4298 ** No response 4299 */ 4300 xp->error = XS_TIMEOUT; 4301 4302 } else { 4303 4304 /* 4305 ** Other protocol messes 4306 */ 4307 PRINT_ADDR(xp); 4308 printf ("COMMAND FAILED (%x %x) @%x.\n", 4309 cp->host_status, cp->scsi_status, (unsigned)cp); 4310 4311 xp->error = XS_TIMEOUT; 4312 } 4313 4314 xp->flags |= ITSDONE; 4315 4316 /* 4317 ** trace output 4318 */ 4319 4320 if (tp->usrflag & UF_TRACE) { 4321 u_char * p; 4322 int i; 4323 PRINT_ADDR(xp); 4324 printf (" CMD:"); 4325 p = (u_char*) &xp->cmd->opcode; 4326 for (i=0; i<xp->cmdlen; i++) printf (" %x", *p++); 4327 4328 if (cp->host_status==HS_COMPLETE) { 4329 switch (cp->scsi_status) { 4330 case S_GOOD: 4331 printf (" GOOD"); 4332 break; 4333 case S_CHECK_COND: 4334 printf (" SENSE:"); 4335 p = (u_char*) &xp->sense; 4336 for (i=0; i<xp->req_sense_length; i++) 4337 printf (" %x", *p++); 4338 break; 4339 default: 4340 printf (" STAT: %x\n", cp->scsi_status); 4341 break; 4342 }; 4343 } else printf (" HOSTERROR: %x", cp->host_status); 4344 printf ("\n"); 4345 }; 4346 4347 /* 4348 ** Free this ccb 4349 */ 4350 ncr_free_ccb (np, cp, xp->flags); 4351 4352 /* 4353 ** signal completion to generic driver. 4354 */ 4355 scsi_done (xp); 4356} 4357 4358/*========================================================== 4359** 4360** 4361** Signal all (or one) control block done. 4362** 4363** 4364**========================================================== 4365*/ 4366 4367void ncr_wakeup (ncb_p np, u_long code) 4368{ 4369 /* 4370 ** Starting at the default ccb and following 4371 ** the links, complete all jobs with a 4372 ** host_status greater than "disconnect". 4373 ** 4374 ** If the "code" parameter is not zero, 4375 ** complete all jobs that are not IDLE. 4376 */ 4377 4378 ccb_p cp = &np->ccb; 4379 while (cp) { 4380 switch (cp->host_status) { 4381 4382 case HS_IDLE: 4383 break; 4384 4385 case HS_DISCONNECT: 4386 if(DEBUG_FLAGS & DEBUG_TINY) printf ("D"); 4387 /* fall through */ 4388 4389 case HS_BUSY: 4390 case HS_NEGOTIATE: 4391 if (!code) break; 4392 cp->host_status = code; 4393 4394 /* fall through */ 4395 4396 default: 4397 ncr_complete (np, cp); 4398 break; 4399 }; 4400 cp = cp -> link_ccb; 4401 }; 4402} 4403 4404/*========================================================== 4405** 4406** 4407** Start NCR chip. 4408** 4409** 4410**========================================================== 4411*/ 4412 4413void ncr_init (ncb_p np, char * msg, u_long code) 4414{ 4415 int i; 4416 u_long usrsync; 4417 u_char usrwide; 4418 u_char burstlen; 4419 4420 /* 4421 ** Reset chip. 4422 */ 4423 4424 OUTB (nc_istat, SRST); 4425 DELAY (1000); 4426 4427 /* 4428 ** Message. 4429 */ 4430 4431 if (msg) printf ("%s: restart (%s).\n", ncr_name (np), msg); 4432 4433 /* 4434 ** Clear Start Queue 4435 */ 4436 4437 for (i=0;i<MAX_START;i++) 4438 np -> squeue [i] = NCB_SCRIPT_PHYS (np, idle); 4439 4440 /* 4441 ** Start at first entry. 4442 */ 4443 4444 np->squeueput = 0; 4445 np->script->startpos[0] = NCB_SCRIPT_PHYS (np, tryloop); 4446 np->script->start0 [0] = SCR_INT ^ IFFALSE (0); 4447 4448 /* 4449 ** Wakeup all pending jobs. 4450 */ 4451 4452 ncr_wakeup (np, code); 4453 4454 /* 4455 ** Init chip. 4456 */ 4457 4458 burstlen = 0xc0; /* XXX 53c875 needs code change to */ 4459 /* be able to use larger bursts */ 4460 4461 OUTB (nc_istat, 0x00 ); /* Remove Reset, abort ... */ 4462 OUTB (nc_scntl0, 0xca ); /* full arb., ena parity, par->ATN */ 4463 OUTB (nc_scntl1, 0x00 ); /* odd parity, and remove CRST!! */ 4464 OUTB (nc_scntl3, np->rv_scntl3);/* timing prescaler */ 4465 OUTB (nc_scid , RRE|np->myaddr);/* host adapter SCSI address */ 4466 OUTW (nc_respid, 1ul<<np->myaddr);/* id to respond to */ 4467 OUTB (nc_istat , SIGP ); /* Signal Process */ 4468 OUTB (nc_dmode , np->rv_dmode); /* XXX modify burstlen ??? */ 4469 OUTB (nc_dcntl , np->rv_dcntl); 4470 OUTB (nc_ctest3, np->rv_ctest3); 4471 OUTB (nc_ctest5, np->rv_ctest5); 4472 OUTB (nc_ctest4, MPEE ); /* enable master parity checking */ 4473 OUTB (nc_stest2, EXT ); /* Extended Sreq/Sack filtering */ 4474 OUTB (nc_stest3, TE ); /* TolerANT enable */ 4475 OUTB (nc_stime0, 0x0b ); /* HTH = disabled, STO = 0.1 sec. */ 4476 4477 if (bootverbose) { 4478 printf ("\tBIOS values: dmode: %02x, dcntl: %02x, ctest3: %02x\n", 4479 np->rv_dmode, np->rv_dcntl, np->rv_ctest3); 4480 printf ("\tdmode: %02x/%02x, dcntl: %02x/%02x, ctest3: %02x/%02x\n", 4481 burstlen | ERL | ERMP | BOF, INB (nc_dmode), 4482 CLSE | PFEN | NOCOM, INB (nc_dcntl), 4483 WRIE, INB (nc_ctest3)); 4484 } 4485 4486 /* 4487 ** Reinitialize usrsync. 4488 ** Have to renegotiate synch mode. 4489 */ 4490 4491 usrsync = 255; 4492 if (SCSI_NCR_MAX_SYNC) { 4493 u_long period; 4494 period =1000000/SCSI_NCR_MAX_SYNC; /* ns = 10e6 / kHz */ 4495 if (period <= 11 * np->ns_sync) { 4496 if (period < 4 * np->ns_sync) 4497 usrsync = np->ns_sync; 4498 else 4499 usrsync = period / 4; 4500 }; 4501 }; 4502 4503 /* 4504 ** Reinitialize usrwide. 4505 ** Have to renegotiate wide mode. 4506 */ 4507 4508 usrwide = (SCSI_NCR_MAX_WIDE); 4509 if (usrwide > np->maxwide) usrwide=np->maxwide; 4510 4511 /* 4512 ** Disable disconnects. 4513 */ 4514 4515 np->disc = 0; 4516 4517 /* 4518 ** Fill in target structure. 4519 */ 4520 4521 for (i=0;i<MAX_TARGET;i++) { 4522 tcb_p tp = &np->target[i]; 4523 4524 tp->sval = 0; 4525 tp->wval = np->rv_scntl3; 4526 4527 tp->usrsync = usrsync; 4528 tp->usrwide = usrwide; 4529 4530 ncr_negotiate (np, tp); 4531 } 4532 4533 /* 4534 ** enable ints 4535 */ 4536 4537 OUTW (nc_sien , STO|HTH|MA|SGE|UDC|RST); 4538 OUTB (nc_dien , MDPE|BF|ABRT|SSI|SIR|IID); 4539 4540 /* 4541 ** Start script processor. 4542 */ 4543 4544 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, start)); 4545} 4546 4547/*========================================================== 4548** 4549** Prepare the negotiation values for wide and 4550** synchronous transfers. 4551** 4552**========================================================== 4553*/ 4554 4555static void ncr_negotiate (struct ncb* np, struct tcb* tp) 4556{ 4557 /* 4558 ** minsync unit is 4ns ! 4559 */ 4560 4561 u_long minsync = tp->usrsync; 4562 4563 /* 4564 ** if not scsi 2 4565 ** don't believe FAST! 4566 */ 4567 4568 if ((minsync < 50) && (tp->inqdata[2] & 0x0f) < 2) 4569 minsync=50; 4570 4571 /* 4572 ** our limit .. 4573 */ 4574 4575 if (minsync < np->ns_sync) 4576 minsync = np->ns_sync; 4577 4578 /* 4579 ** divider limit 4580 */ 4581 4582 if (minsync > (np->ns_sync * 11) / 4) 4583 minsync = 255; 4584 4585 tp->minsync = minsync; 4586 tp->maxoffs = (minsync<255 ? np->maxoffs : 0); 4587 4588 /* 4589 ** period=0: has to negotiate sync transfer 4590 */ 4591 4592 tp->period=0; 4593 4594 /* 4595 ** widedone=0: has to negotiate wide transfer 4596 */ 4597 tp->widedone=0; 4598} 4599 4600/*========================================================== 4601** 4602** Switch sync mode for current job and it's target 4603** 4604**========================================================== 4605*/ 4606 4607static void ncr_setsync (ncb_p np, ccb_p cp, u_char sxfer) 4608{ 4609 struct scsi_xfer *xp; 4610 tcb_p tp; 4611 u_char target = INB (nc_ctest0) & 0x0f; 4612 4613 assert (cp); 4614 if (!cp) return; 4615 4616 xp = cp->xfer; 4617 assert (xp); 4618 if (!xp) return; 4619 assert (target == (xp->sc_link->target & 0x0f)); 4620 4621 tp = &np->target[target]; 4622 tp->period= sxfer&0x1f ? ((sxfer>>5)+4) * np->ns_sync : 0xffff; 4623 4624 if (tp->sval == sxfer) return; 4625 tp->sval = sxfer; 4626 4627 /* 4628 ** Bells and whistles ;-) 4629 */ 4630 PRINT_ADDR(xp); 4631 if (sxfer & 0x1f) { 4632 unsigned f10 = 10000 << (tp->widedone ? tp->widedone -1 : 0); 4633 unsigned mb10 = (f10 + tp->period/2) / tp->period; 4634 /* 4635 ** Disable extended Sreq/Sack filtering 4636 */ 4637 if (tp->period <= 200) OUTB (nc_stest2, 0); 4638 printf ("%d.%d MB/s (%d ns, offset %d)\n", 4639 mb10 / 10, mb10 % 10, tp->period, sxfer & 0x1f); 4640 } else printf ("asynchronous.\n"); 4641 4642 /* 4643 ** set actual value and sync_status 4644 */ 4645 OUTB (nc_sxfer, sxfer); 4646 np->sync_st = sxfer; 4647 4648 /* 4649 ** patch ALL ccbs of this target. 4650 */ 4651 for (cp = &np->ccb; cp; cp = cp->link_ccb) { 4652 if (!cp->xfer) continue; 4653 if (cp->xfer->sc_link->target != target) continue; 4654 cp->sync_status = sxfer; 4655 }; 4656} 4657 4658/*========================================================== 4659** 4660** Switch wide mode for current job and it's target 4661** 4662**========================================================== 4663*/ 4664 4665static void ncr_setwide (ncb_p np, ccb_p cp, u_char wide) 4666{ 4667 struct scsi_xfer *xp; 4668 u_short target = INB (nc_ctest0) & 0x0f; 4669 tcb_p tp; 4670 u_char scntl3 = np->rv_scntl3 | (wide ? EWS : 0); 4671 4672 assert (cp); 4673 if (!cp) return; 4674 4675 xp = cp->xfer; 4676 assert (xp); 4677 if (!xp) return; 4678 assert (target == (xp->sc_link->target & 0x0f)); 4679 4680 tp = &np->target[target]; 4681 tp->widedone = wide+1; 4682 if (tp->wval == scntl3) return; 4683 tp->wval = scntl3; 4684 4685 /* 4686 ** Bells and whistles ;-) 4687 */ 4688 PRINT_ADDR(xp); 4689 if (scntl3 & EWS) 4690 printf ("WIDE SCSI (16 bit) enabled"); 4691 else 4692 printf ("WIDE SCSI disabled"); 4693 4694 /* 4695 ** set actual value and sync_status 4696 */ 4697 OUTB (nc_scntl3, scntl3); 4698 np->wide_st = scntl3; 4699 4700 /* 4701 ** patch ALL ccbs of this target. 4702 */ 4703 for (cp = &np->ccb; cp; cp = cp->link_ccb) { 4704 if (!cp->xfer) continue; 4705 if (cp->xfer->sc_link->target != target) continue; 4706 cp->wide_status = scntl3; 4707 }; 4708} 4709 4710/*========================================================== 4711** 4712** Switch tagged mode for a target. 4713** 4714**========================================================== 4715*/ 4716 4717static void ncr_setmaxtags (tcb_p tp, u_long usrtags) 4718{ 4719 int l; 4720 for (l=0; l<MAX_LUN; l++) { 4721 lcb_p lp; 4722 if (!tp) break; 4723 lp=tp->lp[l]; 4724 if (!lp) continue; 4725 ncr_settags (tp, lp, usrtags); 4726 }; 4727} 4728 4729static void ncr_settags (tcb_p tp, lcb_p lp, u_long usrtags) 4730{ 4731 u_char reqtags, tmp; 4732 4733 if ((!tp) || (!lp)) return; 4734 4735 /* 4736 ** only devices capable of tagges commands 4737 ** only disk devices 4738 ** only if enabled by user .. 4739 */ 4740 if ((tp->inqdata[0] & 0x1f) != 0x00 4741 || (tp->inqdata[7] & INQ7_QUEUE) == 0 4742 || (tp->quirks & QUIRK_NOTAGS) != 0) { 4743 usrtags=0; 4744 } 4745 if (usrtags) { 4746 reqtags = usrtags; 4747 if (lp->actlink <= 1) 4748 lp->usetags=reqtags; 4749 } else { 4750 reqtags = 1; 4751 if (lp->actlink <= 1) 4752 lp->usetags=0; 4753 }; 4754 4755 /* 4756 ** don't announce more than available. 4757 */ 4758 tmp = lp->actccbs; 4759 if (tmp > reqtags) tmp = reqtags; 4760 lp->reqlink = tmp; 4761 4762 /* 4763 ** don't discard if announced. 4764 */ 4765 tmp = lp->actlink; 4766 if (tmp < reqtags) tmp = reqtags; 4767 lp->reqccbs = tmp; 4768 if (lp->reqlink < lp->reqccbs) 4769 lp->reqlink = lp->reqccbs; 4770} 4771 4772/*---------------------------------------------------- 4773** 4774** handle user commands 4775** 4776**---------------------------------------------------- 4777*/ 4778 4779static void ncr_usercmd (ncb_p np) 4780{ 4781 u_char t; 4782 tcb_p tp; 4783 4784 switch (np->user.cmd) { 4785 4786 case 0: return; 4787 4788 case UC_SETSYNC: 4789 for (t=0; t<MAX_TARGET; t++) { 4790 if (!((np->user.target>>t)&1)) continue; 4791 tp = &np->target[t]; 4792 tp->usrsync = np->user.data; 4793 ncr_negotiate (np, tp); 4794 }; 4795 break; 4796 4797 case UC_SETTAGS: 4798 if (np->user.data > MAX_TAGS) 4799 break; 4800 for (t=0; t<MAX_TARGET; t++) { 4801 if (!((np->user.target>>t)&1)) continue; 4802 tp = &np->target[t]; 4803 tp->usrtags = np->user.data; 4804 ncr_setmaxtags (tp, tp->usrtags); 4805 }; 4806 break; 4807 4808 case UC_SETDEBUG: 4809 ncr_debug = np->user.data; 4810 break; 4811 4812 case UC_SETORDER: 4813 np->order = np->user.data; 4814 break; 4815 4816 case UC_SETWIDE: 4817 for (t=0; t<MAX_TARGET; t++) { 4818 u_long size; 4819 if (!((np->user.target>>t)&1)) continue; 4820 tp = &np->target[t]; 4821 size = np->user.data; 4822 if (size > np->maxwide) size=np->maxwide; 4823 tp->usrwide = size; 4824 ncr_negotiate (np, tp); 4825 }; 4826 break; 4827 4828 case UC_SETFLAG: 4829 for (t=0; t<MAX_TARGET; t++) { 4830 if (!((np->user.target>>t)&1)) continue; 4831 tp = &np->target[t]; 4832 tp->usrflag = np->user.data; 4833 }; 4834 break; 4835 } 4836 np->user.cmd=0; 4837} 4838 4839 4840 4841 4842/*========================================================== 4843** 4844** 4845** ncr timeout handler. 4846** 4847** 4848**========================================================== 4849** 4850** Misused to keep the driver running when 4851** interrupts are not configured correctly. 4852** 4853**---------------------------------------------------------- 4854*/ 4855 4856static void ncr_timeout (void *arg) 4857{ 4858 ncb_p np = arg; 4859 u_long thistime = time.tv_sec; 4860 u_long step = np->ticks; 4861 u_long count = 0; 4862 long signed t; 4863 ccb_p cp; 4864 4865 if (np->lasttime != thistime) { 4866 /* 4867 ** block ncr interrupts 4868 */ 4869 int oldspl = splbio(); 4870 np->lasttime = thistime; 4871 4872 ncr_usercmd (np); 4873 4874 /*---------------------------------------------------- 4875 ** 4876 ** handle ncr chip timeouts 4877 ** 4878 ** Assumption: 4879 ** We have a chance to arbitrate for the 4880 ** SCSI bus at least every 10 seconds. 4881 ** 4882 **---------------------------------------------------- 4883 */ 4884 4885 t = thistime - np->heartbeat; 4886 4887 if (t<2) np->latetime=0; else np->latetime++; 4888 4889 if (np->latetime>2) { 4890 /* 4891 ** If there are no requests, the script 4892 ** processor will sleep on SEL_WAIT_RESEL. 4893 ** But we have to check whether it died. 4894 ** Let's try to wake it up. 4895 */ 4896 OUTB (nc_istat, SIGP); 4897 }; 4898 4899 /*---------------------------------------------------- 4900 ** 4901 ** handle ccb timeouts 4902 ** 4903 **---------------------------------------------------- 4904 */ 4905 4906 for (cp=&np->ccb; cp; cp=cp->link_ccb) { 4907 /* 4908 ** look for timed out ccbs. 4909 */ 4910 if (!cp->host_status) continue; 4911 count++; 4912 if (cp->tlimit > thistime) continue; 4913 4914 /* 4915 ** Disable reselect. 4916 ** Remove it from startqueue. 4917 */ 4918 cp->jump_ccb.l_cmd = (SCR_JUMP); 4919 if (cp->phys.header.launch.l_paddr == 4920 NCB_SCRIPT_PHYS (np, select)) { 4921 printf ("%s: timeout ccb=%x (skip)\n", 4922 ncr_name (np), (unsigned)cp); 4923 cp->phys.header.launch.l_paddr 4924 = NCB_SCRIPT_PHYS (np, skip); 4925 }; 4926 4927 switch (cp->host_status) { 4928 4929 case HS_BUSY: 4930 case HS_NEGOTIATE: 4931 /* 4932 ** still in start queue ? 4933 */ 4934 if (cp->phys.header.launch.l_paddr == 4935 NCB_SCRIPT_PHYS (np, skip)) 4936 continue; 4937 4938 /* fall through */ 4939 case HS_DISCONNECT: 4940 cp->host_status=HS_TIMEOUT; 4941 }; 4942 cp->tag = 0; 4943 4944 /* 4945 ** wakeup this ccb. 4946 */ 4947 ncr_complete (np, cp); 4948 }; 4949 splx (oldspl); 4950 } 4951 4952 timeout (ncr_timeout, (caddr_t) np, step ? step : 1); 4953 4954 if (INB(nc_istat) & (INTF|SIP|DIP)) { 4955 4956 /* 4957 ** Process pending interrupts. 4958 */ 4959 4960 int oldspl = splbio (); 4961 if (DEBUG_FLAGS & DEBUG_TINY) printf ("{"); 4962 ncr_exception (np); 4963 if (DEBUG_FLAGS & DEBUG_TINY) printf ("}"); 4964 splx (oldspl); 4965 }; 4966} 4967 4968/*========================================================== 4969** 4970** 4971** ncr chip exception handler. 4972** 4973** 4974**========================================================== 4975*/ 4976 4977void ncr_exception (ncb_p np) 4978{ 4979 u_char istat, dstat; 4980 u_short sist; 4981 u_long dsp, dsa; 4982 int i, script_ofs; 4983 4984 /* 4985 ** interrupt on the fly ? 4986 */ 4987 while ((istat = INB (nc_istat)) & INTF) { 4988 if (DEBUG_FLAGS & DEBUG_TINY) printf ("F "); 4989 OUTB (nc_istat, INTF); 4990 np->profile.num_fly++; 4991 ncr_wakeup (np, 0); 4992 }; 4993 if (!(istat & (SIP|DIP))) { 4994 return; 4995 } 4996 4997 /* 4998 ** Steinbach's Guideline for Systems Programming: 4999 ** Never test for an error condition you don't know how to handle. 5000 */ 5001 5002 sist = (istat & SIP) ? INW (nc_sist) : 0; 5003 dstat = (istat & DIP) ? INB (nc_dstat) : 0; 5004 np->profile.num_int++; 5005 5006 if (DEBUG_FLAGS & DEBUG_TINY) 5007 printf ("<%d|%x:%x|%x:%x>", 5008 INB(nc_scr0), 5009 dstat,sist, 5010 (unsigned)INL(nc_dsp), 5011 (unsigned)INL(nc_dbc)); 5012 if ((dstat==DFE) && (sist==PAR)) return; 5013 5014/*========================================================== 5015** 5016** First the normal cases. 5017** 5018**========================================================== 5019*/ 5020 /*------------------------------------------- 5021 ** SCSI reset 5022 **------------------------------------------- 5023 */ 5024 5025 if (sist & RST) { 5026 ncr_init (np, bootverbose ? "scsi reset" : NULL, HS_RESET); 5027 return; 5028 }; 5029 5030 /*------------------------------------------- 5031 ** selection timeout 5032 ** 5033 ** IID excluded from dstat mask! 5034 ** (chip bug) 5035 **------------------------------------------- 5036 */ 5037 5038 if ((sist & STO) && 5039 !(sist & (GEN|HTH|MA|SGE|UDC|RST|PAR)) && 5040 !(dstat & (MDPE|BF|ABRT|SIR))) { 5041 ncr_int_sto (np); 5042 return; 5043 }; 5044 5045 /*------------------------------------------- 5046 ** Phase mismatch. 5047 **------------------------------------------- 5048 */ 5049 5050 if ((sist & MA) && 5051 !(sist & (STO|GEN|HTH|SGE|UDC|RST|PAR)) && 5052 !(dstat & (MDPE|BF|ABRT|SIR|IID))) { 5053 ncr_int_ma (np, dstat); 5054 return; 5055 }; 5056 5057 /*---------------------------------------- 5058 ** move command with length 0 5059 **---------------------------------------- 5060 */ 5061 5062 if ((dstat & IID) && 5063 !(sist & (STO|GEN|HTH|MA|SGE|UDC|RST|PAR)) && 5064 !(dstat & (MDPE|BF|ABRT|SIR)) && 5065 ((INL(nc_dbc) & 0xf8000000) == SCR_MOVE_TBL)) { 5066 /* 5067 ** Target wants more data than available. 5068 ** The "no_data" script will do it. 5069 */ 5070 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, no_data)); 5071 return; 5072 }; 5073 5074 /*------------------------------------------- 5075 ** Programmed interrupt 5076 **------------------------------------------- 5077 */ 5078 5079 if ((dstat & SIR) && 5080 !(sist & (STO|GEN|HTH|MA|SGE|UDC|RST|PAR)) && 5081 !(dstat & (MDPE|BF|ABRT|IID)) && 5082 (INB(nc_dsps) <= SIR_MAX)) { 5083 ncr_int_sir (np); 5084 return; 5085 }; 5086 5087 /*======================================== 5088 ** do the register dump 5089 **======================================== 5090 */ 5091 5092 if (time.tv_sec - np->regtime.tv_sec>10) { 5093 int i; 5094 gettime(&np->regtime); 5095 for (i=0; i<sizeof(np->regdump); i++) 5096 ((char*)&np->regdump)[i] = ((volatile char*)np->reg)[i]; 5097 np->regdump.nc_dstat = dstat; 5098 np->regdump.nc_sist = sist; 5099 }; 5100 5101 /*========================================= 5102 ** log message for real hard errors 5103 **========================================= 5104 5105 "ncr0 targ 0?: ERROR (ds:si) (so-si-sd) (sxfer/scntl3) @ (dsp:dbc)." 5106 " reg: r0 r1 r2 r3 r4 r5 r6 ..... rf." 5107 5108 exception register: 5109 ds: dstat 5110 si: sist 5111 5112 SCSI bus lines: 5113 so: control lines as driver by NCR. 5114 si: control lines as seen by NCR. 5115 sd: scsi data lines as seen by NCR. 5116 5117 wide/fastmode: 5118 sxfer: (see the manual) 5119 scntl3: (see the manual) 5120 5121 current script command: 5122 dsp: script adress (relative to start of script). 5123 dbc: first word of script command. 5124 5125 First 16 register of the chip: 5126 r0..rf 5127 5128 ============================================= 5129 */ 5130 5131 dsp = (unsigned) INL (nc_dsp); 5132 dsa = (unsigned) INL (nc_dsa); 5133 5134 script_ofs = dsp - np->p_script; 5135 5136 printf ("%s:%d: ERROR (%x:%x) (%x-%x-%x) (%x/%x) @ (%x:%08x).\n", 5137 ncr_name (np), INB (nc_ctest0)&0x0f, dstat, sist, 5138 INB (nc_socl), INB (nc_sbcl), INB (nc_sbdl), 5139 INB (nc_sxfer),INB (nc_scntl3), script_ofs, 5140 (unsigned) INL (nc_dbc)); 5141 5142 if (((script_ofs & 3) == 0) && 5143 (unsigned)script_ofs < sizeof(struct script)) { 5144 printf ("\tscript cmd = %08x\n", 5145 *(ncrcmd *)((char*)np->script +script_ofs)); 5146 } 5147 5148 printf ("\treg:\t"); 5149 for (i=0; i<16;i++) 5150 printf (" %02x", ((volatile u_char*)np->reg)[i]); 5151 printf (".\n"); 5152 5153 /*---------------------------------------- 5154 ** clean up the dma fifo 5155 **---------------------------------------- 5156 */ 5157 5158 if ( (INB(nc_sstat0) & (ILF|ORF|OLF) ) || 5159 (INB(nc_sstat1) & (FF3210) ) || 5160 (INB(nc_sstat2) & (ILF1|ORF1|OLF1)) || /* wide .. */ 5161 !(dstat & DFE)) { 5162 printf ("%s: have to clear fifos.\n", ncr_name (np)); 5163 OUTB (nc_stest3, TE|CSF); /* clear scsi fifo */ 5164 OUTB (nc_ctest3, np->rv_ctest3 | CLF); 5165 /* clear dma fifo */ 5166 } 5167 5168 /*---------------------------------------- 5169 ** handshake timeout 5170 **---------------------------------------- 5171 */ 5172 5173 if (sist & HTH) { 5174 printf ("%s: handshake timeout\n", ncr_name(np)); 5175 OUTB (nc_scntl1, CRST); 5176 DELAY (1000); 5177 OUTB (nc_scntl1, 0x00); 5178 OUTB (nc_scr0, HS_FAIL); 5179 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, cleanup)); 5180 return; 5181 } 5182 5183 /*---------------------------------------- 5184 ** unexpected disconnect 5185 **---------------------------------------- 5186 */ 5187 5188 if ((sist & UDC) && 5189 !(sist & (STO|GEN|HTH|MA|SGE|RST|PAR)) && 5190 !(dstat & (MDPE|BF|ABRT|SIR|IID))) { 5191 OUTB (nc_scr0, HS_UNEXPECTED); 5192 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, cleanup)); 5193 return; 5194 }; 5195 5196 /*---------------------------------------- 5197 ** cannot disconnect 5198 **---------------------------------------- 5199 */ 5200 5201 if ((dstat & IID) && 5202 !(sist & (STO|GEN|HTH|MA|SGE|UDC|RST|PAR)) && 5203 !(dstat & (MDPE|BF|ABRT|SIR)) && 5204 ((INL(nc_dbc) & 0xf8000000) == SCR_WAIT_DISC)) { 5205 /* 5206 ** Unexpected data cycle while waiting for disconnect. 5207 */ 5208 if (INB(nc_sstat2) & LDSC) { 5209 /* 5210 ** It's an early reconnect. 5211 ** Let's continue ... 5212 */ 5213 OUTB (nc_dcntl, np->rv_dcntl | STD); 5214 /* 5215 ** info message 5216 */ 5217 printf ("%s: INFO: LDSC while IID.\n", 5218 ncr_name (np)); 5219 return; 5220 }; 5221 printf ("%s: target %d doesn't release the bus.\n", 5222 ncr_name (np), INB (nc_ctest0)&0x0f); 5223 /* 5224 ** return without restarting the NCR. 5225 ** timeout will do the real work. 5226 */ 5227 return; 5228 }; 5229 5230 /*---------------------------------------- 5231 ** single step 5232 **---------------------------------------- 5233 */ 5234 5235 if ((dstat & SSI) && 5236 !(sist & (STO|GEN|HTH|MA|SGE|UDC|RST|PAR)) && 5237 !(dstat & (MDPE|BF|ABRT|SIR|IID))) { 5238 OUTB (nc_dcntl, np->rv_dcntl | STD); 5239 return; 5240 }; 5241 5242/* 5243** @RECOVER@ HTH, SGE, ABRT. 5244** 5245** We should try to recover from these interrupts. 5246** They may occur if there are problems with synch transfers, or 5247** if targets are switched on or off while the driver is running. 5248*/ 5249 5250 if (sist & SGE) { 5251 /* clear scsi offsets */ 5252 OUTB (nc_ctest3, np->rv_ctest3 | CLF); 5253 } 5254 5255 /* 5256 ** Freeze controller to be able to read the messages. 5257 */ 5258 5259 if (DEBUG_FLAGS & DEBUG_FREEZE) { 5260 int i; 5261 unsigned char val; 5262 for (i=0; i<0x60; i++) { 5263 switch (i%16) { 5264 5265 case 0: 5266 printf ("%s: reg[%d0]: ", 5267 ncr_name(np),i/16); 5268 break; 5269 case 4: 5270 case 8: 5271 case 12: 5272 printf (" "); 5273 break; 5274 }; 5275 val = ((unsigned char*) np->vaddr) [i]; 5276 printf (" %x%x", val/16, val%16); 5277 if (i%16==15) printf (".\n"); 5278 }; 5279 5280 untimeout (ncr_timeout, (caddr_t) np); 5281 5282 printf ("%s: halted!\n", ncr_name(np)); 5283 /* 5284 ** don't restart controller ... 5285 */ 5286 OUTB (nc_istat, SRST); 5287 return; 5288 }; 5289 5290#ifdef NCR_FREEZE 5291 /* 5292 ** Freeze system to be able to read the messages. 5293 */ 5294 printf ("ncr: fatal error: system halted - press reset to reboot ..."); 5295 (void) splhigh(); 5296 for (;;); 5297#endif 5298 5299 /* 5300 ** sorry, have to kill ALL jobs ... 5301 */ 5302 5303 ncr_init (np, "fatal error", HS_FAIL); 5304} 5305 5306/*========================================================== 5307** 5308** ncr chip exception handler for selection timeout 5309** 5310**========================================================== 5311** 5312** There seems to be a bug in the 53c810. 5313** Although a STO-Interrupt is pending, 5314** it continues executing script commands. 5315** But it will fail and interrupt (IID) on 5316** the next instruction where it's looking 5317** for a valid phase. 5318** 5319**---------------------------------------------------------- 5320*/ 5321 5322void ncr_int_sto (ncb_p np) 5323{ 5324 u_long dsa, scratcha, diff; 5325 ccb_p cp; 5326 if (DEBUG_FLAGS & DEBUG_TINY) printf ("T"); 5327 5328 /* 5329 ** look for ccb and set the status. 5330 */ 5331 5332 dsa = INL (nc_dsa); 5333 cp = &np->ccb; 5334 while (cp && (CCB_PHYS (cp, phys) != dsa)) 5335 cp = cp->link_ccb; 5336 5337 if (cp) { 5338 cp-> host_status = HS_SEL_TIMEOUT; 5339 ncr_complete (np, cp); 5340 }; 5341 5342 /* 5343 ** repair start queue 5344 */ 5345 5346 scratcha = INL (nc_scratcha); 5347 diff = scratcha - NCB_SCRIPT_PHYS (np, tryloop); 5348 5349/* assert ((diff <= MAX_START * 20) && !(diff % 20));*/ 5350 5351 if ((diff <= MAX_START * 20) && !(diff % 20)) { 5352 np->script->startpos[0] = scratcha; 5353 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, start)); 5354 return; 5355 }; 5356 ncr_init (np, "selection timeout", HS_FAIL); 5357} 5358 5359/*========================================================== 5360** 5361** 5362** ncr chip exception handler for phase errors. 5363** 5364** 5365**========================================================== 5366** 5367** We have to construct a new transfer descriptor, 5368** to transfer the rest of the current block. 5369** 5370**---------------------------------------------------------- 5371*/ 5372 5373static void ncr_int_ma (ncb_p np, u_char dstat) 5374{ 5375 u_long dbc; 5376 u_long rest; 5377 u_long dsa; 5378 u_long dsp; 5379 u_long nxtdsp; 5380 u_long *vdsp; 5381 u_long oadr, olen; 5382 u_long *tblp, *newcmd; 5383 u_char cmd, sbcl, delta, ss0, ss2; 5384 ccb_p cp; 5385 5386 dsp = INL (nc_dsp); 5387 dsa = INL (nc_dsa); 5388 dbc = INL (nc_dbc); 5389 ss0 = INB (nc_sstat0); 5390 ss2 = INB (nc_sstat2); 5391 sbcl= INB (nc_sbcl); 5392 5393 cmd = dbc >> 24; 5394 rest= dbc & 0xffffff; 5395 delta=(INB (nc_dfifo) - rest) & 0x7f; 5396 5397 /* 5398 ** The data in the dma fifo has not been transfered to 5399 ** the target -> add the amount to the rest 5400 ** and clear the data. 5401 ** Check the sstat2 register in case of wide transfer. 5402 */ 5403 5404 if (!(dstat & DFE)) rest += delta; 5405 if (ss0 & OLF) rest++; 5406 if (ss0 & ORF) rest++; 5407 if (INB(nc_scntl3) & EWS) { 5408 if (ss2 & OLF1) rest++; 5409 if (ss2 & ORF1) rest++; 5410 }; 5411 OUTB (nc_ctest3, np->rv_ctest3 | CLF); /* clear dma fifo */ 5412 OUTB (nc_stest3, TE|CSF); /* clear scsi fifo */ 5413 5414 /* 5415 ** locate matching cp 5416 */ 5417 dsa = INL (nc_dsa); 5418 cp = &np->ccb; 5419 while (cp && (CCB_PHYS (cp, phys) != dsa)) 5420 cp = cp->link_ccb; 5421 5422 if (!cp) { 5423 printf ("%s: SCSI phase error fixup: CCB already dequeued (0x%08lx)\n", 5424 ncr_name (np), (u_long) np->header.cp); 5425 return; 5426 } 5427 if (cp != np->header.cp) { 5428 printf ("%s: SCSI phase error fixup: CCB address mismatch (0x%08lx != 0x%08lx) np.ccb = 0x%08lx\n", 5429 ncr_name (np), (u_long) cp, (u_long) np->header.cp, &np->ccb); 5430/* return;*/ 5431 } 5432 5433 /* 5434 ** find the interrupted script command, 5435 ** and the address at which to continue. 5436 */ 5437 5438 if (dsp == vtophys (&cp->patch[2])) { 5439 vdsp = &cp->patch[0]; 5440 nxtdsp = vdsp[3]; 5441 } else if (dsp == vtophys (&cp->patch[6])) { 5442 vdsp = &cp->patch[4]; 5443 nxtdsp = vdsp[3]; 5444 } else { 5445 vdsp = (u_long*) ((char*)np->script - np->p_script + dsp -8); 5446 nxtdsp = dsp; 5447 }; 5448 5449 /* 5450 ** log the information 5451 */ 5452 if (DEBUG_FLAGS & (DEBUG_TINY|DEBUG_PHASE)) { 5453 printf ("P%x%x ",cmd&7, sbcl&7); 5454 printf ("RL=%d D=%d SS0=%x ", 5455 (unsigned) rest, (unsigned) delta, ss0); 5456 }; 5457 if (DEBUG_FLAGS & DEBUG_PHASE) { 5458 printf ("\nCP=%x CP2=%x DSP=%x NXT=%x VDSP=%x CMD=%x ", 5459 (unsigned)cp, (unsigned)np->header.cp, 5460 (unsigned)dsp, 5461 (unsigned)nxtdsp, (unsigned)vdsp, cmd); 5462 }; 5463 5464 /* 5465 ** get old startaddress and old length. 5466 */ 5467 5468 oadr = vdsp[1]; 5469 5470 if (cmd & 0x10) { /* Table indirect */ 5471 tblp = (u_long*) ((char*) &cp->phys + oadr); 5472 olen = tblp[0]; 5473 oadr = tblp[1]; 5474 } else { 5475 tblp = (u_long*) 0; 5476 olen = vdsp[0] & 0xffffff; 5477 }; 5478 5479 if (DEBUG_FLAGS & DEBUG_PHASE) { 5480 printf ("OCMD=%x\nTBLP=%x OLEN=%x OADR=%x\n", 5481 (unsigned) (vdsp[0] >> 24), 5482 (unsigned) tblp, 5483 (unsigned) olen, 5484 (unsigned) oadr); 5485 }; 5486 5487 /* 5488 ** if old phase not dataphase, leave here. 5489 */ 5490 5491 if (cmd != (vdsp[0] >> 24)) { 5492 PRINT_ADDR(cp->xfer); 5493 printf ("internal error: cmd=%02x != %02x=(vdsp[0] >> 24)\n", 5494 (unsigned)cmd, (unsigned)vdsp[0] >> 24); 5495 5496 return; 5497 } 5498 if (cmd & 0x06) { 5499 PRINT_ADDR(cp->xfer); 5500 printf ("phase change %x-%x %d@%08x resid=%d.\n", 5501 cmd&7, sbcl&7, (unsigned)olen, 5502 (unsigned)oadr, (unsigned)rest); 5503 5504 OUTB (nc_dcntl, np->rv_dcntl | STD); 5505 return; 5506 }; 5507 5508 /* 5509 ** choose the correct patch area. 5510 ** if savep points to one, choose the other. 5511 */ 5512 5513 newcmd = cp->patch; 5514 if (cp->phys.header.savep == vtophys (newcmd)) newcmd+=4; 5515 5516 /* 5517 ** fillin the commands 5518 */ 5519 5520 newcmd[0] = ((cmd & 0x0f) << 24) | rest; 5521 newcmd[1] = oadr + olen - rest; 5522 newcmd[2] = SCR_JUMP; 5523 newcmd[3] = nxtdsp; 5524 5525 if (DEBUG_FLAGS & DEBUG_PHASE) { 5526 PRINT_ADDR(cp->xfer); 5527 printf ("newcmd[%d] %x %x %x %x.\n", 5528 newcmd - cp->patch, 5529 (unsigned)newcmd[0], 5530 (unsigned)newcmd[1], 5531 (unsigned)newcmd[2], 5532 (unsigned)newcmd[3]); 5533 } 5534 /* 5535 ** fake the return address (to the patch). 5536 ** and restart script processor at dispatcher. 5537 */ 5538 np->profile.num_break++; 5539 OUTL (nc_temp, vtophys (newcmd)); 5540 if ((cmd & 7) == 0) 5541 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, dispatch)); 5542 else 5543 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, checkatn)); 5544} 5545 5546/*========================================================== 5547** 5548** 5549** ncr chip exception handler for programmed interrupts. 5550** 5551** 5552**========================================================== 5553*/ 5554 5555static int ncr_show_msg (u_char * msg) 5556{ 5557 u_char i; 5558 printf ("%x",*msg); 5559 if (*msg==M_EXTENDED) { 5560 for (i=1;i<8;i++) { 5561 if (i-1>msg[1]) break; 5562 printf ("-%x",msg[i]); 5563 }; 5564 return (i+1); 5565 } else if ((*msg & 0xf0) == 0x20) { 5566 printf ("-%x",msg[1]); 5567 return (2); 5568 }; 5569 return (1); 5570} 5571 5572void ncr_int_sir (ncb_p np) 5573{ 5574 u_char chg, ofs, per, fak, wide; 5575 u_char num = INB (nc_dsps); 5576 ccb_p cp=0; 5577 u_long dsa; 5578 u_char target = INB (nc_ctest0) & 0x0f; 5579 tcb_p tp = &np->target[target]; 5580 int i; 5581 if (DEBUG_FLAGS & DEBUG_TINY) printf ("I#%d", num); 5582 5583 switch (num) { 5584 case SIR_SENSE_RESTART: 5585 case SIR_STALL_RESTART: 5586 break; 5587 5588 default: 5589 /* 5590 ** lookup the ccb 5591 */ 5592 dsa = INL (nc_dsa); 5593 cp = &np->ccb; 5594 while (cp && (CCB_PHYS (cp, phys) != dsa)) 5595 cp = cp->link_ccb; 5596 5597 assert (cp); 5598 if (!cp) 5599 goto out; 5600 assert (cp == np->header.cp); 5601 if (cp != np->header.cp) 5602 goto out; 5603 } 5604 5605 switch (num) { 5606 5607/*-------------------------------------------------------------------- 5608** 5609** Processing of interrupted getcc selects 5610** 5611**-------------------------------------------------------------------- 5612*/ 5613 5614 case SIR_SENSE_RESTART: 5615 /*------------------------------------------ 5616 ** Script processor is idle. 5617 ** Look for interrupted "check cond" 5618 **------------------------------------------ 5619 */ 5620 5621 if (DEBUG_FLAGS & DEBUG_RESTART) 5622 printf ("%s: int#%d",ncr_name (np),num); 5623 cp = (ccb_p) 0; 5624 for (i=0; i<MAX_TARGET; i++) { 5625 if (DEBUG_FLAGS & DEBUG_RESTART) printf (" t%d", i); 5626 tp = &np->target[i]; 5627 if (DEBUG_FLAGS & DEBUG_RESTART) printf ("+"); 5628 cp = tp->hold_cp; 5629 if (!cp) continue; 5630 if (DEBUG_FLAGS & DEBUG_RESTART) printf ("+"); 5631 if ((cp->host_status==HS_BUSY) && 5632 (cp->scsi_status==S_CHECK_COND)) 5633 break; 5634 if (DEBUG_FLAGS & DEBUG_RESTART) printf ("- (remove)"); 5635 tp->hold_cp = cp = (ccb_p) 0; 5636 }; 5637 5638 if (cp) { 5639 if (DEBUG_FLAGS & DEBUG_RESTART) 5640 printf ("+ restart job ..\n"); 5641 OUTL (nc_dsa, CCB_PHYS (cp, phys)); 5642 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, getcc)); 5643 return; 5644 }; 5645 5646 /* 5647 ** no job, resume normal processing 5648 */ 5649 if (DEBUG_FLAGS & DEBUG_RESTART) printf (" -- remove trap\n"); 5650 np->script->start0[0] = SCR_INT ^ IFFALSE (0); 5651 break; 5652 5653 case SIR_SENSE_FAILED: 5654 /*------------------------------------------- 5655 ** While trying to select for 5656 ** getting the condition code, 5657 ** a target reselected us. 5658 **------------------------------------------- 5659 */ 5660 if (DEBUG_FLAGS & DEBUG_RESTART) { 5661 PRINT_ADDR(cp->xfer); 5662 printf ("in getcc reselect by t%d.\n", 5663 INB(nc_ssid) & 0x0f); 5664 } 5665 5666 /* 5667 ** Mark this job 5668 */ 5669 cp->host_status = HS_BUSY; 5670 cp->scsi_status = S_CHECK_COND; 5671 np->target[cp->xfer->sc_link->target].hold_cp = cp; 5672 5673 /* 5674 ** And patch code to restart it. 5675 */ 5676 np->script->start0[0] = SCR_INT; 5677 break; 5678 5679/*----------------------------------------------------------------------------- 5680** 5681** Was Sie schon immer ueber transfermode negotiation wissen wollten ... 5682** 5683** We try to negotiate sync and wide transfer only after 5684** a successfull inquire command. We look at byte 7 of the 5685** inquire data to determine the capabilities if the target. 5686** 5687** When we try to negotiate, we append the negotiation message 5688** to the identify and (maybe) simple tag message. 5689** The host status field is set to HS_NEGOTIATE to mark this 5690** situation. 5691** 5692** If the target doesn't answer this message immidiately 5693** (as required by the standard), the SIR_NEGO_FAIL interrupt 5694** will be raised eventually. 5695** The handler removes the HS_NEGOTIATE status, and sets the 5696** negotiated value to the default (async / nowide). 5697** 5698** If we receive a matching answer immediately, we check it 5699** for validity, and set the values. 5700** 5701** If we receive a Reject message immediately, we assume the 5702** negotiation has failed, and fall back to standard values. 5703** 5704** If we receive a negotiation message while not in HS_NEGOTIATE 5705** state, it's a target initiated negotiation. We prepare a 5706** (hopefully) valid answer, set our parameters, and send back 5707** this answer to the target. 5708** 5709** If the target doesn't fetch the answer (no message out phase), 5710** we assume the negotiation has failed, and fall back to default 5711** settings. 5712** 5713** When we set the values, we adjust them in all ccbs belonging 5714** to this target, in the controller's register, and in the "phys" 5715** field of the controller's struct ncb. 5716** 5717** Possible cases: hs sir msg_in value send goto 5718** We try try to negotiate: 5719** -> target doesnt't msgin NEG FAIL noop defa. - dispatch 5720** -> target rejected our msg NEG FAIL reject defa. - dispatch 5721** -> target answered (ok) NEG SYNC sdtr set - clrack 5722** -> target answered (!ok) NEG SYNC sdtr defa. REJ--->msg_bad 5723** -> target answered (ok) NEG WIDE wdtr set - clrack 5724** -> target answered (!ok) NEG WIDE wdtr defa. REJ--->msg_bad 5725** -> any other msgin NEG FAIL noop defa. - dispatch 5726** 5727** Target tries to negotiate: 5728** -> incoming message --- SYNC sdtr set SDTR - 5729** -> incoming message --- WIDE wdtr set WDTR - 5730** We sent our answer: 5731** -> target doesn't msgout --- PROTO ? defa. - dispatch 5732** 5733**----------------------------------------------------------------------------- 5734*/ 5735 5736 case SIR_NEGO_FAILED: 5737 /*------------------------------------------------------- 5738 ** 5739 ** Negotiation failed. 5740 ** Target doesn't send an answer message, 5741 ** or target rejected our message. 5742 ** 5743 ** Remove negotiation request. 5744 ** 5745 **------------------------------------------------------- 5746 */ 5747 OUTB (HS_PRT, HS_BUSY); 5748 5749 /* fall through */ 5750 5751 case SIR_NEGO_PROTO: 5752 /*------------------------------------------------------- 5753 ** 5754 ** Negotiation failed. 5755 ** Target doesn't fetch the answer message. 5756 ** 5757 **------------------------------------------------------- 5758 */ 5759 5760 if (DEBUG_FLAGS & DEBUG_NEGO) { 5761 PRINT_ADDR(cp->xfer); 5762 printf ("negotiation failed sir=%x status=%x.\n", 5763 num, cp->nego_status); 5764 }; 5765 5766 /* 5767 ** any error in negotiation: 5768 ** fall back to default mode. 5769 */ 5770 switch (cp->nego_status) { 5771 5772 case NS_SYNC: 5773 ncr_setsync (np, cp, 0xe0); 5774 break; 5775 5776 case NS_WIDE: 5777 ncr_setwide (np, cp, 0); 5778 break; 5779 5780 }; 5781 np->msgin [0] = M_NOOP; 5782 np->msgout[0] = M_NOOP; 5783 cp->nego_status = 0; 5784 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, dispatch)); 5785 break; 5786 5787 case SIR_NEGO_SYNC: 5788 /* 5789 ** Synchronous request message received. 5790 */ 5791 5792 if (DEBUG_FLAGS & DEBUG_NEGO) { 5793 PRINT_ADDR(cp->xfer); 5794 printf ("sync msgin: "); 5795 (void) ncr_show_msg (np->msgin); 5796 printf (".\n"); 5797 }; 5798 5799 /* 5800 ** get requested values. 5801 */ 5802 5803 chg = 0; 5804 per = np->msgin[3]; 5805 ofs = np->msgin[4]; 5806 if (ofs==0) per=255; 5807 5808 /* 5809 ** if target sends SDTR message, 5810 ** it CAN transfer synch. 5811 */ 5812 5813 if (ofs) 5814 tp->inqdata[7] |= INQ7_SYNC; 5815 5816 /* 5817 ** check values against driver limits. 5818 */ 5819 5820 if (per < np->ns_sync) 5821 {chg = 1; per = np->ns_sync;} 5822 if (per < tp->minsync) 5823 {chg = 1; per = tp->minsync;} 5824 if (ofs > tp->maxoffs) 5825 {chg = 1; ofs = tp->maxoffs;} 5826 5827 /* 5828 ** Check against controller limits. 5829 */ 5830 if (ofs != 0) { 5831 fak = (4ul * per - 1) / np->ns_sync - 3; 5832 if (fak>7) { 5833 chg = 1; 5834 ofs = 0; 5835 } 5836 } 5837 if (ofs == 0) { 5838 fak = 7; 5839 per = 0; 5840 tp->minsync = 0; 5841 } 5842 5843 if (DEBUG_FLAGS & DEBUG_NEGO) { 5844 PRINT_ADDR(cp->xfer); 5845 printf ("sync: per=%d ofs=%d fak=%d chg=%d.\n", 5846 per, ofs, fak, chg); 5847 } 5848 5849 if (INB (HS_PRT) == HS_NEGOTIATE) { 5850 OUTB (HS_PRT, HS_BUSY); 5851 switch (cp->nego_status) { 5852 5853 case NS_SYNC: 5854 /* 5855 ** This was an answer message 5856 */ 5857 if (chg) { 5858 /* 5859 ** Answer wasn't acceptable. 5860 */ 5861 ncr_setsync (np, cp, 0xe0); 5862 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad)); 5863 } else { 5864 /* 5865 ** Answer is ok. 5866 */ 5867 ncr_setsync (np, cp, (fak<<5)|ofs); 5868 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack)); 5869 }; 5870 return; 5871 5872 case NS_WIDE: 5873 ncr_setwide (np, cp, 0); 5874 break; 5875 }; 5876 }; 5877 5878 /* 5879 ** It was a request. Set value and 5880 ** prepare an answer message 5881 */ 5882 5883 ncr_setsync (np, cp, (fak<<5)|ofs); 5884 5885 np->msgout[0] = M_EXTENDED; 5886 np->msgout[1] = 3; 5887 np->msgout[2] = M_X_SYNC_REQ; 5888 np->msgout[3] = per; 5889 np->msgout[4] = ofs; 5890 5891 cp->nego_status = NS_SYNC; 5892 5893 if (DEBUG_FLAGS & DEBUG_NEGO) { 5894 PRINT_ADDR(cp->xfer); 5895 printf ("sync msgout: "); 5896 (void) ncr_show_msg (np->msgout); 5897 printf (".\n"); 5898 } 5899 5900 if (!ofs) { 5901 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad)); 5902 return; 5903 } 5904 np->msgin [0] = M_NOOP; 5905 5906 break; 5907 5908 case SIR_NEGO_WIDE: 5909 /* 5910 ** Wide request message received. 5911 */ 5912 if (DEBUG_FLAGS & DEBUG_NEGO) { 5913 PRINT_ADDR(cp->xfer); 5914 printf ("wide msgin: "); 5915 (void) ncr_show_msg (np->msgin); 5916 printf (".\n"); 5917 }; 5918 5919 /* 5920 ** get requested values. 5921 */ 5922 5923 chg = 0; 5924 wide = np->msgin[3]; 5925 5926 /* 5927 ** if target sends WDTR message, 5928 ** it CAN transfer wide. 5929 */ 5930 5931 if (wide) 5932 tp->inqdata[7] |= INQ7_WIDE16; 5933 5934 /* 5935 ** check values against driver limits. 5936 */ 5937 5938 if (wide > tp->usrwide) 5939 {chg = 1; wide = tp->usrwide;} 5940 5941 if (DEBUG_FLAGS & DEBUG_NEGO) { 5942 PRINT_ADDR(cp->xfer); 5943 printf ("wide: wide=%d chg=%d.\n", wide, chg); 5944 } 5945 5946 if (INB (HS_PRT) == HS_NEGOTIATE) { 5947 OUTB (HS_PRT, HS_BUSY); 5948 switch (cp->nego_status) { 5949 5950 case NS_WIDE: 5951 /* 5952 ** This was an answer message 5953 */ 5954 if (chg) { 5955 /* 5956 ** Answer wasn't acceptable. 5957 */ 5958 ncr_setwide (np, cp, 0); 5959 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, msg_bad)); 5960 } else { 5961 /* 5962 ** Answer is ok. 5963 */ 5964 ncr_setwide (np, cp, wide); 5965 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, clrack)); 5966 }; 5967 return; 5968 5969 case NS_SYNC: 5970 ncr_setsync (np, cp, 0xe0); 5971 break; 5972 }; 5973 }; 5974 5975 /* 5976 ** It was a request, set value and 5977 ** prepare an answer message 5978 */ 5979 5980 ncr_setwide (np, cp, wide); 5981 5982 np->msgout[0] = M_EXTENDED; 5983 np->msgout[1] = 2; 5984 np->msgout[2] = M_X_WIDE_REQ; 5985 np->msgout[3] = wide; 5986 5987 np->msgin [0] = M_NOOP; 5988 5989 cp->nego_status = NS_WIDE; 5990 5991 if (DEBUG_FLAGS & DEBUG_NEGO) { 5992 PRINT_ADDR(cp->xfer); 5993 printf ("wide msgout: "); 5994 (void) ncr_show_msg (np->msgout); 5995 printf (".\n"); 5996 } 5997 break; 5998 5999/*-------------------------------------------------------------------- 6000** 6001** Processing of special messages 6002** 6003**-------------------------------------------------------------------- 6004*/ 6005 6006 case SIR_REJECT_RECEIVED: 6007 /*----------------------------------------------- 6008 ** 6009 ** We received a M_REJECT message. 6010 ** 6011 **----------------------------------------------- 6012 */ 6013 6014 PRINT_ADDR(cp->xfer); 6015 printf ("M_REJECT received (%x:%x).\n", 6016 (unsigned)np->lastmsg, np->msgout[0]); 6017 break; 6018 6019 case SIR_REJECT_SENT: 6020 /*----------------------------------------------- 6021 ** 6022 ** We received an unknown message 6023 ** 6024 **----------------------------------------------- 6025 */ 6026 6027 PRINT_ADDR(cp->xfer); 6028 printf ("M_REJECT sent for "); 6029 (void) ncr_show_msg (np->msgin); 6030 printf (".\n"); 6031 break; 6032 6033/*-------------------------------------------------------------------- 6034** 6035** Processing of special messages 6036** 6037**-------------------------------------------------------------------- 6038*/ 6039 6040 case SIR_IGN_RESIDUE: 6041 /*----------------------------------------------- 6042 ** 6043 ** We received an IGNORE RESIDUE message, 6044 ** which couldn't be handled by the script. 6045 ** 6046 **----------------------------------------------- 6047 */ 6048 6049 PRINT_ADDR(cp->xfer); 6050 printf ("M_IGN_RESIDUE received, but not yet implemented.\n"); 6051 break; 6052 6053 case SIR_MISSING_SAVE: 6054 /*----------------------------------------------- 6055 ** 6056 ** We received an DISCONNECT message, 6057 ** but the datapointer wasn't saved before. 6058 ** 6059 **----------------------------------------------- 6060 */ 6061 6062 PRINT_ADDR(cp->xfer); 6063 printf ("M_DISCONNECT received, but datapointer not saved:\n" 6064 "\tdata=%x save=%x goal=%x.\n", 6065 (unsigned) INL (nc_temp), 6066 (unsigned) np->header.savep, 6067 (unsigned) np->header.goalp); 6068 break; 6069 6070/*-------------------------------------------------------------------- 6071** 6072** Processing of a "S_QUEUE_FULL" status. 6073** 6074** The current command has been rejected, 6075** because there are too many in the command queue. 6076** We have started too many commands for that target. 6077** 6078** If possible, reinsert at head of queue. 6079** Stall queue until there are no disconnected jobs 6080** (ncr is REALLY idle). Then restart processing. 6081** 6082** We should restart the current job after the controller 6083** has become idle. But this is not yet implemented. 6084** 6085**-------------------------------------------------------------------- 6086*/ 6087 case SIR_STALL_QUEUE: 6088 /*----------------------------------------------- 6089 ** 6090 ** Stall the start queue. 6091 ** 6092 **----------------------------------------------- 6093 */ 6094 PRINT_ADDR(cp->xfer); 6095 printf ("queue full.\n"); 6096 6097 np->script->start1[0] = SCR_INT; 6098 6099 /* 6100 ** Try to disable tagged transfers. 6101 */ 6102 ncr_setmaxtags (&np->target[target], 0); 6103 6104 /* 6105 ** @QUEUE@ 6106 ** 6107 ** Should update the launch field of the 6108 ** current job to be able to restart it. 6109 ** Then prepend it to the start queue. 6110 */ 6111 6112 /* fall through */ 6113 6114 case SIR_STALL_RESTART: 6115 /*----------------------------------------------- 6116 ** 6117 ** Enable selecting again, 6118 ** if NO disconnected jobs. 6119 ** 6120 **----------------------------------------------- 6121 */ 6122 /* 6123 ** Look for a disconnected job. 6124 */ 6125 cp = &np->ccb; 6126 while (cp && cp->host_status != HS_DISCONNECT) 6127 cp = cp->link_ccb; 6128 6129 /* 6130 ** if there is one, ... 6131 */ 6132 if (cp) { 6133 /* 6134 ** wait for reselection 6135 */ 6136 OUTL (nc_dsp, NCB_SCRIPT_PHYS (np, reselect)); 6137 return; 6138 }; 6139 6140 /* 6141 ** else remove the interrupt. 6142 */ 6143 6144 printf ("%s: queue empty.\n", ncr_name (np)); 6145 np->script->start1[0] = SCR_INT ^ IFFALSE (0); 6146 break; 6147 }; 6148 6149out: 6150 OUTB (nc_dcntl, np->rv_dcntl | STD); 6151} 6152 6153/*========================================================== 6154** 6155** 6156** Aquire a control block 6157** 6158** 6159**========================================================== 6160*/ 6161 6162static ccb_p ncr_get_ccb 6163 (ncb_p np, u_long flags, u_long target, u_long lun) 6164{ 6165 lcb_p lp; 6166 ccb_p cp = (ccb_p) 0; 6167 int oldspl; 6168 6169 oldspl = splhigh(); 6170 /* 6171 ** Lun structure available ? 6172 */ 6173 6174 lp = np->target[target].lp[lun]; 6175 if (lp) { 6176 cp = lp->next_ccb; 6177 6178 /* 6179 ** Look for free CCB 6180 */ 6181 6182 while (cp && cp->magic) { 6183 cp = cp->next_ccb; 6184 } 6185 } 6186 6187 /* 6188 ** if nothing available, take the default. 6189 */ 6190 6191 if (!cp) cp = &np->ccb; 6192 6193 /* 6194 ** Wait until available. 6195 */ 6196 6197 while (cp->magic) { 6198 if (flags & SCSI_NOSLEEP) break; 6199 if (tsleep ((caddr_t)cp, PRIBIO|PCATCH, "ncr", 0)) 6200 break; 6201 }; 6202 6203 if (cp->magic) { 6204 splx(oldspl); 6205 return ((ccb_p) 0); 6206 } 6207 6208 cp->magic = 1; 6209 splx(oldspl); 6210 return (cp); 6211} 6212 6213/*========================================================== 6214** 6215** 6216** Release one control block 6217** 6218** 6219**========================================================== 6220*/ 6221 6222void ncr_free_ccb (ncb_p np, ccb_p cp, int flags) 6223{ 6224 /* 6225 ** sanity 6226 */ 6227 6228 assert (cp != NULL); 6229 6230 cp -> host_status = HS_IDLE; 6231 cp -> magic = 0; 6232 if (cp == &np->ccb) 6233 wakeup ((caddr_t) cp); 6234} 6235 6236/*========================================================== 6237** 6238** 6239** Allocation of resources for Targets/Luns/Tags. 6240** 6241** 6242**========================================================== 6243*/ 6244 6245static void ncr_alloc_ccb (ncb_p np, u_long target, u_long lun) 6246{ 6247 tcb_p tp; 6248 lcb_p lp; 6249 ccb_p cp; 6250 6251 assert (np != NULL); 6252 6253 if (target>=MAX_TARGET) return; 6254 if (lun >=MAX_LUN ) return; 6255 6256 tp=&np->target[target]; 6257 6258 if (!tp->jump_tcb.l_cmd) { 6259 6260 /* 6261 ** initialize it. 6262 */ 6263 tp->jump_tcb.l_cmd = (SCR_JUMP^IFFALSE (DATA (0x80 + target))); 6264 tp->jump_tcb.l_paddr = np->jump_tcb.l_paddr; 6265 6266 tp->getscr[0] = SCR_COPY (1); 6267 tp->getscr[1] = vtophys (&tp->sval); 6268 tp->getscr[2] = np->paddr + offsetof (struct ncr_reg, nc_sxfer); 6269 tp->getscr[3] = SCR_COPY (1); 6270 tp->getscr[4] = vtophys (&tp->wval); 6271 tp->getscr[5] = np->paddr + offsetof (struct ncr_reg, nc_scntl3); 6272 6273 assert (( (offsetof(struct ncr_reg, nc_sxfer) ^ 6274 offsetof(struct tcb , sval )) &3) == 0); 6275 assert (( (offsetof(struct ncr_reg, nc_scntl3) ^ 6276 offsetof(struct tcb , wval )) &3) == 0); 6277 6278 tp->call_lun.l_cmd = (SCR_CALL); 6279 tp->call_lun.l_paddr = NCB_SCRIPT_PHYS (np, resel_lun); 6280 6281 tp->jump_lcb.l_cmd = (SCR_JUMP); 6282 tp->jump_lcb.l_paddr = NCB_SCRIPT_PHYS (np, abort); 6283 np->jump_tcb.l_paddr = vtophys (&tp->jump_tcb); 6284 6285 tp->usrtags = SCSI_NCR_DFLT_TAGS; 6286 ncr_setmaxtags (tp, tp->usrtags); 6287 } 6288 6289 /* 6290 ** Logic unit control block 6291 */ 6292 lp = tp->lp[lun]; 6293 if (!lp) { 6294 /* 6295 ** Allocate a lcb 6296 */ 6297 lp = (lcb_p) malloc (sizeof (struct lcb), M_DEVBUF, M_NOWAIT); 6298 if (!lp) return; 6299 6300 /* 6301 ** Initialize it 6302 */ 6303 bzero (lp, sizeof (*lp)); 6304 lp->jump_lcb.l_cmd = (SCR_JUMP ^ IFFALSE (DATA (lun))); 6305 lp->jump_lcb.l_paddr = tp->jump_lcb.l_paddr; 6306 6307 lp->call_tag.l_cmd = (SCR_CALL); 6308 lp->call_tag.l_paddr = NCB_SCRIPT_PHYS (np, resel_tag); 6309 6310 lp->jump_ccb.l_cmd = (SCR_JUMP); 6311 lp->jump_ccb.l_paddr = NCB_SCRIPT_PHYS (np, aborttag); 6312 6313 lp->actlink = 1; 6314 6315 /* 6316 ** Chain into LUN list 6317 */ 6318 tp->jump_lcb.l_paddr = vtophys (&lp->jump_lcb); 6319 tp->lp[lun] = lp; 6320 6321 } 6322 6323 /* 6324 ** Limit possible number of ccbs. 6325 ** 6326 ** If tagged command queueing is enabled, 6327 ** can use more than one ccb. 6328 */ 6329 6330 if (np->actccbs >= MAX_START-2) return; 6331 if (lp->actccbs && (lp->actccbs >= lp->reqccbs)) 6332 return; 6333 6334 /* 6335 ** Allocate a ccb 6336 */ 6337 cp = (ccb_p) malloc (sizeof (struct ccb), M_DEVBUF, M_NOWAIT); 6338 6339 if (!cp) 6340 return; 6341 6342 if (DEBUG_FLAGS & DEBUG_ALLOC) { 6343 printf ("new ccb @%x.\n", (unsigned) cp); 6344 } 6345 6346 /* 6347 ** Count it 6348 */ 6349 lp->actccbs++; 6350 np->actccbs++; 6351 6352 /* 6353 ** Initialize it 6354 */ 6355 bzero (cp, sizeof (*cp)); 6356 6357 /* 6358 ** Fill in physical addresses 6359 */ 6360 6361 cp->p_ccb = vtophys (cp); 6362 6363 /* 6364 ** Chain into reselect list 6365 */ 6366 cp->jump_ccb.l_cmd = SCR_JUMP; 6367 cp->jump_ccb.l_paddr = lp->jump_ccb.l_paddr; 6368 lp->jump_ccb.l_paddr = CCB_PHYS (cp, jump_ccb); 6369 cp->call_tmp.l_cmd = SCR_CALL; 6370 cp->call_tmp.l_paddr = NCB_SCRIPT_PHYS (np, resel_tmp); 6371 6372 /* 6373 ** Chain into wakeup list 6374 */ 6375 cp->link_ccb = np->ccb.link_ccb; 6376 np->ccb.link_ccb = cp; 6377 6378 /* 6379 ** Chain into CCB list 6380 */ 6381 cp->next_ccb = lp->next_ccb; 6382 lp->next_ccb = cp; 6383} 6384 6385/*========================================================== 6386** 6387** 6388** Announce the number of ccbs/tags to the scsi driver. 6389** 6390** 6391**========================================================== 6392*/ 6393 6394static void ncr_opennings (ncb_p np, lcb_p lp, struct scsi_xfer * xp) 6395{ 6396 /* 6397 ** want to reduce the number ... 6398 */ 6399 if (lp->actlink > lp->reqlink) { 6400 6401 /* 6402 ** Try to reduce the count. 6403 ** We assume to run at splbio .. 6404 */ 6405 u_char diff = lp->actlink - lp->reqlink; 6406 6407 if (!diff) return; 6408 6409#ifdef __NetBSD__ 6410 if (diff > xp->sc_link->openings) 6411 diff = xp->sc_link->openings; 6412 6413 xp->sc_link->openings -= diff; 6414#else /* !__NetBSD__ */ 6415 if (diff > xp->sc_link->opennings) 6416 diff = xp->sc_link->opennings; 6417 6418 xp->sc_link->opennings -= diff; 6419#endif /* __NetBSD__ */ 6420 lp->actlink -= diff; 6421 if (DEBUG_FLAGS & DEBUG_TAGS) 6422 printf ("%s: actlink: diff=%d, new=%d, req=%d\n", 6423 ncr_name(np), diff, lp->actlink, lp->reqlink); 6424 return; 6425 }; 6426 6427 /* 6428 ** want to increase the number ? 6429 */ 6430 if (lp->reqlink > lp->actlink) { 6431 u_char diff = lp->reqlink - lp->actlink; 6432 6433#ifdef __NetBSD__ 6434 xp->sc_link->openings += diff; 6435#else /* !__NetBSD__ */ 6436 xp->sc_link->opennings += diff; 6437#endif /* __NetBSD__ */ 6438 lp->actlink += diff; 6439 wakeup ((caddr_t) xp->sc_link); 6440 if (DEBUG_FLAGS & DEBUG_TAGS) 6441 printf ("%s: actlink: diff=%d, new=%d, req=%d\n", 6442 ncr_name(np), diff, lp->actlink, lp->reqlink); 6443 }; 6444} 6445 6446/*========================================================== 6447** 6448** 6449** Build Scatter Gather Block 6450** 6451** 6452**========================================================== 6453** 6454** The transfer area may be scattered among 6455** several non adjacent physical pages. 6456** 6457** We may use MAX_SCATTER blocks. 6458** 6459**---------------------------------------------------------- 6460*/ 6461 6462static int ncr_scatter 6463 (struct dsb* phys, vm_offset_t vaddr, vm_size_t datalen) 6464{ 6465 u_long paddr, pnext; 6466 6467 u_short segment = 0; 6468 u_long segsize, segaddr; 6469 u_long size, csize = 0; 6470 u_long chunk = MAX_SIZE; 6471 int free; 6472 6473 bzero (&phys->data, sizeof (phys->data)); 6474 if (!datalen) return (0); 6475 6476 paddr = vtophys (vaddr); 6477 6478 /* 6479 ** insert extra break points at a distance of chunk. 6480 ** We try to reduce the number of interrupts caused 6481 ** by unexpected phase changes due to disconnects. 6482 ** A typical harddisk may disconnect before ANY block. 6483 ** If we wanted to avoid unexpected phase changes at all 6484 ** we had to use a break point every 512 bytes. 6485 ** Of course the number of scatter/gather blocks is 6486 ** limited. 6487 */ 6488 6489 free = MAX_SCATTER - 1; 6490 6491 if (vaddr & PAGE_MASK) free -= datalen / PAGE_SIZE; 6492 6493 if (free>1) 6494 while ((chunk * free >= 2 * datalen) && (chunk>=1024)) 6495 chunk /= 2; 6496 6497 if(DEBUG_FLAGS & DEBUG_SCATTER) 6498 printf("ncr?:\tscattering virtual=0x%x size=%d chunk=%d.\n", 6499 (unsigned) vaddr, (unsigned) datalen, (unsigned) chunk); 6500 6501 /* 6502 ** Build data descriptors. 6503 */ 6504 while (datalen && (segment < MAX_SCATTER)) { 6505 6506 /* 6507 ** this segment is empty 6508 */ 6509 segsize = 0; 6510 segaddr = paddr; 6511 pnext = paddr; 6512 6513 if (!csize) csize = chunk; 6514 6515 while ((datalen) && (paddr == pnext) && (csize)) { 6516 6517 /* 6518 ** continue this segment 6519 */ 6520 pnext = (paddr & (~PAGE_MASK)) + PAGE_SIZE; 6521 6522 /* 6523 ** Compute max size 6524 */ 6525 6526 size = pnext - paddr; /* page size */ 6527 if (size > datalen) size = datalen; /* data size */ 6528 if (size > csize ) size = csize ; /* chunksize */ 6529 6530 segsize += size; 6531 vaddr += size; 6532 csize -= size; 6533 datalen -= size; 6534 paddr = vtophys (vaddr); 6535 }; 6536 6537 if(DEBUG_FLAGS & DEBUG_SCATTER) 6538 printf ("\tseg #%d addr=%x size=%d (rest=%d).\n", 6539 segment, 6540 (unsigned) segaddr, 6541 (unsigned) segsize, 6542 (unsigned) datalen); 6543 6544 phys->data[segment].addr = segaddr; 6545 phys->data[segment].size = segsize; 6546 segment++; 6547 } 6548 6549 if (datalen) { 6550 printf("ncr?: scatter/gather failed (residue=%d).\n", 6551 (unsigned) datalen); 6552 return (-1); 6553 }; 6554 6555 return (segment); 6556} 6557 6558/*========================================================== 6559** 6560** 6561** Test the pci bus snoop logic :-( 6562** 6563** Has to be called with interrupts disabled. 6564** 6565** 6566**========================================================== 6567*/ 6568 6569#ifndef NCR_IOMAPPED 6570static int ncr_regtest (struct ncb* np) 6571{ 6572 register volatile u_long data, *addr; 6573 /* 6574 ** ncr registers may NOT be cached. 6575 ** write 0xffffffff to a read only register area, 6576 ** and try to read it back. 6577 */ 6578 addr = (volatile u_long*) &np->reg->nc_dstat; 6579 data = 0xffffffff; 6580 *addr= data; 6581 data = *addr; 6582#if 1 6583 if (data == 0xffffffff) { 6584#else 6585 if ((data & 0xe2f0fffd) != 0x02000080) { 6586#endif 6587 printf ("CACHE TEST FAILED: reg dstat-sstat2 readback %x.\n", 6588 (unsigned) data); 6589 return (0x10); 6590 }; 6591 return (0); 6592} 6593#endif 6594 6595static int ncr_snooptest (struct ncb* np) 6596{ 6597 u_long ncr_rd, ncr_wr, ncr_bk, host_rd, host_wr, pc, err=0; 6598 int i; 6599#ifndef NCR_IOMAPPED 6600 err |= ncr_regtest (np); 6601 if (err) return (err); 6602#endif 6603 /* 6604 ** init 6605 */ 6606 pc = NCB_SCRIPT_PHYS (np, snooptest); 6607 host_wr = 1; 6608 ncr_wr = 2; 6609 /* 6610 ** Set memory and register. 6611 */ 6612 ncr_cache = host_wr; 6613 OUTL (nc_temp, ncr_wr); 6614 /* 6615 ** Start script (exchange values) 6616 */ 6617 OUTL (nc_dsp, pc); 6618 /* 6619 ** Wait 'til done (with timeout) 6620 */ 6621 for (i=0; i<NCR_SNOOP_TIMEOUT; i++) 6622 if (INB(nc_istat) & (INTF|SIP|DIP)) 6623 break; 6624 /* 6625 ** Save termination position. 6626 */ 6627 pc = INL (nc_dsp); 6628 /* 6629 ** Read memory and register. 6630 */ 6631 host_rd = ncr_cache; 6632 ncr_rd = INL (nc_scratcha); 6633 ncr_bk = INL (nc_temp); 6634 /* 6635 ** Reset ncr chip 6636 */ 6637 OUTB (nc_istat, SRST); 6638 DELAY (1000); 6639 OUTB (nc_istat, 0 ); 6640 /* 6641 ** check for timeout 6642 */ 6643 if (i>=NCR_SNOOP_TIMEOUT) { 6644 printf ("CACHE TEST FAILED: timeout.\n"); 6645 return (0x20); 6646 }; 6647 /* 6648 ** Check termination position. 6649 */ 6650 if (pc != NCB_SCRIPT_PHYS (np, snoopend)+8) { 6651 printf ("CACHE TEST FAILED: script execution failed.\n"); 6652 printf ("\tstart=%08x, pc=%08x, end=%08x\n", 6653 NCB_SCRIPT_PHYS (np, snooptest), pc, 6654 NCB_SCRIPT_PHYS (np, snoopend) +8); 6655 return (0x40); 6656 }; 6657 /* 6658 ** Show results. 6659 */ 6660 if (host_wr != ncr_rd) { 6661 printf ("CACHE TEST FAILED: host wrote %d, ncr read %d.\n", 6662 (int) host_wr, (int) ncr_rd); 6663 err |= 1; 6664 }; 6665 if (host_rd != ncr_wr) { 6666 printf ("CACHE TEST FAILED: ncr wrote %d, host read %d.\n", 6667 (int) ncr_wr, (int) host_rd); 6668 err |= 2; 6669 }; 6670 if (ncr_bk != ncr_wr) { 6671 printf ("CACHE TEST FAILED: ncr wrote %d, read back %d.\n", 6672 (int) ncr_wr, (int) ncr_bk); 6673 err |= 4; 6674 }; 6675 return (err); 6676} 6677 6678/*========================================================== 6679** 6680** 6681** Profiling the drivers and targets performance. 6682** 6683** 6684**========================================================== 6685*/ 6686 6687/* 6688** Compute the difference in milliseconds. 6689**/ 6690 6691static int ncr_delta (struct timeval * from, struct timeval * to) 6692{ 6693 if (!from->tv_sec) return (-1); 6694 if (!to ->tv_sec) return (-2); 6695 return ( (to->tv_sec - from->tv_sec - 2)*1000+ 6696 +(to->tv_usec - from->tv_usec + 2000000)/1000); 6697} 6698 6699#define PROFILE cp->phys.header.stamp 6700static void ncb_profile (ncb_p np, ccb_p cp) 6701{ 6702 int co, da, st, en, di, se, post,work,disc; 6703 u_long diff; 6704 6705 gettime(&PROFILE.end); 6706 6707 st = ncr_delta (&PROFILE.start,&PROFILE.status); 6708 if (st<0) return; /* status not reached */ 6709 6710 da = ncr_delta (&PROFILE.start,&PROFILE.data); 6711 if (da<0) return; /* No data transfer phase */ 6712 6713 co = ncr_delta (&PROFILE.start,&PROFILE.command); 6714 if (co<0) return; /* command not executed */ 6715 6716 en = ncr_delta (&PROFILE.start,&PROFILE.end), 6717 di = ncr_delta (&PROFILE.start,&PROFILE.disconnect), 6718 se = ncr_delta (&PROFILE.start,&PROFILE.select); 6719 post = en - st; 6720 6721 /* 6722 ** @PROFILE@ Disconnect time invalid if multiple disconnects 6723 */ 6724 6725 if (di>=0) disc = se-di; else disc = 0; 6726 6727 work = (st - co) - disc; 6728 6729 diff = (np->disc_phys - np->disc_ref) & 0xff; 6730 np->disc_ref += diff; 6731 6732 np->profile.num_trans += 1; 6733 if (cp->xfer) 6734 np->profile.num_bytes += cp->xfer->datalen; 6735 np->profile.num_disc += diff; 6736 np->profile.ms_setup += co; 6737 np->profile.ms_data += work; 6738 np->profile.ms_disc += disc; 6739 np->profile.ms_post += post; 6740} 6741#undef PROFILE 6742 6743/*========================================================== 6744** 6745** Determine the ncr's clock frequency. 6746** This is important for the negotiation 6747** of the synchronous transfer rate. 6748** 6749**========================================================== 6750** 6751** Note: we have to return the correct value. 6752** THERE IS NO SAVE DEFAULT VALUE. 6753** 6754** We assume that all NCR based boards are delivered 6755** with a 40Mhz clock. Because we have to divide 6756** by an integer value greater than 3, only clock 6757** frequencies of 40Mhz (/4) or 50MHz (/5) permit 6758** the FAST-SCSI rate of 10MHz. 6759** 6760**---------------------------------------------------------- 6761*/ 6762 6763#ifndef NCR_CLOCK 6764# define NCR_CLOCK 40 6765#endif /* NCR_CLOCK */ 6766 6767/* 6768 * calculate NCR SCSI clock frequency (in KHz) 6769 */ 6770static unsigned 6771ncrgetfreq (ncb_p np, int gen) 6772{ 6773 int ms = 0; 6774 /* 6775 * Measure GEN timer delay in order 6776 * to calculate SCSI clock frequency 6777 * 6778 * This code will never execute too 6779 * many loop iterations (if DELAY is 6780 * reasonably correct). It could get 6781 * too low a delay (too high a freq.) 6782 * if the CPU is slow executing the 6783 * loop for some reason (an NMI, for 6784 * example). For this reason we will 6785 * if multiple measurements are to be 6786 * performed trust the higher delay 6787 * (lower frequency returned). 6788 */ 6789 OUTB (nc_stest1, 0); /* make sure clock doubler is OFF */ 6790 OUTW (nc_sien , 0); /* mask all scsi interrupts */ 6791 (void) INW (nc_sist); /* clear pending scsi interrupt */ 6792 OUTB (nc_dien , 0); /* mask all dma interrupts */ 6793 (void) INW (nc_sist); /* another one, just to be sure :) */ 6794 OUTB (nc_scntl3, 4); /* set pre-scaler to divide by 3 */ 6795 OUTB (nc_stime1, 0); /* disable general purpose timer */ 6796 OUTB (nc_stime1, gen); /* set to nominal delay of (1<<gen) * 125us */ 6797 while (!(INW(nc_sist) & GEN) && ms++ < 1000) 6798 DELAY(1000); /* count ms */ 6799 OUTB (nc_stime1, 0); /* disable general purpose timer */ 6800 OUTB (nc_scntl3, 0); 6801 /* 6802 * Set prescaler to divide by whatever "0" means. 6803 * "0" ought to choose divide by 2, but appears 6804 * to set divide by 3.5 mode in my 53c810 ... 6805 */ 6806 OUTB (nc_scntl3, 0); 6807 6808 if (bootverbose) 6809 printf ("\tDelay (GEN=%d): %lu msec\n", gen, ms); 6810 /* 6811 * adjust for prescaler, and convert into KHz 6812 */ 6813 return ms ? ((1 << gen) * 4440) / ms : 0; 6814} 6815 6816static void ncr_getclock (ncb_p np) 6817{ 6818 unsigned char scntl3; 6819 unsigned char stest1; 6820 scntl3 = INB(nc_scntl3); 6821 stest1 = INB(nc_stest1); 6822 6823 /* always false, except for 875 with clock doubler selected */ 6824 if ((stest1 & (DBLEN+DBLSEL)) == DBLEN+DBLSEL) { 6825 OUTB(nc_stest1, 0); 6826 scntl3 = 3; 6827 } else { 6828 if ((scntl3 & 7) == 0) { 6829 unsigned f1, f2; 6830 /* throw away first result */ 6831 (void) ncrgetfreq (np, 11); 6832 f1 = ncrgetfreq (np, 11); 6833 f2 = ncrgetfreq (np, 11); 6834 6835 if (bootverbose) 6836 printf ("\tNCR clock is %luKHz, %luKHz\n", f1, f2); 6837 if (f1 > f2) f1 = f2; /* trust lower result */ 6838 if (f1 > 45000) { 6839 scntl3 = 5; /* >45Mhz: assume 80MHz */ 6840 } else { 6841 scntl3 = 3; /* <45Mhz: assume 40MHz */ 6842 } 6843 } 6844 } 6845 6846 np->rv_scntl3 = ((scntl3 & 0x7) << 4) -0x20 + (scntl3 & 0x7); 6847 6848 if (bootverbose) { 6849 printf ("\tinitial value of SCNTL3 = %02x, final = %02x\n", 6850 scntl3, np->rv_scntl3); 6851 } 6852} 6853 6854/*=========================================================================*/ 6855 6856#ifdef NCR_TEKRAM_EEPROM 6857 6858struct tekram_eeprom_dev { 6859 u_char devmode; 6860#define TKR_PARCHK 0x01 6861#define TKR_TRYSYNC 0x02 6862#define TKR_ENDISC 0x04 6863#define TKR_STARTUNIT 0x08 6864#define TKR_USETAGS 0x10 6865#define TKR_TRYWIDE 0x20 6866 u_char syncparam; /* max. sync transfer rate (table ?) */ 6867 u_char filler1; 6868 u_char filler2; 6869}; 6870 6871 6872struct tekram_eeprom { 6873 struct tekram_eeprom_dev 6874 dev[16]; 6875 u_char adaptid; 6876 u_char adaptmode; 6877#define TKR_ADPT_GT2DRV 0x01 6878#define TKR_ADPT_GT1GB 0x02 6879#define TKR_ADPT_RSTBUS 0x04 6880#define TKR_ADPT_ACTNEG 0x08 6881#define TKR_ADPT_NOSEEK 0x10 6882#define TKR_ADPT_MORLUN 0x20 6883 u_char delay; /* unit ? (table ???) */ 6884 u_char tags; /* use 4 times as many ... */ 6885 u_char filler[60]; 6886}; 6887 6888static void 6889tekram_write_bit (ncb_p np, int bit) 6890{ 6891 u_char val = 0x10 + ((bit & 1) << 1); 6892 6893 DELAY(10); 6894 OUTB (nc_gpreg, val); 6895 DELAY(10); 6896 OUTB (nc_gpreg, val | 0x04); 6897 DELAY(10); 6898 OUTB (nc_gpreg, val); 6899 DELAY(10); 6900} 6901 6902static int 6903tekram_read_bit (ncb_p np) 6904{ 6905 OUTB (nc_gpreg, 0x10); 6906 DELAY(10); 6907 OUTB (nc_gpreg, 0x14); 6908 DELAY(10); 6909 return INB (nc_gpreg) & 1; 6910} 6911 6912static u_short 6913read_tekram_eeprom_reg (ncb_p np, int reg) 6914{ 6915 int bit; 6916 u_short result = 0; 6917 int cmd = 0x80 | reg; 6918 6919 OUTB (nc_gpreg, 0x10); 6920 6921 tekram_write_bit (np, 1); 6922 for (bit = 7; bit >= 0; bit--) 6923 { 6924 tekram_write_bit (np, cmd >> bit); 6925 } 6926 6927 for (bit = 0; bit < 16; bit++) 6928 { 6929 result <<= 1; 6930 result |= tekram_read_bit (np); 6931 } 6932 6933 OUTB (nc_gpreg, 0x00); 6934 return result; 6935} 6936 6937static int 6938read_tekram_eeprom(ncb_p np, struct tekram_eeprom *buffer) 6939{ 6940 u_short *p = (u_short *) buffer; 6941 u_short sum = 0; 6942 int i; 6943 6944 if (INB (nc_gpcntl) != 0x09) 6945 { 6946 return 0; 6947 } 6948 for (i = 0; i < 64; i++) 6949 { 6950 u_short val; 6951if((i&0x0f) == 0) printf ("%02x:", i*2); 6952 val = read_tekram_eeprom_reg (np, i); 6953 if (p) 6954 *p++ = val; 6955 sum += val; 6956if((i&0x01) == 0x00) printf (" "); 6957 printf ("%02x%02x", val & 0xff, (val >> 8) & 0xff); 6958if((i&0x0f) == 0x0f) printf ("\n"); 6959 } 6960printf ("Sum = %04x\n", sum); 6961 return sum == 0x1234; 6962} 6963#endif /* NCR_TEKRAM_EEPROM */ 6964 6965/*=========================================================================*/ 6966#endif /* KERNEL */ 6967