Annotation of Gnu-Mach/scsi/rz_cpu.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1991,1990 Carnegie Mellon University
                      4:  * All Rights Reserved.
                      5:  * 
                      6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
                     11:  * 
                     12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     15:  * 
                     16:  * Carnegie Mellon requests users of this software to return to
                     17:  * 
                     18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
                     22:  * 
                     23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     File: rz_cpu.c
                     28:  *     Author: Alessandro Forin, Carnegie Mellon University
                     29:  *     Date:   7/91
                     30:  *
                     31:  *     Top layer of the SCSI driver: interface with the MI.
                     32:  *     This file contains operations specific to CPU-like devices.
                     33:  *
                     34:  * We handle here the case of simple devices which do not use any
                     35:  * sophisticated host-to-host communication protocol, they look
                     36:  * very much like degenerative cases of TAPE devices.
                     37:  *
                     38:  * For documentation and debugging, we also provide code to act like one.
                     39:  */
                     40: 
                     41: #include <mach/std_types.h>
                     42: #include <scsi/compat_30.h>
                     43: 
                     44: #include <scsi/scsi.h>
                     45: #include <scsi/scsi_defs.h>
                     46: #include <scsi/rz.h>
                     47: 
                     48: #if  (NSCSI > 0)
                     49: 
                     50: void sccpu_act_as_target(); /* forwards */
                     51: void sccpu_start();
                     52: 
                     53: /*
                     54:  * This function decides which 'protocol' we well speak
                     55:  * to a cpu target. For now the decision is left to a
                     56:  * global var. XXXXXXX
                     57:  */
                     58: extern scsi_devsw_t scsi_host;
                     59: scsi_devsw_t   *scsi_cpu_protocol = /* later &scsi_host*/
                     60:                        &scsi_devsw[SCSI_CPU];
                     61: 
                     62: void sccpu_new_initiator(self, initiator)
                     63:        target_info_t   *self, *initiator;
                     64: {
                     65:        initiator->dev_ops = scsi_cpu_protocol;
                     66:        if (initiator == self) {
                     67:                self->flags = TGT_DID_SYNCH|TGT_FULLY_PROBED|TGT_ONLINE|
                     68:                             TGT_ALIVE|TGT_US;
                     69:                self->dev_info.cpu.req_pending = FALSE;
                     70:        } else {
                     71:                initiator->flags = TGT_ONLINE|TGT_ALIVE;
                     72:                initiator->dev_info.cpu.req_pending = TRUE;
                     73:        }
                     74: }
                     75: 
                     76: void sccpu_strategy(ior)
                     77:        register io_req_t       ior;
                     78: {
                     79:        void                    sccpu_start();
                     80: 
                     81:        rz_simpleq_strategy(ior, sccpu_start);
                     82: }
                     83: 
                     84: void sccpu_start(tgt, done)
                     85:        target_info_t   *tgt;
                     86:        boolean_t       done;
                     87: {
                     88:        io_req_t                head, ior;
                     89:        scsi_ret_t              ret;
                     90: 
                     91:        /* this is to the doc & debug code mentioned in the beginning */
                     92:        if (!done && tgt->dev_info.cpu.req_pending) {
                     93:                panic("sccpu_act_as_target called");
                     94: #if 0
                     95:                sccpu_act_as_target( tgt);
                     96: #endif
                     97:                return;
                     98:        }
                     99: 
                    100:        ior = tgt->ior;
                    101:        if (ior == 0)
                    102:                return;
                    103: 
                    104:        if (done) {
                    105: 
                    106:                /* see if we must retry */
                    107:                if ((tgt->done == SCSI_RET_RETRY) &&
                    108:                    ((ior->io_op & IO_INTERNAL) == 0)) {
                    109:                        delay(1000000);/*XXX*/
                    110:                        goto start;
                    111:                } else
                    112:                /* got a bus reset ? shouldn't matter */
                    113:                if ((tgt->done == (SCSI_RET_ABORTED|SCSI_RET_RETRY)) &&
                    114:                    ((ior->io_op & IO_INTERNAL) == 0)) {
                    115:                        goto start;
                    116:                } else
                    117: 
                    118:                /* check completion status */
                    119: 
                    120:                if (tgt->cur_cmd == SCSI_CMD_REQUEST_SENSE) {
                    121:                        scsi_sense_data_t *sns;
                    122: 
                    123:                        ior->io_op = ior->io_temporary;
                    124:                        ior->io_error = D_IO_ERROR;
                    125:                        ior->io_op |= IO_ERROR;
                    126: 
                    127:                        sns = (scsi_sense_data_t *)tgt->cmd_ptr;
                    128:                        if (scsi_debug)
                    129:                                scsi_print_sense_data(sns);
                    130: 
                    131:                        if (scsi_check_sense_data(tgt, sns)) {
                    132:                            if (sns->u.xtended.ili) {
                    133:                                if (ior->io_op & IO_READ) {
                    134:                                    int residue;
                    135: 
                    136:                                    residue =   sns->u.xtended.info0 << 24 |
                    137:                                                sns->u.xtended.info1 << 16 |
                    138:                                                sns->u.xtended.info2 <<  8 |
                    139:                                                sns->u.xtended.info3;
                    140:                                    if (scsi_debug)
                    141:                                        printf("Cpu Short Read (%d)\n", residue);
                    142:                                    /*
                    143:                                     * NOTE: residue == requested - actual
                    144:                                     * We only care if > 0
                    145:                                     */
                    146:                                    if (residue < 0) residue = 0;/* sanity */
                    147:                                    ior->io_residual += residue;
                    148:                                    ior->io_error = 0;
                    149:                                    ior->io_op &= ~IO_ERROR;
                    150:                                    /* goto ok */
                    151:                                }
                    152:                            }
                    153:                        }
                    154:                }
                    155: 
                    156:                else if (tgt->done != SCSI_RET_SUCCESS) {
                    157: 
                    158:                    if (tgt->done == SCSI_RET_NEED_SENSE) {
                    159: 
                    160:                        ior->io_temporary = ior->io_op;
                    161:                        ior->io_op = IO_INTERNAL;
                    162:                        if (scsi_debug)
                    163:                                printf("[NeedSns x%x x%x]", ior->io_residual, ior->io_count);
                    164:                        scsi_request_sense(tgt, ior, 0);
                    165:                        return;
                    166: 
                    167:                    } else if (tgt->done == SCSI_RET_RETRY) {
                    168:                        /* only retry here READs and WRITEs */
                    169:                        if ((ior->io_op & IO_INTERNAL) == 0) {
                    170:                                ior->io_residual = 0;
                    171:                                goto start;
                    172:                        } else{
                    173:                                ior->io_error = D_WOULD_BLOCK;
                    174:                                ior->io_op |= IO_ERROR;
                    175:                        }
                    176:                    } else {
                    177:                        ior->io_error = D_IO_ERROR;
                    178:                        ior->io_op |= IO_ERROR;
                    179:                    }
                    180:                }
                    181: 
                    182:                if (scsi_debug)
                    183:                        printf("[Resid x%x]", ior->io_residual);
                    184: 
                    185:                /* dequeue next one */
                    186:                head = ior;
                    187: 
                    188:                simple_lock(&tgt->target_lock);
                    189:                ior = head->io_next;
                    190:                tgt->ior = ior;
                    191:                if (ior)
                    192:                        ior->io_prev = head->io_prev;
                    193:                simple_unlock(&tgt->target_lock);
                    194: 
                    195:                iodone(head);
                    196: 
                    197:                if (ior == 0)
                    198:                        return;
                    199:        }
                    200:        ior->io_residual = 0;
                    201: start:
                    202:        if (ior->io_op & IO_READ) {
                    203:                ret = scsi_receive( tgt, ior );
                    204:        } else if ((ior->io_op & IO_INTERNAL) == 0) {
                    205:                ret = scsi_send( tgt, ior );
                    206:        }
                    207: }
                    208: 
                    209: 
                    210: #if 0
                    211: /* XX turned off this code because it's impossible
                    212:    to reference 'end' and other such magic symbols
                    213:    from boot modules. */
                    214: /*
                    215:  * This is a simple code to make us act as a dumb
                    216:  * processor type.  Use for debugging only.
                    217:  */
                    218: static struct io_req   sccpu_ior;
                    219: vm_offset_t            sccpu_buffer; /* set this with debugger */
                    220: 
                    221: void sccpu_act_as_target(self)
                    222:        target_info_t   *self;
                    223: {
                    224:        static char     inq_data[] = "\3\0\1\0\040\0\0\0Mach3.0 Processor Link  v0.1";
                    225:        static char     sns_data[] = "\160\0\0\0\0\0\0\0\0";
                    226: 
                    227:        self->dev_info.cpu.req_pending = FALSE;
                    228:        sccpu_ior.io_next = 0;
                    229: #define MAXSIZE 1024*64
                    230:        sccpu_ior.io_count = (MAXSIZE < self->dev_info.cpu.req_len) ?
                    231:                MAXSIZE : self->dev_info.cpu.req_len;
                    232: 
                    233:        switch (self->dev_info.cpu.req_cmd) {
                    234:        case SCSI_CMD_INQUIRY:
                    235:                sccpu_ior.io_data = inq_data; break;
                    236:        case SCSI_CMD_REQUEST_SENSE:
                    237:                sccpu_ior.io_data = sns_data; break;
                    238:        default:
                    239:                if (sccpu_buffer == 0) {
                    240:                    /* ( read my lips :-) */
                    241:                    /* extern char end[]; */
                    242:                    sccpu_buffer = trunc_page(kalloc(MAXSIZE));
                    243:                }
                    244:                sccpu_ior.io_data = (char*)sccpu_buffer; break;
                    245:        }
                    246: 
                    247:        if (self->dev_info.cpu.req_cmd == SCSI_CMD_SEND) {
                    248:                self->cur_cmd = SCSI_CMD_READ;
                    249:                sccpu_ior.io_op = IO_READ;
                    250:        } else {
                    251:                self->cur_cmd = SCSI_CMD_WRITE;
                    252:                sccpu_ior.io_op = IO_WRITE;
                    253:        }
                    254:        self->ior = &sccpu_ior;
                    255: }
                    256: #endif
                    257: 
                    258: /*#define PERF*/
                    259: #ifdef PERF
                    260: int test_read_size = 512;
                    261: int test_read_nreads = 1000;
                    262: int test_read_bdev = 0;
                    263: int test_read_or_write = 1;
                    264: 
                    265: #include <sys/time.h>
                    266: #include <machine/machspl.h>   /* spl */
                    267: 
                    268: test_read(max)
                    269: {
                    270:        int i, ssk, usecs;
                    271:        struct timeval start, stop;
                    272:        spl_t s;
                    273: 
                    274:        if (max != 0)
                    275:                test_read_nreads = max;
                    276: 
                    277:        s = spl0();
                    278:        start = time;
                    279:        if (test_read_or_write) read_test(); else write_test();
                    280:        stop = time;
                    281:        splx(s);
                    282: 
                    283:        usecs = stop.tv_usec - start.tv_usec;
                    284:        if (usecs < 0) {
                    285:                stop.tv_sec -= 1;
                    286:                usecs += 1000000;
                    287:        }
                    288:        printf("Size %d count %d time %3d sec %d us\n",
                    289:                        test_read_size, test_read_nreads,
                    290:                        stop.tv_sec - start.tv_sec, usecs);
                    291: }
                    292: 
                    293: read_test()
                    294: {
                    295:        struct io_req   io, io1;
                    296:        register int    i;
                    297: 
                    298:        bzero(&io, sizeof(io));
                    299:        io.io_unit = test_read_bdev;
                    300:        io.io_op = IO_READ;
                    301:        io.io_count = test_read_size;
                    302:        io.io_data = (char*)sccpu_buffer;
                    303:        io1 = io;
                    304: 
                    305:        sccpu_strategy(&io);
                    306:        for (i = 1; i < test_read_nreads; i += 2) {
                    307:                io1.io_op = IO_READ;
                    308:                sccpu_strategy(&io1);
                    309:                iowait(&io);
                    310:                io.io_op = IO_READ;
                    311:                sccpu_strategy(&io);
                    312:                iowait(&io1);
                    313:        }
                    314:        iowait(&io);
                    315: }
                    316: 
                    317: write_test()
                    318: {
                    319:        struct io_req   io, io1;
                    320:        register int    i;
                    321: 
                    322:        bzero(&io, sizeof(io));
                    323:        io.io_unit = test_read_bdev;
                    324:        io.io_op = IO_WRITE;
                    325:        io.io_count = test_read_size;
                    326:        io.io_data = (char*)sccpu_buffer;
                    327:        io1 = io;
                    328: 
                    329:        sccpu_strategy(&io);
                    330:        for (i = 1; i < test_read_nreads; i += 2) {
                    331:                io1.io_op = IO_WRITE;
                    332:                sccpu_strategy(&io1);
                    333:                iowait(&io);
                    334:                io.io_op = IO_WRITE;
                    335:                sccpu_strategy(&io);
                    336:                iowait(&io1);
                    337:        }
                    338:        iowait(&io);
                    339: }
                    340: 
                    341: tur_test()
                    342: {
                    343:        struct io_req   io;
                    344:        register int    i;
                    345:        char            *a;
                    346:        struct timeval start, stop;
                    347:        spl_t s;
                    348:        target_info_t   *tgt;
                    349: 
                    350:        bzero(&io, sizeof(io));
                    351:        io.io_unit = test_read_bdev;
                    352:        io.io_data = (char*)&io;/*unused but kernel space*/
                    353: 
                    354:        rz_check(io.io_unit, &a, &tgt);
                    355:        s = spl0();
                    356:        start = time;
                    357:        for (i = 0; i < test_read_nreads; i++) {
                    358:                io.io_op = IO_INTERNAL;
                    359:                scsi_test_unit_ready(tgt,&io);
                    360:        }
                    361:        stop = time;
                    362:        splx(s);
                    363:        i = stop.tv_usec - start.tv_usec;
                    364:        if (i < 0) {
                    365:                stop.tv_sec -= 1;
                    366:                i += 1000000;
                    367:        }
                    368:        printf("%d test-unit-ready took %3d sec %d us\n",
                    369:                        test_read_nreads,
                    370:                        stop.tv_sec - start.tv_sec, i);
                    371: }
                    372: 
                    373: /*#define      MEM_PERF*/
                    374: #ifdef MEM_PERF
                    375: int mem_read_size = 1024; /* ints! */
                    376: int mem_read_nreads = 1000;
                    377: volatile int *mem_read_address = (volatile int*)0xb0080000;
                    378: volatile int *mem_write_address = (volatile int*)0xb0081000;
                    379: 
                    380: mem_test(max, which)
                    381: {
                    382:        int i, ssk, usecs;
                    383:        struct timeval start, stop;
                    384:        int (*fun)(), mwrite_test(), mread_test(), mcopy_test();
                    385:        spl_t s;
                    386: 
                    387:        if (max == 0)
                    388:                max = mem_read_nreads;
                    389: 
                    390:        switch (which) {
                    391:        case 1: fun = mwrite_test; break;
                    392:        case 2: fun = mcopy_test; break;
                    393:        default:fun = mread_test; break;
                    394:        }
                    395: 
                    396:        s = spl0();
                    397:        start = time;
                    398:        for (i = 0; i < max; i++)
                    399:                (*fun)(mem_read_size);
                    400:        stop = time;
                    401:        splx(s);
                    402: 
                    403:        usecs = stop.tv_usec - start.tv_usec;
                    404:        if (usecs < 0) {
                    405:                stop.tv_sec -= 1;
                    406:                usecs += 1000000;
                    407:        }
                    408:        printf("Size %d count %d time %3d sec %d us\n",
                    409:                        mem_read_size*4, max,
                    410:                        stop.tv_sec - start.tv_sec, usecs);
                    411: }
                    412: 
                    413: mread_test(max)
                    414:        register int max;
                    415: {
                    416:        register int    i;
                    417:        register volatile int *addr = mem_read_address;
                    418: 
                    419:        for (i = 0; i < max; i++) {
                    420:                register int j = *addr++;
                    421:        }
                    422: }
                    423: mwrite_test(max)
                    424:        register int max;
                    425: {
                    426:        register int    i;
                    427:        register volatile int *addr = mem_read_address;
                    428: 
                    429:        for (i = 0; i < max; i++) {
                    430:                *addr++ = i;
                    431:        }
                    432: }
                    433: 
                    434: mcopy_test(max)
                    435:        register int max;
                    436: {
                    437:        register volatile int *from = mem_read_address;
                    438:        register volatile int *to = mem_write_address;
                    439:        register volatile int *endaddr;
                    440: 
                    441:        endaddr = to + max;
                    442:        while (to < endaddr)
                    443:                *to++ = *from++;
                    444: 
                    445: }
                    446: #endif /*MEM_PERF*/
                    447: 
                    448: #endif /*PERF*/
                    449: 
                    450: #endif  /* NSCSI > 0 */

unix.superglobalmegacorp.com

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