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

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

unix.superglobalmegacorp.com

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