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

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

unix.superglobalmegacorp.com

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