Annotation of Net2/arch/amiga/dev/sd.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1990 The Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * This code is derived from software contributed to Berkeley by
                      6:  * Van Jacobson of Lawrence Berkeley Laboratory.
                      7:  *
                      8:  * Redistribution and use in source and binary forms, with or without
                      9:  * modification, are permitted provided that the following conditions
                     10:  * are met:
                     11:  * 1. Redistributions of source code must retain the above copyright
                     12:  *    notice, this list of conditions and the following disclaimer.
                     13:  * 2. Redistributions in binary form must reproduce the above copyright
                     14:  *    notice, this list of conditions and the following disclaimer in the
                     15:  *    documentation and/or other materials provided with the distribution.
                     16:  * 3. All advertising materials mentioning features or use of this software
                     17:  *    must display the following acknowledgement:
                     18:  *     This product includes software developed by the University of
                     19:  *     California, Berkeley and its contributors.
                     20:  * 4. Neither the name of the University nor the names of its contributors
                     21:  *    may be used to endorse or promote products derived from this software
                     22:  *    without specific prior written permission.
                     23:  *
                     24:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
                     25:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                     26:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                     27:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
                     28:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                     29:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                     30:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                     31:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                     32:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                     33:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                     34:  * SUCH DAMAGE.
                     35:  *
                     36:  *     @(#)sd.c        7.8 (Berkeley) 6/9/91
                     37:  */
                     38: 
                     39: /*
                     40:  * SCSI CCS (Command Command Set) disk driver.
                     41:  */
                     42: #include "sd.h"
                     43: #if NSD > 0
                     44: 
                     45: #ifndef lint
                     46: static char rcsid[] = "/b/source/CVS/src/sys/arch/amiga/dev/sd.c,v 1.1.1.1 1993/07/05 19:19:47 mw Exp";
                     47: #endif
                     48: 
                     49: #include "sys/param.h"
                     50: #include "sys/systm.h"
                     51: #include "sys/buf.h"
                     52: #include "sys/dkstat.h"
                     53: #include "sys/disklabel.h"
                     54: #include "sys/malloc.h"
                     55: #include "sys/proc.h"
                     56: #include "sys/reboot.h"
                     57: #include "sys/file.h"
                     58: 
                     59: #include "device.h"
                     60: #include "scsireg.h"
                     61: #include "vm/vm_param.h"
                     62: #include "vm/lock.h"
                     63: #include "vm/vm_statistics.h"
                     64: #include "vm/pmap.h"
                     65: #include "vm/vm_prot.h"
                     66: 
                     67: #include "rdb.h"
                     68: 
                     69: struct sd_softc;
                     70: 
                     71: extern int sdinit (register struct amiga_device *ad);
                     72: extern void sdreset (register struct sd_softc *sc, register struct amiga_device *ad);
                     73: extern int sdopen (dev_t dev, int flags, int mode, struct proc *p);
                     74: extern void sdstrategy (register struct buf *bp);
                     75: extern void sdustart (register int unit);
                     76: extern void sdstart (register int unit);
                     77: extern void sdgo (register int unit);
                     78: extern void sdintr (register int unit, int stat);
                     79: extern int sdioctl (dev_t dev, int cmd, caddr_t data, int flag, struct proc *p);
                     80: extern int sdsize (dev_t dev);
                     81: extern int sddump (dev_t dev);
                     82: static int sdident (struct sd_softc *sc, struct amiga_device *ad);
                     83: static void sdlblkstrat (register struct buf *bp, register int bsize);
                     84: static int sderror (int unit, register struct sd_softc *sc, register struct amiga_device *am, int stat);
                     85: static void sdfinish (int unit, register struct sd_softc *sc, register struct buf *bp);
                     86: 
                     87: extern void disksort();
                     88: extern int physio();
                     89: extern void TBIS();
                     90: 
                     91: int    sdinit();
                     92: void   sdstrategy(), sdstart(), sdustart(), sdgo(), sdintr();
                     93: 
                     94: struct driver sddriver = {
                     95:        sdinit, "sd", (int (*)())sdstart, (int (*)())sdgo, (int (*)())sdintr, 0,
                     96: };
                     97: 
                     98: #if 0
                     99: struct size {
                    100:        u_long  strtblk;
                    101:        u_long  endblk;
                    102:        int     nblocks;
                    103: };
                    104: 
                    105: struct sdinfo {
                    106:        u_int   cylinders;      /* number of driver cylinders         RDB value */
                    107:        u_int   sectors;        /* sectors per track                  RDB value */
                    108:        u_int   heads;          /* number of drive heads              RDB value */
                    109:        u_int   cylblocks;      /* available number of blocks per cyl RDB value */
                    110:        struct  size part[8];
                    111: };
                    112: 
                    113: /*
                    114:  * since the SCSI standard tends to hide the disk structure, we define
                    115:  * partitions in terms of DEV_BSIZE blocks.  The default partition table
                    116:  * (for an unlabeled disk) reserves 512K for a boot area, has an 8 meg
                    117:  * root and 32 meg of swap.  The rest of the space on the drive goes in
                    118:  * the G partition.  As usual, the C partition covers the entire disk
                    119:  * (including the boot area).
                    120:  */
                    121: struct sdinfo sddefaultpart = {
                    122:             1024,   17408,   16384   , /* A */
                    123:            17408,   82944,   65536   , /* B */
                    124:                0,       0,       0   , /* C */
                    125:            17408,  115712,   98304   , /* D */
                    126:           115712,  218112,  102400   , /* E */
                    127:           218112,       0,       0   , /* F */
                    128:            82944,       0,       0   , /* G */
                    129:           115712,       0,       0   , /* H */
                    130: };
                    131: #endif
                    132: 
                    133: struct sd_softc {
                    134:        struct  amiga_device *sc_ad;
                    135:        struct  devqueue sc_dq;
                    136:        int     sc_format_pid;  /* process using "format" mode */
                    137:        short   sc_flags;
                    138:        short   sc_type;        /* drive type */
                    139:        short   sc_punit;       /* physical unit (scsi lun) */
                    140:        u_short sc_bshift;      /* convert device blocks to DEV_BSIZE blks */
                    141:        u_int   sc_blks;        /* number of blocks on device */
                    142:        int     sc_blksize;     /* device block size in bytes */
                    143:        u_int   sc_wpms;        /* average xfer rate in 16 bit wds/sec. */
                    144:        char    sc_idstr[32];   /* XXX */
                    145:        struct  disklabel sc_label;  /* drive partition table & label info */
                    146:        int     sc_have_label;
                    147:        int     sc_write_label;
                    148: } sd_softc[NSD];
                    149: 
                    150: /* sc_flags values */
                    151: #define        SDF_ALIVE       0x1
                    152: 
                    153: #ifdef DEBUG
                    154: int sddebug = 0;
                    155: #define SDB_ERROR      0x01
                    156: #define SDB_PARTIAL    0x02
                    157: /*#define QUASEL*/
                    158: #endif
                    159: 
                    160: #ifdef QUASEL
                    161: #define QPRINTF(a) printf a
                    162: #else
                    163: #define QPRINTF(a)
                    164: #endif
                    165: 
                    166: struct sdstats {
                    167:        long    sdresets;
                    168:        long    sdtransfers;
                    169:        long    sdpartials;
                    170: } sdstats[NSD];
                    171: 
                    172: struct buf sdtab[NSD];
                    173: struct scsi_fmt_cdb sdcmd[NSD];
                    174: struct scsi_fmt_sense sdsense[NSD];
                    175: 
                    176: static struct scsi_fmt_cdb sd_read_cmd = { 10, CMD_READ_EXT };
                    177: static struct scsi_fmt_cdb sd_write_cmd = { 10, CMD_WRITE_EXT };
                    178: 
                    179: #define        sdunit(x)       (minor(x) >> 3)
                    180: #define sdpart(x)      (minor(x) & 0x7)
                    181: #define        sdpunit(x)      ((x) & 7)
                    182: #define        b_cylin         b_resid
                    183: 
                    184: #define        SDRETRY         2
                    185: 
                    186: /*
                    187:  * Table of scsi commands users are allowed to access via "format"
                    188:  * mode.  0 means not legal.  1 means "immediate" (doesn't need dma).
                    189:  * -1 means needs dma and/or wait for intr.
                    190:  */
                    191: static char legal_cmds[256] = {
                    192: /*****  0   1   2   3   4   5   6   7     8   9   A   B   C   D   E   F */
                    193: /*00*/ 0,  0,  0,  0, -1,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    194: /*10*/ 0,  0,  1,  0,  0,  1,  0,  0,    0,  0,  1,  0,  0,  0,  0,  0,
                    195: /*20*/ 0,  0,  0,  0,  0,  1,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    196: /*30*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    197: /*40*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    198: /*50*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    199: /*60*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    200: /*70*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    201: /*80*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    202: /*90*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    203: /*a0*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    204: /*b0*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    205: /*c0*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    206: /*d0*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    207: /*e0*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    208: /*f0*/ 0,  0,  0,  0,  0,  0,  0,  0,    0,  0,  0,  0,  0,  0,  0,  0,
                    209: };
                    210: 
                    211: static struct scsi_inquiry inqbuf;
                    212: static struct scsi_fmt_cdb inq = {
                    213:        6,
                    214:        CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0
                    215: };
                    216: 
                    217: static u_char capbuf[8];
                    218: struct scsi_fmt_cdb cap = {
                    219:        10,
                    220:        CMD_READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0
                    221: };
                    222: 
                    223: static int
                    224: sdident(sc, ad)
                    225:        struct sd_softc *sc;
                    226:        struct amiga_device *ad;
                    227: {
                    228:        int unit;
                    229:        register int ctlr, slave;
                    230:        register int i;
                    231:        register int tries = 10;
                    232:        int ismo = 0;
                    233: 
                    234:        ctlr = ad->amiga_ctlr;
                    235:        slave = ad->amiga_slave;
                    236:        unit = sc->sc_punit;
                    237:        scsi_delay(-1);
                    238: 
                    239:        /*
                    240:         * See if unit exists and is a disk then read block size & nblocks.
                    241:         */
                    242:        while ((i = scsi_test_unit_rdy(slave)) != 0) {
                    243: retry_TUR:
                    244:                if (i == -1 || --tries < 0) {
                    245:                        if (ismo)
                    246:                                break;
                    247:                        /* doesn't exist or not a CCS device */
                    248:                        goto failed;
                    249:                }
                    250:                if (i == STS_CHECKCOND) {
                    251:                        u_char sensebuf[128];
                    252:                        struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf;
                    253: 
                    254:                        i = scsi_request_sense(slave, sensebuf, sizeof(sensebuf));
                    255:                        if (sp->class == 7)
                    256:                                switch (sp->key) {
                    257:                                /* not ready -- might be MO with no media */
                    258:                                case 2:
                    259:                                        if (sp->len == 12 &&
                    260:                                            sensebuf[12] == 10) /* XXX */
                    261:                                                ismo = 1;
                    262:                                        break;
                    263:                                /* drive doing an RTZ -- give it a while */
                    264:                                case 6:
                    265:                                        DELAY(1000000);
                    266:                                        break;
                    267:                                default:
                    268:                                        break;
                    269:                                }
                    270:                }
                    271:                DELAY(1000);
                    272:        }
                    273:        /*
                    274:         * Find out about device
                    275:         */
                    276:        if (i = scsi_immed_command(slave, &inq, (u_char *)&inqbuf, sizeof(inqbuf), B_READ))
                    277:          {
                    278:            if (i == STS_CHECKCOND)
                    279:              goto retry_TUR;
                    280:            goto failed;
                    281:          }
                    282:        switch (inqbuf.type) {
                    283:        case 0:         /* disk */
                    284:        case 4:         /* WORM */
                    285:        case 5:         /* CD-ROM */
                    286:        case 7:         /* Magneto-optical */
                    287:                break;
                    288:        default:        /* not a disk */
                    289:                if (sddebug)
                    290:                  printf ("Unit %d unknown scsi-type: %d\n", slave, inqbuf.type);
                    291:                goto failed;
                    292:        }
                    293:        /*
                    294:         * Get a usable id string
                    295:         */
                    296:        if (inqbuf.version < 1) {
                    297:                bcopy("UNKNOWN", &sc->sc_idstr[0], 8);
                    298:                bcopy("DRIVE TYPE", &sc->sc_idstr[8], 11);
                    299:        } else {
                    300:                bcopy((caddr_t)&inqbuf.vendor_id, (caddr_t)sc->sc_idstr, 28);
                    301:                for (i = 27; i > 23; --i)
                    302:                        if (sc->sc_idstr[i] != ' ')
                    303:                                break;
                    304:                sc->sc_idstr[i+1] = 0;
                    305:                for (i = 23; i > 7; --i)
                    306:                        if (sc->sc_idstr[i] != ' ')
                    307:                                break;
                    308:                sc->sc_idstr[i+1] = 0;
                    309:                for (i = 7; i >= 0; --i)
                    310:                        if (sc->sc_idstr[i] != ' ')
                    311:                                break;
                    312:                sc->sc_idstr[i+1] = 0;
                    313:        }
                    314:        i = scsi_immed_command(slave, &cap, (u_char *)&capbuf, sizeof(capbuf), B_READ);
                    315:        if (i) {
                    316:                if (i != STS_CHECKCOND ||
                    317:                    bcmp(&sc->sc_idstr[0], "HP", 3) ||
                    318:                    bcmp(&sc->sc_idstr[8], "S6300.650A", 11))
                    319:                        goto failed;
                    320:                /* XXX unformatted or non-existant MO media; fake it */
                    321:                sc->sc_blks = 318664;
                    322:                sc->sc_blksize = 1024;
                    323:        } else {
                    324:                sc->sc_blks = *(u_int *)&capbuf[0];
                    325:                sc->sc_blksize = *(int *)&capbuf[4];
                    326:        }
                    327:        /* return value of read capacity is last valid block number */
                    328:        sc->sc_blks++;
                    329: 
                    330:        if (inqbuf.version < 1)
                    331:                printf("sd%d: type 0x%x, qual 0x%x, ver %d", ad->amiga_unit,
                    332:                        inqbuf.type, inqbuf.qual, inqbuf.version);
                    333:        else
                    334:                printf("sd%d: %s %s rev %s", ad->amiga_unit, sc->sc_idstr, &sc->sc_idstr[8],
                    335:                        &sc->sc_idstr[24]);
                    336:        printf(", %d %d byte blocks\n", sc->sc_blks, sc->sc_blksize);
                    337:        if (sc->sc_blksize != DEV_BSIZE) {
                    338:                if (sc->sc_blksize < DEV_BSIZE) {
                    339:                        printf("sd%d: need %d byte blocks - drive ignored\n",
                    340:                                unit, DEV_BSIZE);
                    341:                        goto failed;
                    342:                }
                    343:                for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1)
                    344:                        ++sc->sc_bshift;
                    345:                sc->sc_blks <<= sc->sc_bshift;
                    346:        }
                    347:        sc->sc_wpms = 32 * (60 * DEV_BSIZE / 2);        /* XXX */
                    348:        scsi_delay(0);
                    349:        return(inqbuf.type);
                    350: failed:
                    351:        scsi_delay(0);
                    352:        return(-1);
                    353: }
                    354: 
                    355: int
                    356: sdinit(ad)
                    357:        register struct amiga_device *ad;
                    358: {
                    359:        register struct sd_softc *sc = &sd_softc[ad->amiga_unit];
                    360:        static u_int block [DEV_BSIZE / 4];
                    361:        struct RigidDiskBlock *rdb = (struct RigidDiskBlock *) block;
                    362:        struct PartitionBlock *pb  = (struct PartitionBlock *) block;
                    363:        int bnum, npbnum, num_bsd_part = 0;
                    364:        struct disklabel *dl;
                    365: 
                    366:        sc->sc_ad = ad;
                    367:        sc->sc_punit = sdpunit(ad->amiga_flags);
                    368:        sc->sc_type = sdident(sc, ad);
                    369:        if (sc->sc_type < 0)
                    370:                return(0);
                    371:        sc->sc_dq.dq_ctlr = ad->amiga_ctlr;
                    372:        sc->sc_dq.dq_unit = ad->amiga_unit;
                    373:        sc->sc_dq.dq_slave = ad->amiga_slave;
                    374:        sc->sc_dq.dq_driver = &sddriver;
                    375: 
                    376:        /* read RDB and partition blocks to find out about which partitions
                    377:           are ok to be scribbled upon by BSD. This is quite Amiga specific. */
                    378: 
                    379:        for (bnum = 0; bnum < RDB_LOCATION_LIMIT; bnum++)
                    380:          {
                    381:            if (scsi_tt_read (ad->amiga_slave, block, DEV_BSIZE, bnum, sc->sc_bshift))
                    382:              /* read error on block */
                    383:              return 0;
                    384: 
                    385:            if (rdb->rdb_ID == IDNAME_RIGIDDISK)
                    386:              break;
                    387:          }
                    388:        if (bnum == RDB_LOCATION_LIMIT)
                    389:          /* no RDB on this disk */
                    390:          return 0;
                    391: 
                    392:        /* fill in as much as we can of the disklabel */
                    393:        dl = &sc->sc_label;
                    394:        bzero (dl, sizeof (*dl));
                    395:        dl->d_magic = DISKMAGIC;
                    396:        dl->d_type  = DTYPE_SCSI;
                    397: 
                    398:        strncpy (dl->d_typename, sc->sc_idstr, sizeof (dl->d_typename) - 1);
                    399:        strcpy (dl->d_packname, "some pack");
                    400:        
                    401:        /* now for more serious information.. */
                    402:        dl->d_secsize    = rdb->rdb_BlockBytes;
                    403:        dl->d_nsectors   = rdb->rdb_Sectors;
                    404:        dl->d_ntracks    = rdb->rdb_Heads;
                    405:        dl->d_ncylinders = rdb->rdb_Cylinders;
                    406:        dl->d_secpercyl  = rdb->rdb_CylBlocks;
                    407:        dl->d_secperunit = (rdb->rdb_CylBlocks 
                    408:                            * (rdb->rdb_HiCylinder - rdb->rdb_LoCylinder));
                    409: 
                    410:        /* makes sense? */
                    411:        dl->d_acylinders = rdb->rdb_Cylinders - (rdb->rdb_HiCylinder - rdb->rdb_LoCylinder);
                    412: 
                    413:        dl->d_magic2 = DISKMAGIC;
                    414: 
                    415:        /* ok, go thru the partition blocks, and check for BSD ID's */
                    416:        
                    417:        for (npbnum = rdb->rdb_PartitionList; npbnum; )
                    418:          {
                    419:            u_int start_block, end_block, nblocks;
                    420:            u_int reserved;
                    421:            int part;
                    422: 
                    423:            if (scsi_tt_read (ad->amiga_slave, block, DEV_BSIZE, npbnum, sc->sc_bshift))
                    424:              break;
                    425:          
                    426:            if (pb->pb_ID != IDNAME_PARTITION)
                    427:              break;
                    428: 
                    429:            /* remember those values, they're destroyed when reading the first
                    430:               partition block */
                    431:            npbnum      = pb->pb_Next;
                    432:            start_block = pb->pb_Environment[DE_LOWCYL] * dl->d_secpercyl;
                    433:            reserved    = pb->pb_Environment[DE_RESERVEDBLKS];
                    434:            end_block   = pb->pb_Environment[DE_UPPERCYL] * dl->d_secpercyl;
                    435: 
                    436:            part = -1;
                    437:            switch (pb->pb_Environment[DE_DOSTYPE])
                    438:              {
                    439:              case DOSTYPE_BSD_ROOT:
                    440:                if (! dl->d_partitions[0].p_size)
                    441:                  {
                    442:                    extern u_long bootdev;
                    443: 
                    444:                    part = 0;
                    445: 
                    446:                    /* Since we don't boot BSD with a standalone-kernel, but
                    447:                       with a simple boot-loader from AmigaDOS, we fake a
                    448:                       bootdev by assigning the just computed values of the
                    449:                       root partition. */
                    450: 
                    451:                    /* 4:               sd major
                    452:                       0:               adaptor number
                    453:                       0:               controller number
                    454:                       ad->amiga_unit:  scsi-unit
                    455:                       part:            partition (A) */
                    456: 
                    457:                    bootdev = MAKEBOOTDEV (4, 0, 0, ad->amiga_unit, part);
                    458:                  }
                    459:                break;
                    460: 
                    461:              case DOSTYPE_BSD_SWAP:            
                    462:                if (! dl->d_partitions[1].p_size)
                    463:                  part = 1;
                    464:                break;
                    465:                
                    466:              case DOSTYPE_BSD_D:
                    467:                if (! dl->d_partitions[3].p_size)
                    468:                  part = 3;
                    469:                break;
                    470:                
                    471:              case DOSTYPE_BSD_E:
                    472:                if (! dl->d_partitions[4].p_size)
                    473:                  part = 4;
                    474:                break;
                    475:                
                    476:              case DOSTYPE_BSD_F:
                    477:                if (! dl->d_partitions[5].p_size)
                    478:                  part = 5;
                    479:                break;
                    480:                
                    481:              case DOSTYPE_BSD_G:
                    482:                if (! dl->d_partitions[6].p_size)
                    483:                  part = 6;
                    484:                break;
                    485:                
                    486:              case DOSTYPE_BSD_H:
                    487:                if (! dl->d_partitions[7].p_size)
                    488:                  part = 7;
                    489:                break;
                    490:              }
                    491: 
                    492:            if (part >= 0)
                    493:              {
                    494:                num_bsd_part++;
                    495: 
                    496:                dl->d_partitions[part].p_offset = start_block + reserved;
                    497:                dl->d_partitions[part].p_size = end_block - start_block - reserved;
                    498: 
                    499:                /* for now, have this static.. XXX */
                    500:                dl->d_partitions[part].p_fsize  = 1024;
                    501:                dl->d_partitions[part].p_fstype = part == 1 ? FS_SWAP : FS_BSDFFS;
                    502:                dl->d_partitions[part].p_frag   = 8;
                    503:                dl->d_partitions[part].p_cpg    = 0;    /* XXX */
                    504:            
                    505:                if (sddebug)
                    506:                  printf ("%c @%d - %d = %d\n", part + 'A',
                    507:                          start_block, end_block, end_block - start_block - reserved);
                    508:              }
                    509:          }
                    510: 
                    511:        dl->d_npartitions = num_bsd_part;
                    512:        if (sddebug)
                    513:          printf ("total %d BSD-partitions.\n", num_bsd_part);
                    514: 
                    515:        /* C gets everything */
                    516:        dl->d_partitions[2].p_size = sc->sc_blks;
                    517: 
                    518:        dl->d_checksum = 0;
                    519:        dl->d_checksum = dkcksum (dl);
                    520: 
                    521:        sc->sc_have_label = 1;
                    522:        sc->sc_write_label = 0;
                    523: 
                    524:        sc->sc_flags = SDF_ALIVE;
                    525:        return(1);
                    526: }
                    527: 
                    528: void
                    529: sdreset(sc, ad)
                    530:        register struct sd_softc *sc;
                    531:        register struct amiga_device *ad;
                    532: {
                    533:        sdstats[ad->amiga_unit].sdresets++;
                    534: }
                    535: 
                    536: int
                    537: sdopen(dev, flags, mode, p)
                    538:        dev_t dev;
                    539:        int flags, mode;
                    540:        struct proc *p;
                    541: {
                    542:        register int unit = sdunit(dev);
                    543:        register struct sd_softc *sc = &sd_softc[unit];
                    544: 
                    545:        if (unit >= NSD)
                    546:                return(ENXIO);
                    547:        if ((sc->sc_flags & SDF_ALIVE) == 0 && suser(p->p_ucred, &p->p_acflag))
                    548:                return(ENXIO);
                    549: 
                    550:        if (sc->sc_ad->amiga_dk >= 0)
                    551:                dk_wpms[sc->sc_ad->amiga_dk] = sc->sc_wpms;
                    552:        return(0);
                    553: }
                    554: 
                    555: /*
                    556:  * This routine is called for partial block transfers and non-aligned
                    557:  * transfers (the latter only being possible on devices with a block size
                    558:  * larger than DEV_BSIZE).  The operation is performed in three steps
                    559:  * using a locally allocated buffer:
                    560:  *     1. transfer any initial partial block
                    561:  *     2. transfer full blocks
                    562:  *     3. transfer any final partial block
                    563:  */
                    564: static void
                    565: sdlblkstrat(bp, bsize)
                    566:        register struct buf *bp;
                    567:        register int bsize;
                    568: {
                    569:        register struct buf *cbp = (struct buf *)malloc(sizeof(struct buf),
                    570:                                                        M_DEVBUF, M_WAITOK);
                    571:        caddr_t cbuf = (caddr_t)malloc(bsize, M_DEVBUF, M_WAITOK);
                    572:        register int bn, resid;
                    573:        register caddr_t addr;
                    574: 
                    575:        bzero((caddr_t)cbp, sizeof(*cbp));
                    576:        cbp->b_proc = curproc;          /* XXX */
                    577:        cbp->b_dev = bp->b_dev;
                    578:        bn = bp->b_blkno;
                    579:        resid = bp->b_bcount;
                    580:        addr = bp->b_un.b_addr;
                    581: #ifdef DEBUG
                    582:        if (sddebug & SDB_PARTIAL)
                    583:                printf("sdlblkstrat: bp %x flags %x bn %x resid %x addr %x\n",
                    584:                       bp, bp->b_flags, bn, resid, addr);
                    585: #endif
                    586: 
                    587:        while (resid > 0) {
                    588:                register int boff = dbtob(bn) & (bsize - 1);
                    589:                register int count;
                    590: 
                    591:                if (boff || resid < bsize) {
                    592:                        sdstats[sdunit(bp->b_dev)].sdpartials++;
                    593:                        count = MIN(resid, bsize - boff);
                    594:                        cbp->b_flags = B_BUSY | B_PHYS | B_READ;
                    595:                        cbp->b_blkno = bn - btodb(boff);
                    596:                        cbp->b_un.b_addr = cbuf;
                    597:                        cbp->b_bcount = bsize;
                    598: #ifdef DEBUG
                    599:                        if (sddebug & SDB_PARTIAL)
                    600:                                printf(" readahead: bn %x cnt %x off %x addr %x\n",
                    601:                                       cbp->b_blkno, count, boff, addr);
                    602: #endif
                    603:                        sdstrategy(cbp);
                    604:                        biowait(cbp);
                    605:                        if (cbp->b_flags & B_ERROR) {
                    606:                                bp->b_flags |= B_ERROR;
                    607:                                bp->b_error = cbp->b_error;
                    608:                                break;
                    609:                        }
                    610:                        if (bp->b_flags & B_READ) {
                    611:                                bcopy(&cbuf[boff], addr, count);
                    612:                                goto done;
                    613:                        }
                    614:                        bcopy(addr, &cbuf[boff], count);
                    615: #ifdef DEBUG
                    616:                        if (sddebug & SDB_PARTIAL)
                    617:                                printf(" writeback: bn %x cnt %x off %x addr %x\n",
                    618:                                       cbp->b_blkno, count, boff, addr);
                    619: #endif
                    620:                } else {
                    621:                        count = resid & ~(bsize - 1);
                    622:                        cbp->b_blkno = bn;
                    623:                        cbp->b_un.b_addr = addr;
                    624:                        cbp->b_bcount = count;
                    625: #ifdef DEBUG
                    626:                        if (sddebug & SDB_PARTIAL)
                    627:                                printf(" fulltrans: bn %x cnt %x addr %x\n",
                    628:                                       cbp->b_blkno, count, addr);
                    629: #endif
                    630:                }
                    631:                cbp->b_flags = B_BUSY | B_PHYS | (bp->b_flags & B_READ);
                    632:                sdstrategy(cbp);
                    633:                biowait(cbp);
                    634:                if (cbp->b_flags & B_ERROR) {
                    635:                        bp->b_flags |= B_ERROR;
                    636:                        bp->b_error = cbp->b_error;
                    637:                        break;
                    638:                }
                    639: done:
                    640:                bn += btodb(count);
                    641:                resid -= count;
                    642:                addr += count;
                    643: #ifdef DEBUG
                    644:                if (sddebug & SDB_PARTIAL)
                    645:                        printf(" done: bn %x resid %x addr %x\n",
                    646:                               bn, resid, addr);
                    647: #endif
                    648:        }
                    649:        free(cbuf, M_DEVBUF);
                    650:        free(cbp, M_DEVBUF);
                    651: }
                    652: 
                    653: void
                    654: sdstrategy(bp)
                    655:        register struct buf *bp;
                    656: {
                    657:        register int unit = sdunit(bp->b_dev);
                    658:        register struct sd_softc *sc = &sd_softc[unit];
                    659:        register struct partition *pinfo = &sc->sc_label.d_partitions[sdpart(bp->b_dev)];
                    660:        register struct buf *dp = &sdtab[unit];
                    661:        register daddr_t bn;
                    662:        register int sz, s;
                    663: 
                    664:        QPRINTF (("sdstrat: unit=%d [s=%d,l=%d], [b=%d,l=%d]\n", unit, 
                    665:                  pinfo->p_offset, pinfo->p_size, bp->b_blkno, bp->b_bcount));
                    666: 
                    667:        if (sc->sc_format_pid) {
                    668:                if (sc->sc_format_pid != curproc->p_pid) {      /* XXX */
                    669:                        bp->b_error = EPERM;
                    670:                        bp->b_flags |= B_ERROR;
                    671:                        goto done;
                    672:                }
                    673:                bp->b_cylin = 0;
                    674:        } else {
                    675:                bn = bp->b_blkno;
                    676:                sz = howmany(bp->b_bcount, DEV_BSIZE);
                    677:                if (bn < 0 || bn + sz > pinfo->p_size) {
                    678:                        sz = pinfo->p_size - bn;
                    679:                        if (sz == 0) {
                    680:                                bp->b_resid = bp->b_bcount;
                    681:                                goto done;
                    682:                        }
                    683:                        if (sz < 0) {
                    684:                                bp->b_error = EINVAL;
                    685:                                bp->b_flags |= B_ERROR;
                    686:                                goto done;
                    687:                        }
                    688:                        bp->b_bcount = dbtob(sz);
                    689:                }
                    690:                /*
                    691:                 * Non-aligned or partial-block transfers handled specially.
                    692:                 */
                    693:                s = sc->sc_blksize - 1;
                    694:                if ((dbtob(bn) & s) || (bp->b_bcount & s)) {
                    695:                        sdlblkstrat(bp, sc->sc_blksize);
                    696:                        goto done;
                    697:                }
                    698:                bp->b_cylin = (bn + pinfo->p_offset) >> sc->sc_bshift;
                    699:        }
                    700:        s = splbio();
                    701:        disksort(dp, bp);
                    702:        if (dp->b_active == 0) {
                    703:                dp->b_active = 1;
                    704:                sdustart(unit);
                    705:        }
                    706:        splx(s);
                    707:        return;
                    708: done:
                    709:        biodone(bp);
                    710: }
                    711: 
                    712: void
                    713: sdustart(unit)
                    714:        register int unit;
                    715: {
                    716:        if (scsireq(&sd_softc[unit].sc_dq))
                    717:                sdstart(unit);
                    718: }
                    719: 
                    720: /*
                    721:  * Return:
                    722:  *     0       if not really an error
                    723:  *     <0      if we should do a retry
                    724:  *     >0      if a fatal error
                    725:  */
                    726: static int
                    727: sderror(unit, sc, am, stat)
                    728:        int unit, stat;
                    729:        register struct sd_softc *sc;
                    730:        register struct amiga_device *am;
                    731: {
                    732:        int cond = 1;
                    733: 
                    734:        sdsense[unit].status = stat;
                    735:        if (stat & STS_CHECKCOND) {
                    736:                struct scsi_xsense *sp;
                    737: 
                    738:                scsi_request_sense(am->amiga_slave,
                    739:                                   sdsense[unit].sense,
                    740:                                   sizeof(sdsense[unit].sense));
                    741:                sp = (struct scsi_xsense *)sdsense[unit].sense;
                    742:                printf("sd%d: scsi sense class %d, code %d", unit,
                    743:                        sp->class, sp->code);
                    744:                if (sp->class == 7) {
                    745:                        printf(", key %d", sp->key);
                    746:                        if (sp->valid)
                    747:                                printf(", blk %d", *(int *)&sp->info1);
                    748:                        switch (sp->key) {
                    749:                        /* no sense, try again */
                    750:                        case 0:
                    751:                                cond = -1;
                    752:                                break;
                    753:                        /* recovered error, not a problem */
                    754:                        case 1:
                    755:                                cond = 0;
                    756:                                break;
                    757:                        }
                    758:                }
                    759:                printf("\n");
                    760:        }
                    761:        return(cond);
                    762: }
                    763: 
                    764: static void
                    765: sdfinish(unit, sc, bp)
                    766:        int unit;
                    767:        register struct sd_softc *sc;
                    768:        register struct buf *bp;
                    769: {
                    770:        sdtab[unit].b_errcnt = 0;
                    771:        sdtab[unit].b_actf = bp->b_actf;
                    772:        bp->b_resid = 0;
                    773:        biodone(bp);
                    774:        scsifree(&sc->sc_dq);
                    775:        if (sdtab[unit].b_actf)
                    776:                sdustart(unit);
                    777:        else
                    778:                sdtab[unit].b_active = 0;
                    779: }
                    780: 
                    781: void
                    782: sdstart(unit)
                    783:        register int unit;
                    784: {
                    785:        register struct sd_softc *sc = &sd_softc[unit];
                    786:        register struct amiga_device *am = sc->sc_ad;
                    787: 
                    788:        /*
                    789:         * we have the SCSI bus -- in format mode, we may or may not need dma
                    790:         * so check now.
                    791:         */
                    792:        if (sc->sc_format_pid && legal_cmds[sdcmd[unit].cdb[0]] > 0) {
                    793:                register struct buf *bp = sdtab[unit].b_actf;
                    794:                register int sts;
                    795: 
                    796:                sts = scsi_immed_command(am->amiga_slave,
                    797:                                         &sdcmd[unit],
                    798:                                         bp->b_un.b_addr, bp->b_bcount,
                    799:                                         bp->b_flags & B_READ);
                    800:                sdsense[unit].status = sts;
                    801:                if (sts & 0xfe) {
                    802:                        (void) sderror(unit, sc, am, sts);
                    803:                        bp->b_flags |= B_ERROR;
                    804:                        bp->b_error = EIO;
                    805:                }
                    806:                sdfinish(unit, sc, bp);
                    807: 
                    808:        } else if (scsiustart(am->amiga_ctlr))
                    809:                sdgo(unit);
                    810: }
                    811: 
                    812: void
                    813: sdgo(unit)
                    814:        register int unit;
                    815: {
                    816:        register struct sd_softc *sc = &sd_softc[unit];
                    817:        register struct amiga_device *am = sc->sc_ad;
                    818:        register struct buf *bp = sdtab[unit].b_actf;
                    819:        register int pad;
                    820:        register struct scsi_fmt_cdb *cmd;
                    821: 
                    822:        /* XXX ? */
                    823:        if (! bp)
                    824:          return;
                    825: 
                    826:        if (sc->sc_format_pid) {
                    827:                cmd = &sdcmd[unit];
                    828:                pad = 0;
                    829:        } else {
                    830:                cmd = bp->b_flags & B_READ? &sd_read_cmd : &sd_write_cmd;
                    831:                *(int *)(&cmd->cdb[2]) = bp->b_cylin;
                    832:                pad = howmany(bp->b_bcount, sc->sc_blksize);
                    833:                *(u_short *)(&cmd->cdb[7]) = pad;
                    834:                QPRINTF(("sdgo[%d, %d]: %s @%d >%d\n",
                    835:                         am->amiga_ctlr, am->amiga_slave,
                    836:                         bp->b_flags & B_READ ? "R" : "W",
                    837:                         bp->b_cylin, pad));
                    838:                pad = (bp->b_bcount & (sc->sc_blksize - 1)) != 0;
                    839: #ifdef DEBUG
                    840:                if (pad)
                    841:                        printf("sd%d: partial block xfer -- %x bytes\n",
                    842:                               unit, bp->b_bcount);
                    843: #endif
                    844:                sdstats[unit].sdtransfers++;
                    845:        }
                    846:        if (scsigo(am->amiga_ctlr, am->amiga_slave, bp, cmd, pad) == 0) {
                    847:                if (am->amiga_dk >= 0) {
                    848:                        dk_busy |= 1 << am->amiga_dk;
                    849:                        ++dk_seek[am->amiga_dk];
                    850:                        ++dk_xfer[am->amiga_dk];
                    851:                        dk_wds[am->amiga_dk] += bp->b_bcount >> 6;
                    852:                }
                    853:                return;
                    854:        }
                    855: #ifdef DEBUG
                    856:        if (sddebug & SDB_ERROR)
                    857:                printf("sd%d: sdstart: %s adr %d blk %d len %d ecnt %d\n",
                    858:                       unit, bp->b_flags & B_READ? "read" : "write",
                    859:                       bp->b_un.b_addr, bp->b_cylin, bp->b_bcount,
                    860:                       sdtab[unit].b_errcnt);
                    861: #endif
                    862:        bp->b_flags |= B_ERROR;
                    863:        bp->b_error = EIO;
                    864:        sdfinish(unit, sc, bp);
                    865: }
                    866: 
                    867: void
                    868: sdintr(unit, stat)
                    869:        register int unit;
                    870:        int stat;
                    871: {
                    872:        register struct sd_softc *sc = &sd_softc[unit];
                    873:        register struct buf *bp = sdtab[unit].b_actf;
                    874:        register struct amiga_device *am = sc->sc_ad;
                    875:        int cond;
                    876:        
                    877:        if (bp == NULL) {
                    878:                printf("sd%d: bp == NULL\n", unit);
                    879:                return;
                    880:        }
                    881:        if (am->amiga_dk >= 0)
                    882:                dk_busy &=~ (1 << am->amiga_dk);
                    883:        if (stat) {
                    884: #ifdef DEBUG
                    885:                if (sddebug & SDB_ERROR)
                    886:                        printf("sd%d: sdintr: bad scsi status 0x%x\n",
                    887:                                unit, stat);
                    888: #endif
                    889:                cond = sderror(unit, sc, am, stat);
                    890:                if (cond) {
                    891:                        if (cond < 0 && sdtab[unit].b_errcnt++ < SDRETRY) {
                    892: #ifdef DEBUG
                    893:                                if (sddebug & SDB_ERROR)
                    894:                                        printf("sd%d: retry #%d\n",
                    895:                                               unit, sdtab[unit].b_errcnt);
                    896: #endif
                    897:                                sdstart(unit);
                    898:                                return;
                    899:                        }
                    900:                        bp->b_flags |= B_ERROR;
                    901:                        bp->b_error = EIO;
                    902:                }
                    903:        }
                    904:        sdfinish(unit, sc, bp);
                    905: }
                    906: 
                    907: #if 1
                    908: u_int
                    909: sdminphys (bp)
                    910:        struct buf *bp;
                    911: {
                    912:        register int unit = sdunit(bp->b_dev);
                    913:        register struct sd_softc *sc = &sd_softc[unit];
                    914:        register struct partition *pinfo = &sc->sc_label.d_partitions[sdpart(bp->b_dev)];
                    915:        register daddr_t bn;
                    916:        register int sz, s;
                    917: 
                    918:        /* first restrict by max amount of physio possible */
                    919:        bp->b_bcount = min(MAXPHYS, bp->b_bcount);
                    920: 
                    921:        /* then restrict by partition size (code replicated from sdstrategy).
                    922:           Should minphys() really fiddle around with b_resid and b_flags ??? XXXX */
                    923: 
                    924:        bn = bp->b_blkno;
                    925:        sz = howmany(bp->b_bcount, DEV_BSIZE);
                    926:        if (bn < 0 || bn + sz > pinfo->p_size) 
                    927:          {
                    928:            sz = pinfo->p_size - bn;
                    929:            if (sz == 0) 
                    930:              {
                    931:                bp->b_resid = bp->b_bcount;
                    932:                goto done;
                    933:              }
                    934:            if (sz < 0) 
                    935:              {
                    936:                bp->b_error = EINVAL;
                    937:                bp->b_flags |= B_ERROR;
                    938:                goto done;
                    939:              }
                    940:            bp->b_bcount = dbtob(sz);
                    941:          }
                    942: 
                    943:        return bp->b_bcount;
                    944: done:
                    945:        return 0;
                    946: }
                    947: 
                    948: 
                    949: int
                    950: sdread(dev, uio, flags)
                    951:        dev_t dev;
                    952:        struct uio *uio;
                    953:        int flags;
                    954: {
                    955:        register int unit = sdunit(dev);
                    956:        register int pid;
                    957: 
                    958:        if ((pid = sd_softc[unit].sc_format_pid) &&
                    959:            pid != uio->uio_procp->p_pid)
                    960:                return (EPERM);
                    961:                
                    962:        return (physio(sdstrategy, NULL, dev, B_READ, sdminphys, uio));
                    963: }
                    964: 
                    965: int
                    966: sdwrite(dev, uio, flags)
                    967:        dev_t dev;
                    968:        struct uio *uio;
                    969:        int flags;
                    970: {
                    971:        register int unit = sdunit(dev);
                    972:        register int pid;
                    973: 
                    974:        if ((pid = sd_softc[unit].sc_format_pid) &&
                    975:            pid != uio->uio_procp->p_pid)
                    976:                return (EPERM);
                    977:                
                    978:        return (physio(sdstrategy, NULL, dev, B_WRITE, sdminphys, uio));
                    979: }
                    980: #endif
                    981: 
                    982: int
                    983: sdioctl(dev, cmd, data, flag, p)
                    984:        dev_t dev;
                    985:        int cmd;
                    986:        caddr_t data;
                    987:        int flag;
                    988:        struct proc *p;
                    989: {
                    990:        register int unit = sdunit(dev);
                    991:        register struct sd_softc *sc = &sd_softc[unit];
                    992:        struct disklabel *dl;
                    993:        int error;
                    994: 
                    995:        switch (cmd) {
                    996:        default:
                    997:                return (EINVAL);
                    998: 
                    999:        case DIOCGDINFO:
                   1000:                *(struct disklabel *)data = sc->sc_label;
                   1001:                return 0;
                   1002: 
                   1003:         case DIOCSDINFO:
                   1004:                 if ((flag & FWRITE) == 0)
                   1005:                  return EBADF;
                   1006: 
                   1007:                dl = (struct disklabel *)data;
                   1008:                if (error = setdisklabel(&sc->sc_label, dl, 0, 0));
                   1009:                        return error;
                   1010:                sc->sc_have_label = 1;
                   1011:                 return 0;
                   1012: 
                   1013:         case DIOCWLABEL:
                   1014:                 if ((flag & FWRITE) == 0)
                   1015:                  return EBADF;
                   1016: 
                   1017:                sc->sc_write_label = *(int *)data;
                   1018:                 return 0;
                   1019: 
                   1020:         case DIOCWDINFO:
                   1021:                 if ((flag & FWRITE) == 0)
                   1022:                  return EBADF;
                   1023: 
                   1024:                dl = (struct disklabel *)data;
                   1025: 
                   1026:                if (error = setdisklabel (&sc->sc_label, dl, 0, 0))
                   1027:                  return error;
                   1028: 
                   1029:                sc->sc_have_label = 1;
                   1030: 
                   1031: #if 0
                   1032:                old_wlabel = as->wlabel;
                   1033:                as->wlabel = 1;
                   1034:                error = writedisklabel(dev, asstrategy, &as->label,
                   1035:                                as->dospart);
                   1036:                as->wlabel = old_wlabel;
                   1037: #endif
                   1038:                return EINVAL;
                   1039: 
                   1040:        case SDIOCSFORMAT:
                   1041:                /* take this device into or out of "format" mode */
                   1042:                if (suser(p->p_ucred, &p->p_acflag))
                   1043:                        return(EPERM);
                   1044: 
                   1045:                if (*(int *)data) {
                   1046:                        if (sc->sc_format_pid)
                   1047:                                return (EPERM);
                   1048:                        sc->sc_format_pid = p->p_pid;
                   1049:                } else
                   1050:                        sc->sc_format_pid = 0;
                   1051:                return (0);
                   1052: 
                   1053:        case SDIOCGFORMAT:
                   1054:                /* find out who has the device in format mode */
                   1055:                *(int *)data = sc->sc_format_pid;
                   1056:                return (0);
                   1057: 
                   1058:        case SDIOCSCSICOMMAND:
                   1059:                /*
                   1060:                 * Save what user gave us as SCSI cdb to use with next
                   1061:                 * read or write to the char device.
                   1062:                 */
                   1063:                if (sc->sc_format_pid != p->p_pid)
                   1064:                        return (EPERM);
                   1065:                if (legal_cmds[((struct scsi_fmt_cdb *)data)->cdb[0]] == 0)
                   1066:                        return (EINVAL);
                   1067:                bcopy(data, (caddr_t)&sdcmd[unit], sizeof(sdcmd[0]));
                   1068:                return (0);
                   1069: 
                   1070:        case SDIOCSENSE:
                   1071:                /*
                   1072:                 * return the SCSI sense data saved after the last
                   1073:                 * operation that completed with "check condition" status.
                   1074:                 */
                   1075:                bcopy((caddr_t)&sdsense[unit], data, sizeof(sdsense[0]));
                   1076:                return (0);
                   1077:                
                   1078:        }
                   1079:        /*NOTREACHED*/
                   1080: }
                   1081: 
                   1082: int
                   1083: sdsize(dev)
                   1084:        dev_t dev;
                   1085: {
                   1086:        register int unit = sdunit(dev);
                   1087:        register struct sd_softc *sc = &sd_softc[unit];
                   1088: 
                   1089:        if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0)
                   1090:                return(-1);
                   1091:        return(sc->sc_label.d_partitions[sdpart(dev)].p_size);
                   1092: }
                   1093: 
                   1094: /*
                   1095:  * Non-interrupt driven, non-dma dump routine.
                   1096:  */
                   1097: int
                   1098: sddump(dev)
                   1099:        dev_t dev;
                   1100: {
                   1101:        int part = sdpart(dev);
                   1102:        int unit = sdunit(dev);
                   1103:        register struct sd_softc *sc = &sd_softc[unit];
                   1104:        register struct amiga_device *am = sc->sc_ad;
                   1105:        register daddr_t baddr;
                   1106:        register int maddr;
                   1107:        register int pages, i;
                   1108:        int stat;
                   1109:        extern int lowram;
                   1110: 
                   1111:        /*
                   1112:         * Hmm... all vax drivers dump maxfree pages which is physmem minus
                   1113:         * the message buffer.  Is there a reason for not dumping the
                   1114:         * message buffer?  Savecore expects to read 'dumpsize' pages of
                   1115:         * dump, where dumpsys() sets dumpsize to physmem!
                   1116:         */
                   1117:        pages = physmem;
                   1118: 
                   1119:        /* is drive ok? */
                   1120:        if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0)
                   1121:                return (ENXIO);
                   1122:        /* dump parameters in range? */
                   1123:        if (dumplo < 0 || dumplo >= sc->sc_label.d_partitions[part].p_size)
                   1124:                return (EINVAL);
                   1125:        if (dumplo + ctod(pages) > sc->sc_label.d_partitions[part].p_size)
                   1126:                pages = dtoc(sc->sc_label.d_partitions[part].p_size - dumplo);
                   1127:        maddr = lowram;
                   1128:        baddr = dumplo + sc->sc_label.d_partitions[part].p_offset;
                   1129:        /* scsi bus idle? */
                   1130:        if (!scsireq(&sc->sc_dq)) {
                   1131:                scsireset(/*am->amiga_ctlr*/);
                   1132:                sdreset(sc, sc->sc_ad);
                   1133:                printf("[ drive %d reset ] ", unit);
                   1134:        }
                   1135:        for (i = 0; i < pages; i++) {
                   1136: #define NPGMB  (1024*1024/NBPG)
                   1137:                /* print out how many Mbs we have dumped */
                   1138:                if (i && (i % NPGMB) == 0)
                   1139:                        printf("%d ", i / NPGMB);
                   1140: #undef NPBMG
                   1141:                pmap_enter(pmap_kernel(), vmmap, maddr, VM_PROT_READ, TRUE);
                   1142:                stat = scsi_tt_write(am->amiga_slave,
                   1143:                                     vmmap, NBPG, baddr, sc->sc_bshift);
                   1144:                if (stat) {
                   1145:                        printf("sddump: scsi write error 0x%x\n", stat);
                   1146:                        return (EIO);
                   1147:                }
                   1148:                maddr += NBPG;
                   1149:                baddr += ctod(1);
                   1150:        }
                   1151:        return (0);
                   1152: }
                   1153: #endif

unix.superglobalmegacorp.com

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