Annotation of Net2/arch/i386/stand/as.c, revision 1.1.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.