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

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

unix.superglobalmegacorp.com

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