Annotation of Net2/arch/i386/stand/as.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * sys/i386/stand/as.c
        !             3:  *
        !             4:  * Standalone driver for Adaptech 1542 SCSI
        !             5:  * 
        !             6:  * Pace Willisson        [email protected]       April 8, 1992
        !             7:  */
        !             8: 
        !             9: #include "param.h"
        !            10: #include "disklabel.h"
        !            11: #include "i386/isa/asreg.h"
        !            12: #include "saio.h"
        !            13: 
        !            14: #ifdef ASDEBUG
        !            15: #define ASPRINT(x) { printf x; DELAY (10000); }
        !            16: #else
        !            17: #define ASPRINT(x)
        !            18: #endif
        !            19: 
        !            20: #define NRETRIES 3
        !            21: 
        !            22: int as_port = 0x330;
        !            23: 
        !            24: struct mailbox_entry mailbox[2];
        !            25: 
        !            26: int
        !            27: asopen(io)
        !            28: struct iob *io;
        !            29: {
        !            30:         struct disklabel *dd;
        !            31:        char cdb[6];
        !            32:        char data[12];
        !            33:        int val;
        !            34:        int oval;
        !            35:        int i;
        !            36:        struct iob aio;
        !            37: 
        !            38:        if (io->i_unit < 0 || io->i_unit > 8
        !            39:            || io->i_part < 0 || io->i_part > 8
        !            40:            || io->i_ctlr < 0 || io->i_ctlr > 0)
        !            41:                return (-1);
        !            42: 
        !            43:        /* dma setup: see page 5-31 in the Adaptech manual */
        !            44:        outb (0xd6, 0xc1);
        !            45:        outb (0xd4, 0x01);
        !            46: 
        !            47:        ASPRINT (("resetting adaptech card... "));
        !            48: 
        !            49:        outb (as_port + AS_CONTROL, AS_CONTROL_SRST);
        !            50: 
        !            51:        /* delay a little */
        !            52:        for (i = 0; i < 100; i++)
        !            53:                inb (0x84);
        !            54:        
        !            55:        while (inb (as_port + AS_STATUS) != (AS_STATUS_INIT | AS_STATUS_IDLE))
        !            56:                ;
        !            57: 
        !            58:        ASPRINT (("reset ok "));
        !            59: 
        !            60:        as_put_byte (AS_CMD_MAILBOX_INIT);
        !            61:        as_put_byte (1); /* one mailbox out, one in */
        !            62:        as_put_byte ((int)mailbox >> 16);
        !            63:        as_put_byte ((int)mailbox >> 8);
        !            64:        as_put_byte ((int)mailbox);
        !            65: 
        !            66:        while (inb (as_port + AS_STATUS) & AS_STATUS_INIT)
        !            67:                ;
        !            68: 
        !            69:        ASPRINT (("mailbox init ok "));
        !            70: 
        !            71:        /* do mode select to set the logical block size */
        !            72:        bzero (cdb, 6);
        !            73:        cdb[0] = 0x15; /* MODE SELECT */
        !            74:        cdb[4] = 12; /* parameter list length */
        !            75: 
        !            76:        bzero (data, 12);
        !            77:        data[3] = 8; /* block descriptor length */
        !            78:        data[9] = DEV_BSIZE >> 16;
        !            79:        data[10] = DEV_BSIZE >> 8;
        !            80:        data[11] = DEV_BSIZE;
        !            81: 
        !            82:        if (ascmd (io->i_unit, 0, cdb, 6, data, 12, 1) < 0) {
        !            83:                printf ("as%d: error setting logical block size\n",
        !            84:                        io->i_unit);
        !            85:                return (-1);
        !            86:        }
        !            87: 
        !            88:        aio = *io;
        !            89:        aio.i_bn = LABELSECTOR;
        !            90:        aio.i_cc = DEV_BSIZE;
        !            91:        /*io->i_ma = buf;*/
        !            92:        aio.i_boff = 0;
        !            93: 
        !            94: #ifdef was
        !            95:        if (asstrategy (&aio, F_READ) == DEV_BSIZE) {
        !            96:                dd = (struct disklabel *)aio.i_ma;
        !            97:                io->i_boff = dd->d_partitions[io->i_part].p_offset;
        !            98:                ASPRINT (("partition offset %d ", io->i_boff));
        !            99:        }
        !           100: #else
        !           101: {
        !           102: extern struct disklabel disklabel;
        !           103:                io->i_boff = disklabel.d_partitions[io->i_part].p_offset;
        !           104:                ASPRINT (("partition offset %d ", io->i_boff));
        !           105: }
        !           106: #endif
        !           107: 
        !           108:        ASPRINT (("asopen ok "));
        !           109:        return(0);
        !           110: }
        !           111: 
        !           112: /* func is F_WRITE or F_READ
        !           113:  * io->i_unit, io->i_part, io->i_bn is starting block
        !           114:  * io->i_cc is byte count
        !           115:  * io->i_ma is memory address
        !           116:  * io->i_boff is block offset for this partition (set up in asopen)
        !           117:  */
        !           118: int
        !           119: asstrategy(io, func)
        !           120: struct iob *io;
        !           121: {
        !           122:        char cdb[6];
        !           123:        int blkno;
        !           124:        int retry;
        !           125: 
        !           126:        ASPRINT (("asstrategy(target=%d, block=%d+%d, count=%d) ",
        !           127:                  io->i_unit, io->i_bn, io->i_boff, io->i_cc));
        !           128: 
        !           129:        if (func == F_WRITE) {
        !           130:                printf ("as%d: write not supported\n", io->i_unit);
        !           131:                return (0);
        !           132:        }
        !           133: 
        !           134:        if (io->i_cc == 0)
        !           135:                return (0);
        !           136: 
        !           137:        if (io->i_cc % DEV_BSIZE != 0) {
        !           138:                printf ("as%d: transfer size not multiple of %d\n",
        !           139:                        io->i_unit, DEV_BSIZE);
        !           140:                return (0);
        !           141:        }
        !           142: 
        !           143:        /* retry in case we get a unit-attention error, which just
        !           144:         * means the drive has been reset since the last command
        !           145:         */
        !           146:        for (retry = 0; retry < NRETRIES; retry++) {
        !           147:                blkno = io->i_bn + io->i_boff;
        !           148: 
        !           149:                cdb[0] = 8; /* scsi read opcode */
        !           150:                cdb[1] = (blkno >> 16) & 0x1f;
        !           151:                cdb[2] = blkno >> 8;
        !           152:                cdb[3] = blkno;
        !           153:                cdb[4] = io->i_cc / DEV_BSIZE;
        !           154:                cdb[5] = 0; /* control byte (used in linking) */
        !           155: 
        !           156:                if (ascmd (io->i_unit, 1, cdb, 6, io->i_ma, io->i_cc,
        !           157:                           retry == NRETRIES - 1) >= 0) {
        !           158:                        ASPRINT (("asstrategy ok "));
        !           159:                        return (io->i_cc);
        !           160:                }
        !           161:        }
        !           162: 
        !           163:        ASPRINT (("asstrategy failed "));
        !           164:        return (0);
        !           165: }
        !           166: 
        !           167: int
        !           168: ascmd (target, readflag, cdb, cdblen, data, datalen, printerr)
        !           169: int target;
        !           170: int readflag;
        !           171: char *cdb;
        !           172: int cdblen;
        !           173: char *data;
        !           174: int datalen;
        !           175: int printerr;
        !           176: {
        !           177:        struct ccb ccb;
        !           178:        int physaddr;
        !           179:        unsigned char *sp;
        !           180:        int i;
        !           181: 
        !           182:        if (mailbox[0].cmd != 0)
        !           183:                /* this can't happen, unless the card flakes */
        !           184:                _stop ("asstart: mailbox not available\n");
        !           185: 
        !           186:        bzero (&ccb, sizeof ccb);
        !           187: 
        !           188:        ccb.ccb_opcode = 3;
        !           189:        ccb.ccb_addr_and_control = target << 5;
        !           190:        if (datalen != 0)
        !           191:                ccb.ccb_addr_and_control |= readflag ? 8 : 0x10;
        !           192:        else
        !           193:                ccb.ccb_addr_and_control |= 0x18;
        !           194: 
        !           195:        ccb.ccb_data_len_msb = datalen >> 16;
        !           196:        ccb.ccb_data_len_mid = datalen >> 8;
        !           197:        ccb.ccb_data_len_lsb = datalen;
        !           198: 
        !           199:        ccb.ccb_requst_sense_allocation_len = MAXSENSE;
        !           200: 
        !           201:        physaddr = (int)data;
        !           202:        ccb.ccb_data_ptr_msb = physaddr >> 16;
        !           203:        ccb.ccb_data_ptr_mid = physaddr >> 8;
        !           204:        ccb.ccb_data_ptr_lsb = physaddr;
        !           205: 
        !           206:        ccb.ccb_scsi_command_len = cdblen;
        !           207:        bcopy (cdb, ccb.ccb_cdb, cdblen);
        !           208: 
        !           209: #ifdef ASDEBUG
        !           210:        printf ("ccb: ");
        !           211:        for (i = 0; i < 48; i++)
        !           212:                printf ("%x ", ((unsigned char *)&ccb)[i]);
        !           213:        printf ("\n");
        !           214:        /*getchar ();*/
        !           215: #endif
        !           216: 
        !           217:        physaddr = (int)&ccb;
        !           218:        mailbox[0].msb = physaddr >> 16;
        !           219:        mailbox[0].mid = physaddr >> 8;
        !           220:        mailbox[0].lsb = physaddr;
        !           221:        mailbox[0].cmd = 1;
        !           222:        
        !           223:        /* tell controller to look in its mailbox */
        !           224:        outb (as_port + AS_CONTROL, AS_CONTROL_IRST);
        !           225:        as_put_byte (AS_CMD_START_SCSI_COMMAND);
        !           226: 
        !           227:        /* wait for status */
        !           228:        ASPRINT (("waiting for status..."));
        !           229:        while (mailbox[1].cmd == 0)
        !           230:                ;
        !           231:        mailbox[1].cmd = 0;
        !           232: 
        !           233: 
        !           234:        if (ccb.ccb_host_status != 0 || ccb.ccb_target_status != 0) {
        !           235: #ifdef ASDEBUG
        !           236:                printerr = 1;
        !           237: #endif
        !           238:                if (printerr) {
        !           239:                        printf ("as%d error: hst=%x tst=%x sense=",
        !           240:                                target,
        !           241:                                ccb.ccb_host_status,
        !           242:                                ccb.ccb_target_status);
        !           243:                        sp = ccb_sense (&ccb);
        !           244:                        for (i = 0; i < 8; i++)
        !           245:                                printf ("%x ", sp[i]);
        !           246:                        printf ("\n");
        !           247: #ifdef ASDEBUG
        !           248:                        /*getchar ();*/
        !           249: #endif
        !           250:                }
        !           251:                return (-1);
        !           252:        }
        !           253:        
        !           254:        ASPRINT (("ascmd ok "));
        !           255: 
        !           256:        return (0);
        !           257: }
        !           258: 
        !           259: int
        !           260: as_put_byte (val)
        !           261: int val;
        !           262: {
        !           263:        while (inb (as_port + AS_STATUS) & AS_STATUS_CDF)
        !           264:                ;
        !           265:        outb (as_port + AS_DATA_OUT, val);
        !           266: }
        !           267:                

unix.superglobalmegacorp.com

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