Annotation of Net2/arch/i386/isa/bt742a.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Written by Julian Elischer ([email protected])
        !             3:  * for TRW Financial Systems for use under the MACH(2.5) operating system.
        !             4:  *
        !             5:  * TRW Financial Systems, in accordance with their agreement with Carnegie
        !             6:  * Mellon University, makes this software available to CMU to distribute
        !             7:  * or use in any manner that they see fit as long as this message is kept with
        !             8:  * the software. For this reason TFS also grants any other persons or
        !             9:  * organisations permission to use or modify this software.
        !            10:  *
        !            11:  * TFS supplies this software to be publicly redistributed
        !            12:  * on the understanding that TFS is not responsible for the correct
        !            13:  * functioning of this software in any circumstances.
        !            14:  *
        !            15:  *
        !            16:  * PATCHES MAGIC                LEVEL   PATCH THAT GOT US HERE
        !            17:  * --------------------         -----   ----------------------
        !            18:  * CURRENT PATCH LEVEL:         1       00098
        !            19:  * --------------------         -----   ----------------------
        !            20:  *
        !            21:  * 16 Feb 93   Julian Elischer         ADDED for SCSI system
        !            22:  */
        !            23: 
        !            24: /*
        !            25:  * HISTORY
        !            26:  * $Log: bt742a.c,v $
        !            27:  * Revision 1.2  1993/04/10 12:05:14  glass
        !            28:  * fixed to be compliant, subservient, and to take advantage of the newly
        !            29:  * hacked config(8)
        !            30:  *
        !            31:  * Revision 1.1  1993/03/21  18:10:06  cgd
        !            32:  * after 0.2.2 "stable" patches applied
        !            33:  * 
        !            34:  * Revision 1.7  1992/08/24  22:40:16  jason
        !            35:  * BIG_DMA ifdef for 512 dma segments instead of 128 segments
        !            36:  *
        !            37:  * Revision 1.6  1992/08/24  21:01:58  jason
        !            38:  * many changes and bugfixes for osf1
        !            39:  *
        !            40:  * Revision 1.5  1992/07/31  01:22:03  julian
        !            41:  * support improved scsi.h layout
        !            42:  *
        !            43:  * Revision 1.4  1992/07/25  03:11:26  julian
        !            44:  * check each request fro sane flags.
        !            45:  *
        !            46:  * Revision 1.3  1992/07/24  00:52:45  julian
        !            47:  * improved timeout handling.
        !            48:  * added support for two arguments to the sd_done (or equiv) call so that
        !            49:  * they can pre-queue several arguments.
        !            50:  * slightly clean up error handling
        !            51:  *
        !            52:  * Revision 1.2  1992/07/17  22:03:54  julian
        !            53:  * upgraded the timeout code.
        !            54:  * added support for UIO-based i/o (as used for pmem operations)
        !            55:  *
        !            56:  * Revision 1.1  1992/05/27  00:51:12  balsup
        !            57:  * machkern/cor merge
        !            58:  * 
        !            59:  */
        !            60: 
        !            61: /*
        !            62:  * bt742a BT-1542A SCSI driver
        !            63:  */
        !            64: 
        !            65: #include <sys/types.h>
        !            66: #include <bt.h>
        !            67: 
        !            68: #include <sys/param.h>
        !            69: #include <sys/systm.h>
        !            70: #include <sys/errno.h>
        !            71: #include <sys/ioctl.h>
        !            72: #include <sys/buf.h>
        !            73: #include <sys/proc.h>
        !            74: #include <sys/user.h>
        !            75: 
        !            76: #ifdef MACH    /* EITHER CMU OR OSF */
        !            77: #include <i386/ipl.h>
        !            78: #include <i386at/scsi.h>
        !            79: #include <i386at/scsiconf.h>
        !            80: 
        !            81: #ifdef OSF     /* OSF ONLY */
        !            82: #include <sys/table.h>
        !            83: #include <i386/handler.h>
        !            84: #include <i386/dispatcher.h>
        !            85: #include <i386/AT386/atbus.h>
        !            86: 
        !            87: #else  OSF     /* CMU ONLY */
        !            88: #include <i386at/atbus.h>
        !            89: #include <i386/pio.h>
        !            90: #endif OSF
        !            91: #endif MACH    /* end of MACH specific */
        !            92: 
        !            93: #ifdef __386BSD__      /* 386BSD specific */
        !            94: #define isa_dev isa_device
        !            95: #define dev_unit id_unit
        !            96: #define dev_addr id_iobase
        !            97: 
        !            98: #include <i386/isa/isa_device.h>
        !            99: #include <scsi/scsi_all.h>
        !           100: #include <scsi/scsiconf.h>
        !           101: #endif __386BSD__
        !           102: 
        !           103: 
        !           104: #ifdef __386BSD__
        !           105: #ifdef DDB
        !           106: int    Debugger();
        !           107: #else
        !           108: #define        Debugger() panic("should call debugger here (adaptec.c)")
        !           109: #endif /*!DDB*/
        !           110: #endif __386BSD__
        !           111: 
        !           112: #ifdef MACH
        !           113: int    Debugger();
        !           114: #endif MACH
        !           115: 
        !           116: extern int delaycount; /* from clock setup code */
        !           117: typedef unsigned long int physaddr;
        !           118: 
        !           119: /*
        !           120:  * I/O Port Interface
        !           121:  */
        !           122: 
        !           123: #define        BT_BASE         bt_base[unit]
        !           124: #define        BT_CTRL_STAT_PORT       (BT_BASE + 0x0) /* control & status */
        !           125: #define        BT_CMD_DATA_PORT        (BT_BASE + 0x1) /* cmds and datas */
        !           126: #define        BT_INTR_PORT            (BT_BASE + 0x2) /* Intr. stat */
        !           127: 
        !           128: /*
        !           129:  * BT_CTRL_STAT bits (write)
        !           130:  */
        !           131: 
        !           132: #define BT_HRST                0x80    /* Hardware reset */
        !           133: #define BT_SRST                0x40    /* Software reset */
        !           134: #define BT_IRST                0x20    /* Interrupt reset */
        !           135: #define BT_SCRST       0x10    /* SCSI bus reset */
        !           136: 
        !           137: /*
        !           138:  * BT_CTRL_STAT bits (read)
        !           139:  */
        !           140: 
        !           141: #define BT_STST                0x80    /* Self test in Progress */
        !           142: #define BT_DIAGF       0x40    /* Diagnostic Failure */
        !           143: #define BT_INIT                0x20    /* Mbx Init required */
        !           144: #define BT_IDLE                0x10    /* Host Adapter Idle */
        !           145: #define BT_CDF         0x08    /* cmd/data out port full */
        !           146: #define BT_DF          0x04    /* Data in port full */
        !           147: #define BT_INVDCMD     0x01    /* Invalid command */
        !           148: 
        !           149: /*
        !           150:  * BT_CMD_DATA bits (write)
        !           151:  */
        !           152: 
        !           153: #define        BT_NOP                  0x00    /* No operation */
        !           154: #define BT_MBX_INIT            0x01    /* Mbx initialization */
        !           155: #define BT_START_SCSI          0x02    /* start scsi command */
        !           156: #define BT_START_BIOS          0x03    /* start bios command */
        !           157: #define BT_INQUIRE             0x04    /* Adapter Inquiry */
        !           158: #define BT_MBO_INTR_EN         0x05    /* Enable MBO available interrupt */
        !           159: #define BT_SEL_TIMEOUT_SET     0x06    /* set selection time-out */
        !           160: #define BT_BUS_ON_TIME_SET     0x07    /* set bus-on time */
        !           161: #define BT_BUS_OFF_TIME_SET    0x08    /* set bus-off time */
        !           162: #define BT_SPEED_SET           0x09    /* set transfer speed */
        !           163: #define BT_DEV_GET             0x0a    /* return installed devices */
        !           164: #define BT_CONF_GET            0x0b    /* return configuration data */
        !           165: #define BT_TARGET_EN           0x0c    /* enable target mode */
        !           166: #define BT_SETUP_GET           0x0d    /* return setup data */
        !           167: #define BT_WRITE_CH2           0x1a    /* write channel 2 buffer */
        !           168: #define BT_READ_CH2            0x1b    /* read channel 2 buffer */
        !           169: #define BT_WRITE_FIFO          0x1c    /* write fifo buffer */
        !           170: #define BT_READ_FIFO           0x1d    /* read fifo buffer */
        !           171: #define BT_ECHO                        0x1e    /* Echo command data */
        !           172: #define BT_MBX_INIT_EXTENDED   0x81    /* Mbx initialization */
        !           173: #define BT_INQUIRE_EXTENDED    0x8D    /* Adapter Setup Inquiry */
        !           174: 
        !           175: struct bt_cmd_buf {
        !           176:         u_char byte[16];       
        !           177: };
        !           178: 
        !           179: /*
        !           180:  * BT_INTR_PORT bits (read)
        !           181:  */
        !           182: 
        !           183: #define BT_ANY_INTR            0x80    /* Any interrupt */
        !           184: #define BT_SCRD                0x08    /* SCSI reset detected */
        !           185: #define BT_HACC                0x04    /* Command complete */
        !           186: #define BT_MBOA                0x02    /* MBX out empty */
        !           187: #define BT_MBIF                0x01    /* MBX in full */
        !           188: 
        !           189: /*
        !           190:  * Mail box defs 
        !           191:  */
        !           192: 
        !           193: #define BT_MBX_SIZE            16      /* mail box size */
        !           194: 
        !           195: struct bt_mbx
        !           196: {
        !           197:        struct bt_mbx_out {
        !           198:                physaddr        ccb_addr;
        !           199:                unsigned char   dummy[3];
        !           200:                unsigned char   cmd;
        !           201:        } mbo [BT_MBX_SIZE];
        !           202:        struct bt_mbx_in{
        !           203:                physaddr        ccb_addr;
        !           204:                unsigned char   btstat;
        !           205:                unsigned char   sdstat;
        !           206:                unsigned char   dummy;
        !           207:                unsigned char   stat;
        !           208:        } mbi[BT_MBX_SIZE];
        !           209: };
        !           210: 
        !           211: /*
        !           212:  * mbo.cmd values
        !           213:  */
        !           214: 
        !           215: #define BT_MBO_FREE    0x0     /* MBO entry is free */
        !           216: #define BT_MBO_START   0x1     /* MBO activate entry */
        !           217: #define BT_MBO_ABORT   0x2     /* MBO abort entry */
        !           218: 
        !           219: #define BT_MBI_FREE    0x0     /* MBI entry is free */
        !           220: #define BT_MBI_OK      0x1     /* completed without error */
        !           221: #define BT_MBI_ABORT   0x2     /* aborted ccb */
        !           222: #define BT_MBI_UNKNOWN 0x3     /* Tried to abort invalid CCB */
        !           223: #define BT_MBI_ERROR   0x4     /* Completed with error */
        !           224: 
        !           225: extern struct bt_mbx bt_mbx[];
        !           226: 
        !           227: #if    defined(BIG_DMA)
        !           228: /* #define     BT_NSEG 8192    /* Number of scatter gather segments - to much vm */
        !           229: #define        BT_NSEG 512
        !           230: #else
        !           231: #define        BT_NSEG 33
        !           232: #endif /* BIG_DMA */
        !           233: struct bt_scat_gath
        !           234:        {
        !           235:                unsigned long   seg_len;
        !           236:                physaddr        seg_addr;
        !           237:        };
        !           238: 
        !           239: struct bt_ccb {
        !           240:        unsigned char           opcode;
        !           241:        unsigned char           :3,data_in:1,data_out:1,:3;
        !           242:        unsigned char           scsi_cmd_length;
        !           243:        unsigned char           req_sense_length;
        !           244:        /*------------------------------------longword boundary */
        !           245:        unsigned long           data_length;
        !           246:        /*------------------------------------longword boundary */
        !           247:        physaddr                data_addr;
        !           248:        /*------------------------------------longword boundary */
        !           249:        unsigned char           dummy[2];
        !           250:        unsigned char           host_stat;
        !           251:        unsigned char           target_stat;
        !           252:        /*------------------------------------longword boundary */
        !           253:        unsigned char           target;
        !           254:        unsigned char           lun;
        !           255:        unsigned char           scsi_cmd[12];   /* 12 bytes (bytes only)*/
        !           256:        unsigned char           dummy2[1];
        !           257:        unsigned char           link_id;
        !           258:        /*------------------------------------4 longword boundary */
        !           259:        physaddr                link_addr;
        !           260:        /*------------------------------------longword boundary */
        !           261:        physaddr                sense_ptr;
        !           262:        /*------------------------------------longword boundary */
        !           263:        struct  scsi_sense_data scsi_sense;
        !           264:        /*------------------------------------longword boundary */
        !           265:        struct  bt_scat_gath    scat_gath[BT_NSEG];
        !           266:        /*------------------------------------longword boundary */
        !           267:        struct  bt_ccb          *next;
        !           268:        /*------------------------------------longword boundary */
        !           269:        struct  scsi_xfer       *xfer;          /* the scsi_xfer for this cmd */
        !           270:        /*------------------------------------longword boundary */
        !           271:        struct  bt_mbx_out      *mbx;           /* pointer to mail box */
        !           272:        /*------------------------------------longword boundary */
        !           273:        long    int     delta;  /* difference from previous*/
        !           274:        struct bt_ccb   *later,*sooner;
        !           275:        int             flags;
        !           276: #define        CCB_FREE        0
        !           277: #define CCB_ACTIVE     1
        !           278: #define        CCB_ABORTED     2
        !           279: };
        !           280: 
        !           281: struct bt_ccb *bt_soonest = (struct bt_ccb *)0;
        !           282: struct bt_ccb *bt_latest = (struct bt_ccb *)0;
        !           283: long int       bt_furtherest = 0;      /* longest time in the timeout queue */
        !           284: /*
        !           285:  * opcode fields
        !           286:  */
        !           287: 
        !           288: #define BT_INITIATOR_CCB       0x00    /* SCSI Initiator CCB */
        !           289: #define BT_TARGET_CCB          0x01    /* SCSI Target CCB */
        !           290: #define BT_INIT_SCAT_GATH_CCB  0x02    /* SCSI Initiator with scattter gather*/
        !           291: #define BT_RESET_CCB           0x81    /* SCSI Bus reset */
        !           292: 
        !           293: 
        !           294: /*
        !           295:  * bt_ccb.host_stat values
        !           296:  */
        !           297: 
        !           298: #define BT_OK          0x00    /* cmd ok */
        !           299: #define BT_LINK_OK     0x0a    /* Link cmd ok */
        !           300: #define BT_LINK_IT     0x0b    /* Link cmd ok + int */
        !           301: #define BT_SEL_TIMEOUT 0x11    /* Selection time out */
        !           302: #define BT_OVER_UNDER  0x12    /* Data over/under run */
        !           303: #define BT_BUS_FREE    0x13    /* Bus dropped at unexpected time */
        !           304: #define BT_INV_BUS     0x14    /* Invalid bus phase/sequence */
        !           305: #define BT_BAD_MBO     0x15    /* Incorrect MBO cmd */
        !           306: #define BT_BAD_CCB     0x16    /* Incorrect ccb opcode */
        !           307: #define BT_BAD_LINK    0x17    /* Not same values of LUN for links */
        !           308: #define BT_INV_TARGET  0x18    /* Invalid target direction */
        !           309: #define BT_CCB_DUP     0x19    /* Duplicate CCB received */
        !           310: #define BT_INV_CCB     0x1a    /* Invalid CCB or segment list */
        !           311: #define BT_ABORTED     42      /* pseudo value from driver */
        !           312: 
        !           313: 
        !           314: 
        !           315: struct bt_setup
        !           316: {
        !           317:        u_char  sync_neg:1;
        !           318:        u_char  parity:1;
        !           319:        u_char  :6;
        !           320:        u_char  speed;
        !           321:        u_char  bus_on;
        !           322:        u_char  bus_off;
        !           323:        u_char  num_mbx;
        !           324:        u_char  mbx[4];
        !           325:        struct
        !           326:        {
        !           327:                u_char  offset:4;
        !           328:                u_char  period:3;
        !           329:                u_char  valid:1;
        !           330:        }sync[8];
        !           331:        u_char  disc_sts;
        !           332: };
        !           333: 
        !           334: struct bt_config
        !           335: {
        !           336:        u_char  chan;
        !           337:        u_char  intr;
        !           338:        u_char  scsi_dev:3;
        !           339:        u_char  :5;
        !           340: };
        !           341: 
        !           342: #define INT9   0x01
        !           343: #define INT10  0x02
        !           344: #define INT11  0x04
        !           345: #define INT12  0x08
        !           346: #define INT14  0x20
        !           347: #define INT15  0x40
        !           348: 
        !           349: #define EISADMA        0x00
        !           350: #define CHAN0  0x01
        !           351: #define CHAN5  0x20
        !           352: #define CHAN6  0x40
        !           353: #define CHAN7  0x80
        !           354: 
        !           355: 
        !           356: 
        !           357: 
        !           358: #ifdef        MACH
        !           359: extern physaddr        kvtophys();
        !           360: #define PHYSTOKV(x)   phystokv(x)
        !           361: #define KVTOPHYS(x)   kvtophys(x)
        !           362: #endif MACH
        !           363: 
        !           364: #ifdef        __386BSD__
        !           365: #define PHYSTOKV(x)   (x | 0xFE000000)
        !           366: #define KVTOPHYS(x)   vtophys(x)
        !           367: #endif        __386BSD__
        !           368: 
        !           369: 
        !           370: 
        !           371: #define PAGESIZ        4096
        !           372: #define INVALIDATE_CACHE {asm volatile( ".byte 0x0F ;.byte 0x08" ); }
        !           373: 
        !           374: 
        !           375: u_char                 bt_scratch_buf[256];
        !           376: #ifdef MACH
        !           377: caddr_t                        bt_base[NBT];           /* base port for each board */
        !           378: #else  MACH
        !           379: short                  bt_base[NBT];           /* base port for each board */
        !           380: #endif MACH
        !           381: struct bt_mbx          bt_mbx[NBT];
        !           382: struct bt_ccb          *bt_ccb_free[NBT];
        !           383: struct bt_ccb          bt_ccb[NBT][BT_MBX_SIZE];
        !           384: struct scsi_xfer       bt_scsi_xfer[NBT];
        !           385: struct isa_dev         *btinfo[NBT];
        !           386: struct bt_ccb          *bt_get_ccb();
        !           387: int                    bt_int[NBT];
        !           388: int                    bt_dma[NBT];
        !           389: int                    bt_scsi_dev[NBT];
        !           390: int                    bt_initialized[NBT];
        !           391: #if defined(OSF)
        !           392: int                    bt_attached[NBT];
        !           393: #endif /* defined(OSF) */
        !           394: 
        !           395: /***********debug values *************/
        !           396: #define        BT_SHOWCCBS 0x01
        !           397: #define        BT_SHOWINTS 0x02
        !           398: #define        BT_SHOWCMDS 0x04
        !           399: #define        BT_SHOWMISC 0x08
        !           400: int    bt_debug = 0;
        !           401: 
        !           402: 
        !           403: int btprobe(), btattach();
        !           404: int btintr();
        !           405: 
        !           406: #ifdef MACH
        !           407: struct isa_driver      btdriver = { btprobe, 0, btattach, "bt", 0, 0, 0};
        !           408: int (*btintrs[])() = {btintr, 0};
        !           409: #endif MACH
        !           410: 
        !           411: #ifdef __386BSD__
        !           412: struct isa_driver      btdriver = { btprobe, btattach, "bt"};
        !           413: #endif __386BSD__
        !           414: 
        !           415: static int     btunit = 0;
        !           416: 
        !           417: #define bt_abortmbx(mbx) \
        !           418:        (mbx)->cmd = BT_MBO_ABORT; \
        !           419:        outb(BT_CMD_DATA_PORT, BT_START_SCSI);
        !           420: #define bt_startmbx(mbx) \
        !           421:        (mbx)->cmd = BT_MBO_START; \
        !           422:        outb(BT_CMD_DATA_PORT, BT_START_SCSI);
        !           423: 
        !           424: 
        !           425: 
        !           426: int    bt_scsi_cmd();
        !           427: int    bt_timeout();
        !           428: void   btminphys();
        !           429: long int bt_adapter_info();
        !           430: 
        !           431: struct scsi_switch     bt_switch =
        !           432: {
        !           433:        bt_scsi_cmd,
        !           434:        btminphys,
        !           435:        0,
        !           436:        0,
        !           437:        bt_adapter_info,
        !           438:        0,0,0
        !           439: };     
        !           440: #define BT_CMD_TIMEOUT_FUDGE 200 /* multiplied to get Secs */
        !           441: #define BT_RESET_TIMEOUT 1000000
        !           442: #define BT_SCSI_TIMEOUT_FUDGE 20 /* divided by for mSecs */
        !           443: 
        !           444: 
        !           445: /***********************************************************************\
        !           446: * bt_cmd(unit,icnt, ocnt,wait, retval, opcode, args)                   *
        !           447: * Activate Adapter command                                             *
        !           448: *      icnt:   number of args (outbound bytes written after opcode)    *
        !           449: *      ocnt:   number of expected returned bytes                       *
        !           450: *      wait:   number of seconds to wait for response                  *
        !           451: *      retval: buffer where to place returned bytes                    *
        !           452: *      opcode: opcode BT_NOP, BT_MBX_INIT, BT_START_SCSI ...           *
        !           453: *      args:   parameters                                              *
        !           454: *                                                                      *
        !           455: * Performs an adapter command through the ports. Not to be confused    *
        !           456: *      with a scsi command, which is read in via the dma               *
        !           457: * One of the adapter commands tells it to read in a scsi command       *
        !           458: \***********************************************************************/
        !           459: bt_cmd(unit,icnt, ocnt, wait,retval, opcode, args)
        !           460: 
        !           461: u_char *retval;
        !           462: unsigned opcode;
        !           463: u_char args;
        !           464: {
        !           465:        unsigned *ic = &opcode;
        !           466:        u_char oc;
        !           467:        register i;
        !           468:        int     sts;
        !           469: 
        !           470:        /*******************************************************\
        !           471:        * multiply the wait argument by a big constant          *
        !           472:        * zero defaults to 1                                    *
        !           473:        \*******************************************************/
        !           474:        if(!wait) 
        !           475:                wait = BT_CMD_TIMEOUT_FUDGE * delaycount; 
        !           476:        else
        !           477:                wait *= BT_CMD_TIMEOUT_FUDGE * delaycount; 
        !           478:        /*******************************************************\
        !           479:        * Wait for the adapter to go idle, unless it's one of   *
        !           480:        * the commands which don't need this                    *
        !           481:        \*******************************************************/
        !           482:        if (opcode != BT_MBX_INIT && opcode != BT_START_SCSI)
        !           483:        {
        !           484:                i = BT_CMD_TIMEOUT_FUDGE * delaycount; /* 1 sec?*/
        !           485:                while (--i)
        !           486:                {
        !           487:                        sts = inb(BT_CTRL_STAT_PORT);
        !           488:                        if (sts & BT_IDLE)
        !           489:                        {
        !           490:                                break;
        !           491:                        }
        !           492:                }
        !           493:                if (!i)
        !           494:                {
        !           495:                        printf("bt_cmd: bt742a host not idle(0x%x)\n",sts);
        !           496:                        return(ENXIO);
        !           497:                }
        !           498:        }
        !           499:        /*******************************************************\
        !           500:        * Now that it is idle, if we expect output, preflush the*
        !           501:        * queue feeding to us.                                  *
        !           502:        \*******************************************************/
        !           503:        if (ocnt)
        !           504:        {
        !           505:                while((inb(BT_CTRL_STAT_PORT)) & BT_DF)
        !           506:                        inb(BT_CMD_DATA_PORT);
        !           507:        }
        !           508:                        
        !           509:        /*******************************************************\
        !           510:        * Output the command and the number of arguments given  *
        !           511:        * for each byte, first check the port is empty.         *
        !           512:        \*******************************************************/
        !           513:        icnt++;         /* include the command */
        !           514:        while (icnt--)
        !           515:        {
        !           516:                sts = inb(BT_CTRL_STAT_PORT);
        !           517:                for (i=0; i< wait; i++)
        !           518:                {
        !           519:                        sts = inb(BT_CTRL_STAT_PORT);
        !           520:                        if (!(sts & BT_CDF))
        !           521:                                break;
        !           522:                }
        !           523:                if (i >=  wait)
        !           524:                {
        !           525:                        printf("bt_cmd: bt742a cmd/data port full\n");
        !           526:                        outb(BT_CTRL_STAT_PORT, BT_SRST); 
        !           527:                        return(ENXIO);
        !           528:                }
        !           529:                outb(BT_CMD_DATA_PORT, (u_char)(*ic++));
        !           530:        }
        !           531:        /*******************************************************\
        !           532:        * If we expect input, loop that many times, each time,  *
        !           533:        * looking for the data register to have valid data      *
        !           534:        \*******************************************************/
        !           535:        while (ocnt--)
        !           536:        {
        !           537:                sts = inb(BT_CTRL_STAT_PORT);
        !           538:                for (i=0; i< wait; i++)
        !           539:                {
        !           540:                        sts = inb(BT_CTRL_STAT_PORT);
        !           541:                        if (sts  & BT_DF)
        !           542:                                break;
        !           543:                }
        !           544:                if (i >=  wait)
        !           545:                {
        !           546:                        printf("bt_cmd: bt742a cmd/data port empty %d\n",ocnt);
        !           547:                        return(ENXIO);
        !           548:                }
        !           549:                oc = inb(BT_CMD_DATA_PORT);
        !           550:                if (retval)
        !           551:                        *retval++ = oc;
        !           552:        }
        !           553:        /*******************************************************\
        !           554:        * Wait for the board to report a finised instruction    *
        !           555:        \*******************************************************/
        !           556:        i=BT_CMD_TIMEOUT_FUDGE * delaycount;    /* 1 sec? */
        !           557:        while (--i)
        !           558:        {
        !           559:                sts = inb(BT_INTR_PORT);
        !           560:                if (sts & BT_HACC)
        !           561:                {
        !           562:                        break;
        !           563:                }
        !           564:        }
        !           565:        if (!i)
        !           566:        {
        !           567:                printf("bt_cmd: bt742a host not finished(0x%x)\n",sts);
        !           568:                return(ENXIO);
        !           569:        }
        !           570:        outb(BT_CTRL_STAT_PORT, BT_IRST);
        !           571:        return(0);
        !           572: }
        !           573: 
        !           574: /*******************************************************\
        !           575: * Check if the device can be found at the port given   *
        !           576: * and if so, set it up ready for further work          *
        !           577: * as an argument, takes the isa_dev structure from     *
        !           578: * autoconf.c                                           *
        !           579: \*******************************************************/
        !           580: 
        !           581: btprobe(dev)
        !           582: struct isa_dev *dev;
        !           583: {
        !           584:        /***********************************************\
        !           585:        * find unit and check we have that many defined *
        !           586:        \***********************************************/
        !           587:        int     unit = btunit;
        !           588: #if defined(OSF)
        !           589:        static ihandler_t bt_handler[NBT];
        !           590:        static ihandler_id_t *bt_handler_id[NBT];
        !           591:        register ihandler_t *chp = &bt_handler[unit];;
        !           592: #endif /* defined(OSF) */
        !           593: 
        !           594:        dev->dev_unit = unit;
        !           595:        bt_base[unit] = dev->dev_addr;
        !           596:        if(unit >= NBT) 
        !           597:        {
        !           598:                printf("bt: unit number (%d) too high\n",unit);
        !           599:                return(0);
        !           600:        }
        !           601:        /***********************************************\
        !           602:        * Try initialise a unit at this location        *
        !           603:        * sets up dma and bus speed, loads bt_int[unit]*
        !           604:        \***********************************************/
        !           605:        if (bt_init(unit) != 0)
        !           606:        {
        !           607:                return(0);
        !           608:        }
        !           609: 
        !           610:        /***********************************************\
        !           611:        * If it's there, put in it's interrupt vectors  *
        !           612:        \***********************************************/
        !           613: #ifdef MACH
        !           614: #if defined(OSF)                               /* OSF */
        !           615:        chp->ih_level = dev->dev_pic;
        !           616:        chp->ih_handler = dev->dev_intr[0];
        !           617:        chp->ih_resolver = i386_resolver;
        !           618:        chp->ih_rdev = dev;
        !           619:        chp->ih_stats.intr_type = INTR_DEVICE;
        !           620:        chp->ih_stats.intr_cnt = 0;
        !           621:        chp->ih_hparam[0].intparam = unit;
        !           622:        if ((bt_handler_id[unit] = handler_add(chp)) != NULL)
        !           623:                handler_enable(bt_handler_id[unit]);
        !           624:        else
        !           625:                panic("Unable to add bt interrupt handler");
        !           626: #else                                          /* CMU */
        !           627:        dev->dev_pic = bt_int[unit];
        !           628:        take_dev_irq(dev);
        !           629: #endif /* !defined(OSF) */
        !           630:        printf("port=%x spl=%d\n", dev->dev_addr, dev->dev_spl);
        !           631: #endif MACH
        !           632: #ifdef  __386BSD__                             /* 386BSD */
        !           633:         dev->id_irq = (1 << bt_int[unit]);
        !           634:         dev->id_drq = bt_dma[unit];
        !           635:        printf("\n  **");
        !           636: #endif  __386BSD__
        !           637: 
        !           638:        btunit++;
        !           639:        return(1);
        !           640: }
        !           641: 
        !           642: /***********************************************\
        !           643: * Attach all the sub-devices we can find       *
        !           644: \***********************************************/
        !           645: btattach(dev)
        !           646: struct isa_dev *dev;
        !           647: {
        !           648:        int     unit = dev->dev_unit;
        !           649: 
        !           650: 
        !           651: #ifdef  __386BSD__
        !           652:        printf(" probing for scsi devices**\n");
        !           653: #endif  __386BSD__
        !           654: 
        !           655:        /***********************************************\
        !           656:        * ask the adapter what subunits are present     *
        !           657:        \***********************************************/
        !           658:        scsi_attachdevs( unit, bt_scsi_dev[unit], &bt_switch);
        !           659: #if defined(OSF)
        !           660:        bt_attached[unit]=1;
        !           661: #endif /* defined(OSF) */
        !           662:        if(!unit) /* only one for all boards */
        !           663:        {
        !           664:                bt_timeout(0);
        !           665:        }
        !           666: #ifdef  __386BSD__
        !           667:        printf("bt%d",unit);
        !           668: #endif  __386BSD__
        !           669:        return;
        !           670: }
        !           671: 
        !           672: /***********************************************\
        !           673: * Return some information to the caller about   *
        !           674: * the adapter and it's capabilities             *
        !           675: \***********************************************/
        !           676: long int bt_adapter_info(unit)
        !           677: int    unit;
        !           678: {
        !           679:        return(2);      /* 2 outstanding requests at a time per device */
        !           680: }
        !           681: 
        !           682: /***********************************************\
        !           683: * Catch an interrupt from the adaptor          *
        !           684: \***********************************************/
        !           685: btintr(unit)
        !           686: {
        !           687:        struct bt_ccb *ccb;
        !           688:        unsigned char stat;
        !           689:        register i;
        !           690: 
        !           691:        if(scsi_debug & PRINTROUTINES)
        !           692:                printf("btintr ");
        !           693:        /***********************************************\
        !           694:        * First acknowlege the interrupt, Then if it's  *
        !           695:        * not telling about a completed operation       *
        !           696:        * just return.                                  *
        !           697:        \***********************************************/
        !           698:        stat = inb(BT_INTR_PORT);
        !           699:        outb(BT_CTRL_STAT_PORT, BT_IRST);
        !           700:        if(scsi_debug & TRACEINTERRUPTS)
        !           701:                printf("int = 0x%x ",stat);
        !           702:        if (! (stat & BT_MBIF))
        !           703:                return 1;
        !           704:        if(scsi_debug & TRACEINTERRUPTS)
        !           705:                printf("mbxi ");
        !           706: #if defined(OSF)
        !           707:        if (!bt_attached[unit])
        !           708:        {
        !           709:                return(1);
        !           710:        }
        !           711: #endif /* defined(OSF) */
        !           712:        /***********************************************\
        !           713:        * If it IS then process the competed operation  *
        !           714:        \***********************************************/
        !           715:        for (i = 0; i < BT_MBX_SIZE; i++)
        !           716:        {
        !           717:                if (bt_mbx[unit].mbi[i].stat != BT_MBI_FREE)
        !           718:                {
        !           719:                        ccb = (struct bt_ccb *)PHYSTOKV(
        !           720:                                        (bt_mbx[unit].mbi[i].ccb_addr));
        !           721:                        if((bt_debug & BT_SHOWCCBS) && ccb)
        !           722:                                printf("<int ccb(%x)>",ccb);
        !           723:                        if((stat =  bt_mbx[unit].mbi[i].stat) != BT_MBI_OK)
        !           724:                        {
        !           725:                                switch(stat)
        !           726:                                {
        !           727:                                case    BT_MBI_ABORT:
        !           728:                                        if(bt_debug & BT_SHOWMISC)
        !           729:                                                printf("abort ");
        !           730:                                        ccb->host_stat = BT_ABORTED;
        !           731:                                        break;
        !           732: 
        !           733:                                case    BT_MBI_UNKNOWN:
        !           734:                                        ccb = (struct bt_ccb *)0;
        !           735:                                        if(bt_debug & BT_SHOWMISC)
        !           736:                                                printf("unknown ccb for abort");
        !           737:                                        break;
        !           738: 
        !           739:                                case    BT_MBI_ERROR:
        !           740:                                        break;
        !           741: 
        !           742:                                default:
        !           743:                                        panic("Impossible mbxi status");
        !           744: 
        !           745:                                }
        !           746:                                if((bt_debug & BT_SHOWCMDS ) && ccb)
        !           747:                                {
        !           748:                                        u_char  *cp;
        !           749:                                        cp = ccb->scsi_cmd;
        !           750:                                        printf("op=%x %x %x %x %x %x\n", 
        !           751:                                                cp[0], cp[1], cp[2],
        !           752:                                                cp[3], cp[4], cp[5]);
        !           753:                                        printf("stat %x for mbi[%d]\n"
        !           754:                                                , bt_mbx[unit].mbi[i].stat, i);
        !           755:                                        printf("addr = 0x%x\n", ccb);
        !           756:                                }
        !           757:                        }
        !           758:                        if(ccb)
        !           759:                        {
        !           760:                                bt_remove_timeout(ccb);
        !           761:                                bt_done(unit,ccb);
        !           762:                        }
        !           763:                        bt_mbx[unit].mbi[i].stat = BT_MBI_FREE;
        !           764:                }
        !           765:        }
        !           766:        return(1);
        !           767: }
        !           768: 
        !           769: /***********************************************\
        !           770: * A ccb (and hence a mbx-out is put onto the   *
        !           771: * free list.                                   *
        !           772: \***********************************************/
        !           773: bt_free_ccb(unit,ccb, flags)
        !           774: struct bt_ccb *ccb;
        !           775: {
        !           776:        unsigned int opri;
        !           777:        
        !           778:        if(scsi_debug & PRINTROUTINES)
        !           779:                printf("ccb%d(0x%x)> ",unit,flags);
        !           780:        if (!(flags & SCSI_NOMASK)) 
        !           781:                opri = splbio();
        !           782: 
        !           783:        ccb->next = bt_ccb_free[unit];
        !           784:        bt_ccb_free[unit] = ccb;
        !           785:        ccb->flags = CCB_FREE;
        !           786:        /***********************************************\
        !           787:        * If there were none, wake abybody waiting for  *
        !           788:        * one to come free, starting with queued entries*
        !           789:        \***********************************************/
        !           790:        if (!ccb->next) {
        !           791:                wakeup(&bt_ccb_free[unit]);
        !           792:        }
        !           793:        if (!(flags & SCSI_NOMASK)) 
        !           794:                splx(opri);
        !           795: }
        !           796: 
        !           797: /***********************************************\
        !           798: * Get a free ccb (and hence mbox-out entry)    *
        !           799: \***********************************************/
        !           800: struct bt_ccb *
        !           801: bt_get_ccb(unit,flags)
        !           802: {
        !           803:        unsigned opri;
        !           804:        struct bt_ccb *rc;
        !           805: 
        !           806:        if(scsi_debug & PRINTROUTINES)
        !           807:                printf("<ccb%d(0x%x) ",unit,flags);
        !           808:        if (!(flags & SCSI_NOMASK)) 
        !           809:                opri = splbio();
        !           810:        /***********************************************\
        !           811:        * If we can and have to, sleep waiting for one  *
        !           812:        * to come free                                  *
        !           813:        \***********************************************/
        !           814:        while ((!(rc = bt_ccb_free[unit])) && (!(flags & SCSI_NOSLEEP)))
        !           815:        {
        !           816:                sleep(&bt_ccb_free[unit], PRIBIO);
        !           817:        }
        !           818:        if (rc) 
        !           819:        {
        !           820:                bt_ccb_free[unit] = rc->next;
        !           821:                rc->flags = CCB_ACTIVE;
        !           822:        }
        !           823:        if (!(flags & SCSI_NOMASK)) 
        !           824:                splx(opri);
        !           825:        return(rc);
        !           826: }
        !           827:                
        !           828: 
        !           829: /***********************************************\
        !           830: * We have a ccb which has been processed by the        *
        !           831: * adaptor, now we look to see how the operation        *
        !           832: * went. Wake up the owner if waiting           *
        !           833: \***********************************************/
        !           834: bt_done(unit,ccb)
        !           835: struct bt_ccb *ccb;
        !           836: {
        !           837:        struct  scsi_sense_data *s1,*s2;
        !           838:        struct  scsi_xfer *xs = ccb->xfer;
        !           839: 
        !           840:        if(scsi_debug & (PRINTROUTINES | TRACEINTERRUPTS))
        !           841:                printf("bt_done ");
        !           842:        /***********************************************\
        !           843:        * Otherwise, put the results of the operation   *
        !           844:        * into the xfer and call whoever started it     *
        !           845:        \***********************************************/
        !           846:        if (    (       ccb->host_stat != BT_OK 
        !           847:                        || ccb->target_stat != SCSI_OK)
        !           848:              && (!(xs->flags & SCSI_ERR_OK)))
        !           849:        {
        !           850: 
        !           851:                s1 = &(ccb->scsi_sense);
        !           852:                s2 = &(xs->sense);
        !           853: 
        !           854:                if(ccb->host_stat)
        !           855:                {
        !           856:                        switch(ccb->host_stat)
        !           857:                        {
        !           858:                        case    BT_ABORTED:     /* No response */
        !           859:                        case    BT_SEL_TIMEOUT: /* No response */
        !           860:                                if (bt_debug & BT_SHOWMISC)
        !           861:                                {
        !           862:                                        printf("timeout reported back\n");
        !           863:                                }
        !           864:                                xs->error = XS_TIMEOUT;
        !           865:                                break;
        !           866:                        default:        /* Other scsi protocol messes */
        !           867:                                xs->error = XS_DRIVER_STUFFUP;
        !           868:                                if (bt_debug & BT_SHOWMISC)
        !           869:                                {
        !           870:                                        printf("unexpected host_stat: %x\n",
        !           871:                                                ccb->host_stat);
        !           872:                                }
        !           873:                        }
        !           874: 
        !           875:                }
        !           876:                else
        !           877:                {
        !           878:                        switch(ccb->target_stat)
        !           879:                        {
        !           880:                        case 0x02:
        !           881:                                /* structure copy!!!!!*/
        !           882:                                *s2=*s1;
        !           883:                                xs->error = XS_SENSE;
        !           884:                                break;
        !           885:                        case 0x08:
        !           886:                                xs->error = XS_BUSY;
        !           887:                                break;
        !           888:                        default:
        !           889:                                if (bt_debug & BT_SHOWMISC)
        !           890:                                {
        !           891:                                        printf("unexpected target_stat: %x\n",
        !           892:                                                ccb->target_stat);
        !           893:                                }
        !           894:                                xs->error = XS_DRIVER_STUFFUP;
        !           895:                        }
        !           896:                }
        !           897:        }
        !           898:        else            /* All went correctly  OR errors expected */
        !           899:        {
        !           900:                xs->resid = 0;
        !           901:        }
        !           902:        xs->flags |= ITSDONE;
        !           903:        bt_free_ccb(unit,ccb, xs->flags);
        !           904:        if(xs->when_done)
        !           905:                (*(xs->when_done))(xs->done_arg,xs->done_arg2);
        !           906: }
        !           907: 
        !           908: /***********************************************\
        !           909: * Start the board, ready for normal operation  *
        !           910: \***********************************************/
        !           911: bt_init(unit)
        !           912: int    unit;
        !           913: {
        !           914:        unsigned char ad[4];
        !           915:        volatile int i,sts;
        !           916:        struct  bt_config conf;
        !           917: 
        !           918:        /***********************************************\
        !           919:        * reset board, If it doesn't respond, assume    *
        !           920:        * that it's not there.. good for the probe      *
        !           921:        \***********************************************/
        !           922: 
        !           923:        outb(BT_CTRL_STAT_PORT, BT_HRST|BT_SRST);
        !           924: 
        !           925:        for (i=0; i < BT_RESET_TIMEOUT; i++)
        !           926:        {
        !           927:                sts = inb(BT_CTRL_STAT_PORT) ;
        !           928:                if ( sts == (BT_IDLE | BT_INIT))
        !           929:                        break;
        !           930:        }
        !           931:        if (i >= BT_RESET_TIMEOUT)
        !           932:        {
        !           933:                if (bt_debug & BT_SHOWMISC)
        !           934:                        printf("bt_init: No answer from bt742a board\n");
        !           935:                return(ENXIO);
        !           936:        }
        !           937: 
        !           938:        /***********************************************\
        !           939:        * Assume we have a board at this stage          *
        !           940:        * setup dma channel from jumpers and save int   *
        !           941:        * level                                         *
        !           942:        \***********************************************/
        !           943: #ifdef __386BSD__
        !           944:        printf("bt%d reading board settings, ",unit);
        !           945: #define        PRNT(x)
        !           946: #else  __386BSD__
        !           947:        printf("bt%d:",unit);
        !           948: #define        PRNT(x) printf(x)
        !           949: #endif __386BSD__
        !           950: 
        !           951:        bt_cmd(unit,0, sizeof(conf), 0 ,&conf, BT_CONF_GET);
        !           952:        switch(conf.chan)
        !           953:        {
        !           954:        case    EISADMA:
        !           955:                bt_dma[unit] = -1;
        !           956:                PRNT("eisa dma ");
        !           957:                break;
        !           958:        case    CHAN0:
        !           959:                outb(0x0b, 0x0c);
        !           960:                outb(0x0a, 0x00);
        !           961:                bt_dma[unit] = 0;
        !           962:                PRNT("dma=0 ");
        !           963:                break;
        !           964:        case    CHAN5:
        !           965:                outb(0xd6, 0xc1);
        !           966:                outb(0xd4, 0x01);
        !           967:                bt_dma[unit] = 5;
        !           968:                PRNT("dma=5 ");
        !           969:                break;
        !           970:        case    CHAN6:
        !           971:                outb(0xd6, 0xc2);
        !           972:                outb(0xd4, 0x02);
        !           973:                bt_dma[unit] = 6;
        !           974:                PRNT("dma=6 ");
        !           975:                break;
        !           976:        case    CHAN7:
        !           977:                outb(0xd6, 0xc3);
        !           978:                outb(0xd4, 0x03);
        !           979:                bt_dma[unit] = 7;
        !           980:                PRNT("dma=7 ");
        !           981:                break;
        !           982:        default:
        !           983:                printf("illegal dma setting %x\n",conf.chan);
        !           984:                return(EIO);
        !           985:        }
        !           986:        switch(conf.intr)
        !           987:        {
        !           988:        case    INT9:
        !           989:                bt_int[unit] = 9;
        !           990:                PRNT("int=9 ");
        !           991:                break;
        !           992:        case    INT10:
        !           993:                bt_int[unit] = 10;
        !           994:                PRNT("int=10 ");
        !           995:                break;
        !           996:        case    INT11:
        !           997:                bt_int[unit] = 11;
        !           998:                PRNT("int=11 ");
        !           999:                break;
        !          1000:        case    INT12:
        !          1001:                bt_int[unit] = 12;
        !          1002:                PRNT("int=12 ");
        !          1003:                break;
        !          1004:        case    INT14:
        !          1005:                bt_int[unit] = 14;
        !          1006:                PRNT("int=14 ");
        !          1007:                break;
        !          1008:        case    INT15:
        !          1009:                bt_int[unit] = 15;
        !          1010:                PRNT("int=15 ");
        !          1011:                break;
        !          1012:        default:
        !          1013:                printf("illegal int setting\n");
        !          1014:                return(EIO);
        !          1015:        }
        !          1016:        /* who are we on the scsi bus */
        !          1017:        bt_scsi_dev[unit] = conf.scsi_dev;
        !          1018:        /***********************************************\
        !          1019:        * Initialize mail box                           *
        !          1020:        \***********************************************/
        !          1021: 
        !          1022:        *((physaddr *)ad) = KVTOPHYS(&bt_mbx[unit]);
        !          1023:        bt_cmd(unit,5, 0, 0, 0, BT_MBX_INIT_EXTENDED
        !          1024:                , BT_MBX_SIZE
        !          1025:                , ad[0]
        !          1026:                , ad[1]
        !          1027:                , ad[2] 
        !          1028:                , ad[3]);
        !          1029: 
        !          1030:        /***********************************************\
        !          1031:        * link the ccb's with the mbox-out entries and  *
        !          1032:        * into a free-list                              *
        !          1033:        \***********************************************/
        !          1034:        for (i=0; i < BT_MBX_SIZE; i++) {
        !          1035:                bt_ccb[unit][i].next = bt_ccb_free[unit];
        !          1036:                bt_ccb_free[unit] = &bt_ccb[unit][i];
        !          1037:                bt_ccb_free[unit]->flags = CCB_FREE;
        !          1038:                bt_ccb_free[unit]->mbx = &bt_mbx[unit].mbo[i];
        !          1039:                bt_mbx[unit].mbo[i].ccb_addr = KVTOPHYS(bt_ccb_free[unit]) ;
        !          1040:        }
        !          1041: 
        !          1042:        /***********************************************\
        !          1043:        * Note that we are going and return (to probe)  *
        !          1044:        \***********************************************/
        !          1045:        bt_initialized[unit]++;
        !          1046:        return( 0 );
        !          1047: }
        !          1048: 
        !          1049: 
        !          1050: #ifndef        min
        !          1051: #define min(x,y) (x < y ? x : y)
        !          1052: #endif min
        !          1053: 
        !          1054: 
        !          1055: void btminphys(bp)
        !          1056: struct buf *bp;
        !          1057: {
        !          1058: #ifdef MACH
        !          1059: #if    !defined(OSF)
        !          1060:        bp->b_flags |= B_NPAGES;                /* can support scat/gather */
        !          1061: #endif /* defined(OSF) */
        !          1062: #endif MACH
        !          1063:        if(bp->b_bcount > ((BT_NSEG-1) * PAGESIZ))
        !          1064:        {
        !          1065:                bp->b_bcount = ((BT_NSEG-1) * PAGESIZ);
        !          1066:        }
        !          1067: }
        !          1068:        
        !          1069: /***********************************************\
        !          1070: * start a scsi operation given the command and *
        !          1071: * the data address. Also needs the unit, target        *
        !          1072: * and lu                                       *
        !          1073: \***********************************************/
        !          1074: int    bt_scsi_cmd(xs)
        !          1075: struct scsi_xfer *xs;
        !          1076: {
        !          1077:        struct  scsi_sense_data *s1,*s2;
        !          1078:        struct bt_ccb *ccb;
        !          1079:        struct bt_scat_gath *sg;
        !          1080:        int     seg;    /* scatter gather seg being worked on */
        !          1081:        int i   = 0;
        !          1082:        int rc  =  0;
        !          1083:        int     thiskv;
        !          1084:        physaddr        thisphys,nextphys;
        !          1085:        int     unit =xs->adapter;
        !          1086:        int     bytes_this_seg,bytes_this_page,datalen,flags;
        !          1087:        struct  iovec   *iovp;
        !          1088: 
        !          1089:        if(scsi_debug & PRINTROUTINES)
        !          1090:                printf("bt_scsi_cmd ");
        !          1091:        /***********************************************\
        !          1092:        * get a ccb (mbox-out) to use. If the transfer  *
        !          1093:        * is from a buf (possibly from interrupt time)  *
        !          1094:        * then we can't allow it to sleep               *
        !          1095:        \***********************************************/
        !          1096:        flags = xs->flags;
        !          1097:        if(xs->bp) flags |= (SCSI_NOSLEEP); /* just to be sure */
        !          1098:        if(flags & ITSDONE)
        !          1099:        {
        !          1100:                printf("Already done?");
        !          1101:                xs->flags &= ~ITSDONE;
        !          1102:        }
        !          1103:        if(!(flags & INUSE))
        !          1104:        {
        !          1105:                printf("Not in use?");
        !          1106:                xs->flags |= INUSE;
        !          1107:        }
        !          1108:        if (!(ccb = bt_get_ccb(unit,flags)))
        !          1109:        {
        !          1110:                xs->error = XS_DRIVER_STUFFUP;
        !          1111:                return(TRY_AGAIN_LATER);
        !          1112:        }
        !          1113: 
        !          1114:        if(bt_debug & BT_SHOWCCBS)
        !          1115:                                printf("<start ccb(%x)>",ccb);
        !          1116:        if (ccb->mbx->cmd != BT_MBO_FREE)
        !          1117:                printf("MBO not free\n");
        !          1118: 
        !          1119:        /***********************************************\
        !          1120:        * Put all the arguments for the xfer in the ccb *
        !          1121:        \***********************************************/
        !          1122:        ccb->xfer               =       xs;
        !          1123:        if(flags & SCSI_RESET)
        !          1124:        {
        !          1125:                ccb->opcode     =       BT_RESET_CCB;
        !          1126:        }
        !          1127:        else
        !          1128:        {
        !          1129:                /* can't use S/G if zero length */
        !          1130:                ccb->opcode     =       (xs->datalen?
        !          1131:                                                BT_INIT_SCAT_GATH_CCB
        !          1132:                                                :BT_INITIATOR_CCB);
        !          1133:        }
        !          1134:        ccb->target             =       xs->targ;;
        !          1135:        ccb->data_out           =       0;
        !          1136:        ccb->data_in            =       0;
        !          1137:        ccb->lun                =       xs->lu;
        !          1138:        ccb->scsi_cmd_length    =       xs->cmdlen;
        !          1139:        ccb->sense_ptr          =       KVTOPHYS(&(ccb->scsi_sense));
        !          1140:        ccb->req_sense_length   =       sizeof(ccb->scsi_sense);
        !          1141: 
        !          1142:        if((xs->datalen) && (!(flags & SCSI_RESET)))
        !          1143:        { /* can use S/G only if not zero length */
        !          1144:                ccb->data_addr = KVTOPHYS(ccb->scat_gath);
        !          1145:                sg              =       ccb->scat_gath ;
        !          1146:                seg             =       0;
        !          1147:                if(flags & SCSI_DATA_UIO)
        !          1148:                {
        !          1149:                        iovp = ((struct uio *)xs->data)->uio_iov;
        !          1150:                        datalen = ((struct uio *)xs->data)->uio_iovcnt;
        !          1151:                        xs->datalen = 0;
        !          1152:                        while ((datalen) && (seg < BT_NSEG))
        !          1153:                        {
        !          1154:                                sg->seg_addr = (physaddr)iovp->iov_base;
        !          1155:                                xs->datalen += sg->seg_len = iovp->iov_len;     
        !          1156:                                if(scsi_debug & SHOWSCATGATH)
        !          1157:                                        printf("(0x%x@0x%x)"
        !          1158:                                                        ,iovp->iov_len
        !          1159:                                                        ,iovp->iov_base);
        !          1160:                                sg++;
        !          1161:                                iovp++;
        !          1162:                                seg++;
        !          1163:                                datalen--;
        !          1164:                        }
        !          1165:                }
        !          1166:                else
        !          1167:                {
        !          1168:                        /***********************************************\
        !          1169:                        * Set up the scatter gather block               *
        !          1170:                        \***********************************************/
        !          1171:                
        !          1172:                        if(scsi_debug & SHOWSCATGATH)
        !          1173:                                printf("%d @0x%x:- ",xs->datalen,xs->data);
        !          1174:                        datalen         =       xs->datalen;
        !          1175:                        thiskv          =       (int)xs->data;
        !          1176:                        thisphys        =       KVTOPHYS(thiskv);
        !          1177:                
        !          1178:                        while ((datalen) && (seg < BT_NSEG))
        !          1179:                        {
        !          1180:                                bytes_this_seg  = 0;
        !          1181:        
        !          1182:                                /* put in the base address */
        !          1183:                                sg->seg_addr = thisphys;
        !          1184:                
        !          1185:                                if(scsi_debug & SHOWSCATGATH)
        !          1186:                                        printf("0x%x",thisphys);
        !          1187:        
        !          1188:                                /* do it at least once */
        !          1189:                                nextphys = thisphys;    
        !          1190:                                while ((datalen) && (thisphys == nextphys))
        !          1191:                                /*********************************************\
        !          1192:                                * This page is contiguous (physically) with   *
        !          1193:                                * the the last, just extend the length        *
        !          1194:                                \*********************************************/
        !          1195:                                {
        !          1196:                                        /* how far to the end of the page */
        !          1197:                                        nextphys= (thisphys & (~(PAGESIZ - 1)))
        !          1198:                                                                + PAGESIZ;
        !          1199:                                        bytes_this_page = nextphys - thisphys;
        !          1200:                                        /**** or the data ****/
        !          1201:                                        bytes_this_page = min(bytes_this_page
        !          1202:                                                                ,datalen);
        !          1203:                                        bytes_this_seg  += bytes_this_page;
        !          1204:                                        datalen         -= bytes_this_page;
        !          1205:                
        !          1206:                                        /* get more ready for the next page */
        !          1207:                                        thiskv  = (thiskv & (~(PAGESIZ - 1)))
        !          1208:                                                                + PAGESIZ;
        !          1209:                                        if(datalen)
        !          1210:                                                thisphys = KVTOPHYS(thiskv);
        !          1211:                                }
        !          1212:                                /********************************************\
        !          1213:                                * next page isn't contiguous, finish the seg *
        !          1214:                                \********************************************/
        !          1215:                                if(scsi_debug & SHOWSCATGATH)
        !          1216:                                        printf("(0x%x)",bytes_this_seg);
        !          1217:                                sg->seg_len = bytes_this_seg;   
        !          1218:                                sg++;
        !          1219:                                seg++;
        !          1220:                        }
        !          1221:                } /*end of iov/kv decision */
        !          1222:                ccb->data_length = seg * sizeof(struct bt_scat_gath);
        !          1223:                if(scsi_debug & SHOWSCATGATH)
        !          1224:                        printf("\n");
        !          1225:                if (datalen)
        !          1226:                { /* there's still data, must have run out of segs! */
        !          1227:                        printf("bt_scsi_cmd%d: more than %d DMA segs\n",
        !          1228:                                unit,BT_NSEG);
        !          1229:                        xs->error = XS_DRIVER_STUFFUP;
        !          1230:                        bt_free_ccb(unit,ccb,flags);
        !          1231:                        return(HAD_ERROR);
        !          1232:                }
        !          1233: 
        !          1234:        }
        !          1235:        else
        !          1236:        {       /* No data xfer, use non S/G values */
        !          1237:                ccb->data_addr = (physaddr)0;
        !          1238:                ccb->data_length = 0;
        !          1239:        }
        !          1240:        ccb->link_id = 0;
        !          1241:        ccb->link_addr = (physaddr)0;
        !          1242:        /***********************************************\
        !          1243:        * Put the scsi command in the ccb and start it  *
        !          1244:        \***********************************************/
        !          1245:        if(!(flags & SCSI_RESET))
        !          1246:        {
        !          1247:                bcopy(xs->cmd, ccb->scsi_cmd, ccb->scsi_cmd_length);
        !          1248:        }
        !          1249:        if(scsi_debug & SHOWCOMMANDS)
        !          1250:        {
        !          1251:                u_char  *b = ccb->scsi_cmd;
        !          1252:                if(!(flags & SCSI_RESET))
        !          1253:                {
        !          1254:                        int i = 0;
        !          1255:                        printf("bt%d:%d:%d-"
        !          1256:                                ,unit
        !          1257:                                ,ccb->target
        !          1258:                                ,ccb->lun);
        !          1259:                        while(i < ccb->scsi_cmd_length )
        !          1260:                        {
        !          1261:                                if(i) printf(",");
        !          1262:                                printf("%x",b[i++]);
        !          1263:                        }
        !          1264:                        printf("-\n");
        !          1265:                }
        !          1266:                else
        !          1267:                {
        !          1268:                        printf("bt%d:%d:%d-RESET- " 
        !          1269:                                ,unit 
        !          1270:                                ,ccb->target
        !          1271:                                ,ccb->lun
        !          1272:                        );
        !          1273:                }
        !          1274:        }
        !          1275:        bt_startmbx(ccb->mbx);
        !          1276:        /***********************************************\
        !          1277:        * Usually return SUCCESSFULLY QUEUED            *
        !          1278:        \***********************************************/
        !          1279:        if(scsi_debug & TRACEINTERRUPTS)
        !          1280:                printf("cmd_sent ");
        !          1281:        if (!(flags & SCSI_NOMASK))
        !          1282:        {
        !          1283:                bt_add_timeout(ccb,xs->timeout);
        !          1284:                return(SUCCESSFULLY_QUEUED);
        !          1285:        }
        !          1286:        /***********************************************\
        !          1287:        * If we can't use interrupts, poll on completion*
        !          1288:        \***********************************************/
        !          1289:        {
        !          1290:                int done = 0;
        !          1291:                int count = delaycount * xs->timeout / BT_SCSI_TIMEOUT_FUDGE;
        !          1292:                if(scsi_debug & TRACEINTERRUPTS)
        !          1293:                        printf("wait ");
        !          1294:                while((!done) && count)
        !          1295:                {
        !          1296:                        i=0;
        !          1297:                        while ( (!done) && i<BT_MBX_SIZE)
        !          1298:                        {
        !          1299:                                if ((bt_mbx[unit].mbi[i].stat != BT_MBI_FREE )
        !          1300:                                   && (PHYSTOKV(bt_mbx[unit].mbi[i].ccb_addr)
        !          1301:                                        == (int)ccb))
        !          1302:                                {
        !          1303:                                        bt_mbx[unit].mbi[i].stat = BT_MBI_FREE;
        !          1304:                                        bt_done(unit,ccb);
        !          1305:                                        done++;
        !          1306:                                }
        !          1307:                                i++;
        !          1308:                        }
        !          1309:                        count--;
        !          1310:                }
        !          1311:                if (!count)
        !          1312:                {
        !          1313:                        if (!(xs->flags & SCSI_SILENT))
        !          1314:                                printf("cmd fail\n");
        !          1315:                        bt_abortmbx(ccb->mbx);
        !          1316:                        count = delaycount * 2000 / BT_SCSI_TIMEOUT_FUDGE;
        !          1317:                        while((!done) && count)
        !          1318:                        {
        !          1319:                                i=0;
        !          1320:                                while ( (!done) && i<BT_MBX_SIZE)
        !          1321:                                {
        !          1322:                                        if ((bt_mbx[unit].mbi[i].stat != BT_MBI_FREE )
        !          1323:                                        && (PHYSTOKV((bt_mbx[unit].mbi[i].ccb_addr)
        !          1324:                                                == (int)ccb)))
        !          1325:                                        {
        !          1326:                                                bt_mbx[unit].mbi[i].stat = BT_MBI_FREE;
        !          1327:                                                bt_done(unit,ccb);
        !          1328:                                                done++;
        !          1329:                                        }
        !          1330:                                        i++;
        !          1331:                                }
        !          1332:                                count--;
        !          1333:                        }
        !          1334:                        if(!count)
        !          1335:                        {
        !          1336:                                printf("abort failed in wait\n");
        !          1337:                                ccb->mbx->cmd = BT_MBO_FREE;
        !          1338:                        }
        !          1339:                        bt_free_ccb(unit,ccb,flags);
        !          1340:                        btintr(unit);
        !          1341:                        xs->error = XS_DRIVER_STUFFUP;
        !          1342:                        return(HAD_ERROR);
        !          1343:                }
        !          1344:                btintr(unit);
        !          1345:                if(xs->error) return(HAD_ERROR);
        !          1346:                return(COMPLETE);
        !          1347:        } 
        !          1348: }
        !          1349: 
        !          1350: /*
        !          1351:  *               +----------+     +----------+     +----------+
        !          1352:  * bt_soonest--->|    later |---->|     later|---->|     later|--->0
        !          1353:  *               | [Delta]  |     | [Delta]  |     | [Delta]  |
        !          1354:  *        0<-----|sooner    |<----|sooner    |<----|sooner    |<----bt_latest
        !          1355:  *               +----------+     +----------+     +----------+
        !          1356:  *
        !          1357:  *     bt_furtherest = sum(Delta[1..n])
        !          1358:  */
        !          1359: bt_add_timeout(ccb,time)
        !          1360: struct bt_ccb  *ccb;
        !          1361: int    time;
        !          1362: {
        !          1363:        int     timeprev;
        !          1364:        struct bt_ccb *prev;
        !          1365:        int     s = splbio();
        !          1366: 
        !          1367:        if(prev = bt_latest) /* yes, an assign */
        !          1368:        {
        !          1369:                timeprev = bt_furtherest;
        !          1370:        }
        !          1371:        else
        !          1372:        {
        !          1373:                timeprev = 0;
        !          1374:        }
        !          1375:        while(prev && (timeprev > time)) 
        !          1376:        {
        !          1377:                timeprev -= prev->delta;
        !          1378:                prev = prev->sooner;
        !          1379:        }
        !          1380:        if(prev)
        !          1381:        {
        !          1382:                ccb->delta = time - timeprev;
        !          1383:                if( ccb->later = prev->later) /* yes an assign */
        !          1384:                {
        !          1385:                        ccb->later->sooner = ccb;
        !          1386:                        ccb->later->delta -= ccb->delta;
        !          1387:                }
        !          1388:                else
        !          1389:                {
        !          1390:                        bt_furtherest = time;
        !          1391:                        bt_latest = ccb;
        !          1392:                }
        !          1393:                ccb->sooner = prev;
        !          1394:                prev->later = ccb;
        !          1395:        }
        !          1396:        else
        !          1397:        {
        !          1398:                if( ccb->later = bt_soonest) /* yes, an assign*/
        !          1399:                {
        !          1400:                        ccb->later->sooner = ccb;
        !          1401:                        ccb->later->delta -= time;
        !          1402:                }
        !          1403:                else
        !          1404:                {
        !          1405:                        bt_furtherest = time;
        !          1406:                        bt_latest = ccb;
        !          1407:                }
        !          1408:                ccb->delta = time;
        !          1409:                ccb->sooner = (struct bt_ccb *)0;
        !          1410:                bt_soonest = ccb;
        !          1411:        }
        !          1412:        splx(s);
        !          1413: }
        !          1414: 
        !          1415: bt_remove_timeout(ccb)
        !          1416: struct bt_ccb  *ccb;
        !          1417: {
        !          1418:        int     s = splbio();
        !          1419: 
        !          1420:        if(ccb->sooner)
        !          1421:        {
        !          1422:                ccb->sooner->later = ccb->later;
        !          1423:        }
        !          1424:        else
        !          1425:        {
        !          1426:                bt_soonest = ccb->later;
        !          1427:        }
        !          1428:        if(ccb->later)
        !          1429:        {
        !          1430:                ccb->later->sooner = ccb->sooner;
        !          1431:                ccb->later->delta += ccb->delta;
        !          1432:        }
        !          1433:        else
        !          1434:        {
        !          1435:                bt_latest = ccb->sooner;
        !          1436:                bt_furtherest -= ccb->delta;
        !          1437:        }
        !          1438:        ccb->sooner = ccb->later = (struct bt_ccb *)0;
        !          1439:        splx(s);
        !          1440: }
        !          1441: 
        !          1442: 
        !          1443: extern int     hz;
        !          1444: #define ONETICK 500 /* milliseconds */
        !          1445: #define SLEEPTIME ((hz * 1000) / ONETICK)
        !          1446: bt_timeout(arg)
        !          1447: int    arg;
        !          1448: {
        !          1449:        struct  bt_ccb  *ccb;
        !          1450:        int     unit;
        !          1451:        int     s       = splbio();
        !          1452: 
        !          1453:        while( ccb = bt_soonest )
        !          1454:        {
        !          1455:                if(ccb->delta <= ONETICK)
        !          1456:                /***********************************************\
        !          1457:                * It has timed out, we need to do some work     *
        !          1458:                \***********************************************/
        !          1459:                {
        !          1460:                        unit = ccb->xfer->adapter;
        !          1461:                        printf("bt%d:%d device timed out\n",unit
        !          1462:                                        ,ccb->xfer->targ);
        !          1463:                        if(bt_debug & BT_SHOWCCBS)
        !          1464:                                tfs_print_active_ccbs();
        !          1465: 
        !          1466:                        /***************************************\
        !          1467:                        * Unlink it from the queue              *
        !          1468:                        \***************************************/
        !          1469:                        bt_remove_timeout(ccb);
        !          1470: 
        !          1471:                        /***************************************\
        !          1472:                        * If The ccb's mbx is not free, then    *
        !          1473:                        * the board has gone south              *
        !          1474:                        \***************************************/
        !          1475:                        if(ccb->mbx->cmd != BT_MBO_FREE)
        !          1476:                        {
        !          1477:                                printf("bt%d not taking commands!\n"
        !          1478:                                                        ,unit);
        !          1479:                                Debugger();
        !          1480:                        }
        !          1481:                        /***************************************\
        !          1482:                        * If it has been through before, then   *
        !          1483:                        * a previous abort has failed, don't    *
        !          1484:                        * try abort again                       *
        !          1485:                        \***************************************/
        !          1486:                        if(ccb->flags == CCB_ABORTED) /* abort timed out */
        !          1487:                        {
        !          1488:                                printf("AGAIN");
        !          1489:                                ccb->xfer->retries = 0; /* I MEAN IT ! */
        !          1490:                                ccb->host_stat = BT_ABORTED;
        !          1491:                                bt_done(unit,ccb);
        !          1492:                        }
        !          1493:                        else    /* abort the operation that has timed out */
        !          1494:                        {
        !          1495:                                printf("\n");
        !          1496:                                bt_abortmbx(ccb->mbx);
        !          1497:                                        /* 2 secs for the abort */
        !          1498:                                bt_add_timeout(ccb,2000 + ONETICK);
        !          1499:                                ccb->flags = CCB_ABORTED;
        !          1500:                        }
        !          1501:                }
        !          1502:                else
        !          1503:                /***********************************************\
        !          1504:                * It has not timed out, adjust and leave        *
        !          1505:                \***********************************************/
        !          1506:                {
        !          1507:                        ccb->delta -= ONETICK;
        !          1508:                        bt_furtherest -= ONETICK;
        !          1509:                        break;
        !          1510:                }
        !          1511:        }
        !          1512:        splx(s);
        !          1513:        timeout(bt_timeout,arg,SLEEPTIME);
        !          1514: }
        !          1515: 
        !          1516: tfs_print_ccb(ccb)
        !          1517: struct bt_ccb *ccb;
        !          1518: {
        !          1519:        printf("ccb:%x op:%x cmdlen:%d senlen:%d\n"
        !          1520:                ,ccb
        !          1521:                ,ccb->opcode
        !          1522:                ,ccb->scsi_cmd_length
        !          1523:                ,ccb->req_sense_length);
        !          1524:        printf("        datlen:%d hstat:%x tstat:%x delta:%d flags:%x\n"
        !          1525:                ,ccb->data_length
        !          1526:                ,ccb->host_stat
        !          1527:                ,ccb->target_stat
        !          1528:                ,ccb->delta
        !          1529:                ,ccb->flags);
        !          1530: }
        !          1531: 
        !          1532: tfs_print_active_ccbs()
        !          1533: {
        !          1534:        struct  bt_ccb *ccb;
        !          1535:        ccb = bt_soonest;
        !          1536: 
        !          1537:        while(ccb)
        !          1538:        {
        !          1539:                tfs_print_ccb(ccb);
        !          1540:                ccb = ccb->later;
        !          1541:        }
        !          1542:        printf("Furtherest = %d\n",bt_furtherest);
        !          1543: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.