Annotation of coherent/b/STREAMS/io.386/haiSd.c, revision 1.1

1.1     ! root        1: /***********************************************************************
        !             2:  *  Module: haisd.c
        !             3:  *
        !             4:  *  Unix device driver functions for accessing SCSI hard drives as
        !             5:  *  block devices.  Conforms to Mark Williams Coherent definition of
        !             6:  *  the Unix Device Driver interface.
        !             7:  *
        !             8:  *  Copyright (c) 1993, Christopher Sean Hilton. All rights reserved.
        !             9:  *
        !            10:  *  Last Modified: Mon Jul 26 17:16:43 1993 by [chris]
        !            11:  *
        !            12:  *  This code assumes BSIZE == (1 << 9).
        !            13:  *
        !            14:  *  $Id: haisd.c,v 2.3 93/08/09 13:45:26 bin Exp Locker: bin $
        !            15:  *
        !            16:  *  $Log:      haisd.c,v $
        !            17:  * Revision 2.3  93/08/09  13:45:26  bin
        !            18:  * Kernel 82 changes
        !            19:  * 
        !            20:  */
        !            21: 
        !            22: #include <stddef.h>
        !            23: #include <sys/fdisk.h>
        !            24: #include <sys/coherent.h>
        !            25: #include <sys/buf.h>
        !            26: #include <sys/inode.h>
        !            27: #include <sys/stat.h>
        !            28: #include <sys/sched.h>
        !            29: #include <sys/sdioctl.h>    /* This is not the Coherent sdioctl.h */
        !            30: #include <sys/hdioctl.h>    /* All this is to make fdisk work... */
        !            31: #include <errno.h>
        !            32: 
        !            33: #include <sys/haiscsi.h>
        !            34: 
        !            35: #define REMOVABLE_MEDIA 0       /* Support Removable media? */
        !            36: 
        !            37: #define INQBUFSZ        64
        !            38: 
        !            39: #define SDIDLE          0
        !            40: #define SDINIT          1
        !            41: #define SDIO            2
        !            42: #define SDSENSE         3
        !            43: #define SDIOCTL         4
        !            44: 
        !            45: #define INQUIRY         0x12
        !            46: #define GETCAPACITY     0x25
        !            47: #define REQSENSE        0x03
        !            48: #define G1READ          0x28
        !            49: #define G1WRITE         0x2a
        !            50: 
        !            51: typedef struct partlim_s *partlim_p;
        !            52: 
        !            53: typedef struct partlim_s {
        !            54:     unsigned long   base;       /* base of the partition (blocks) */
        !            55:     unsigned long   size;       /* size of the partition (blocks) */
        !            56: } partlim_t;
        !            57: 
        !            58: typedef struct sdctrl_s *sdctrl_p;
        !            59: 
        !            60: typedef struct sdctrl_s {
        !            61:     unsigned short  state;
        !            62:     unsigned short  lastclose;
        !            63:     BUF             *actf,
        !            64:                     *actl;
        !            65:     srb_t           srb;
        !            66:     partlim_t       plim[1 + 4];    /* special device (1) + all partitions (4) */
        !            67:     BUF             buf;
        !            68: } sdctrl_t;
        !            69: 
        !            70: static int sdload();            /* Initialize a SCSI device at (id) */
        !            71: static void sdopen();           /* Open SCSI DASD at (dev) */
        !            72: static void sdclose();          /* Close SCSI DASD at (dev) */
        !            73: static void sdblock();          /* Block Entry Point */
        !            74: static void sdread();           /* Read SCSI DASD at (dev) */
        !            75: static void sdwrite();          /* Write SCSI DASD at (dev) */
        !            76: static void sdioctl();          /* I/O Control for DASD. */
        !            77: 
        !            78: extern int nulldev();
        !            79: extern int nonedev();
        !            80: 
        !            81: static void sdstart();
        !            82: static void sdfinish();
        !            83: 
        !            84: #define partindex(d)    ((((d) & (SPECIAL | PARTMASK)) == 0x80) ? 0 : ((d) & PARTMASK) + 1)
        !            85: 
        !            86: dca_t sddca = {
        !            87:     sdopen,         /* Open */
        !            88:     sdclose,        /* Close */
        !            89:     sdblock,        /* Block */
        !            90:     sdread,         /* Read */
        !            91:     sdwrite,        /* Write */
        !            92:     sdioctl,        /* Ioctl */
        !            93:     sdload,         /* Load */
        !            94:     nulldev,        /* Unload */
        !            95:     nulldev         /* Poll */
        !            96: };
        !            97: 
        !            98: #if REMOVABLE_MEDIA
        !            99: static int rmsdload();          /* Removable Media Disks */
        !           100: 
        !           101: dca_t rmsddca = {
        !           102:     sdopen,         /* Open */
        !           103:     sdclose,        /* Close */
        !           104:     sdblock,        /* Block */
        !           105:     sdread,         /* Read */
        !           106:     sdwrite,        /* Write */
        !           107:     sdioctl,        /* Ioctl */
        !           108:     rmsdload,       /* Load */
        !           109:     nulldev,        /* Unload */
        !           110:     nulldev         /* Poll */
        !           111: };
        !           112: #endif
        !           113: 
        !           114: static sdctrl_p sddevs[MAXDEVS];
        !           115: 
        !           116: /***********************************************************************
        !           117:  *  sdload()
        !           118:  *
        !           119:  *  Start up a DASD device at (id).
        !           120:  *
        !           121:  *  1)  Make sure that it's a disk drive and that we can support it.
        !           122:  *  2)  Get its size and blocksize to make sure that we can use it.
        !           123:  *  3)  Set up a control structure for it.
        !           124:  */
        !           125: 
        !           126: static int sdload(id)
        !           127: register int id;
        !           128: {
        !           129:     register sdctrl_p c;
        !           130:     register srb_p r;
        !           131:     int timeout;
        !           132:     char inqbuf[INQBUFSZ];
        !           133:     long diskcap[2];
        !           134: 
        !           135:        _CHIRP('Q', 143);
        !           136:     c = kalloc(sizeof(sdctrl_t));
        !           137:     if (!c) {
        !           138:         printf("\tout of memory in sdload(): ");
        !           139:         return 0;
        !           140:     }
        !           141: 
        !           142:     memset(c, 0, sizeof(sdctrl_t));
        !           143:     c->state = SDINIT;
        !           144:     r = &(c->srb);
        !           145:     r->dev = makedev(SCSIMAJOR, SPECIAL | (id << 4));
        !           146:     r->target = id;
        !           147:     r->lun = 0;
        !           148:     r->timeout = 0;
        !           149:     r->cleanup = NULL;
        !           150:     r->xferdir = DMAREAD;
        !           151: 
        !           152:     /* Request Sense to clear reset condition. */
        !           153:     r->buf. space = KRNL_ADDR;
        !           154:     r->buf. addr. caddr = (caddr_t) r->sensebuf;
        !           155:     r->buf. size = sizeof(r->sensebuf);
        !           156:     memset(&(r->cdb), 0, sizeof(cdb_t));
        !           157:     r->cdb. g0. opcode = REQSENSE;
        !           158:     r->cdb. g0. xfr_len = sizeof(r->sensebuf);
        !           159:     startscsi(r);
        !           160:     timeout = 1000000L;
        !           161:     while (r->status == ST_PENDING && --timeout > 0L)
        !           162:         ;
        !           163: 
        !           164:     if (r->status != ST_GOOD) {
        !           165:         printf("\tRequest sense failed: status (0x%x)\n", r->status);
        !           166:         kfree(c);
        !           167:         return 0;
        !           168:     }
        !           169: 
        !           170:     /* Inquiry to make sure that this is a disk drive */
        !           171:     r->buf. space = KRNL_ADDR;
        !           172:     r->buf. addr. caddr = (caddr_t) inqbuf;
        !           173:     r->buf. size = sizeof(inqbuf);
        !           174:     memset(&(r->cdb), 0, sizeof(cdb_t));
        !           175:     r->cdb. g0. opcode = INQUIRY;
        !           176:     r->cdb. g0. xfr_len = sizeof(inqbuf);
        !           177:     startscsi(r);
        !           178:     timeout = 1000000L;
        !           179:     while (r->status == ST_PENDING && --timeout > 0L)
        !           180:         ;
        !           181: 
        !           182:     if (r->status != ST_GOOD) {
        !           183:         printf("\tInquiry failed status: (0x%x)\n", r->status);
        !           184:         kfree(c);
        !           185:         return 0;
        !           186:     }
        !           187:     if (inqbuf[0] != 0) {
        !           188:         printf("\tDevice type byte: (0x%x) - not a DASD\n", inqbuf[0]);
        !           189:         kfree(c);
        !           190:         return 0;
        !           191:     }
        !           192:     else if (inqbuf[1] & 0x80) {
        !           193:         printf("\tRemovable Media Not supported yet.\n");
        !           194:         kfree(c);
        !           195:         return 0;
        !           196:     }
        !           197: 
        !           198:     /* Get Capacity to set up the drive for use */
        !           199:     r->buf. space = KRNL_ADDR;
        !           200:     r->buf. addr. caddr = (caddr_t) diskcap;
        !           201:     r->buf. size = sizeof(diskcap);
        !           202:     diskcap[0] = diskcap[1] = 0;
        !           203:     memset(&r->cdb, 0, sizeof(cdb_t));
        !           204:     r->cdb. g1. opcode = GETCAPACITY;
        !           205:     startscsi(r);
        !           206:     timeout = 1000000L;
        !           207:     while (r->status == ST_PENDING && --timeout > 0L)
        !           208:         ;
        !           209: 
        !           210:     if (r->status != ST_GOOD) {
        !           211:         printf("\tGet Capacity Failed: 0x%x\n", r->status);
        !           212:         kfree(c);
        !           213:         return 0;
        !           214:     }
        !           215:     flip(diskcap[0]);
        !           216:     flip(diskcap[1]);
        !           217:     if (diskcap[1] != BSIZE) {
        !           218:         printf("\tInvalid Block Size %d Reformat with %d Bytes/Block\n", diskcap[1], BSIZE);
        !           219:         kfree(c);
        !           220:         return 0;
        !           221:     }
        !           222: 
        !           223:     inqbuf[36] = '\0';
        !           224:     printf("\t%s %d MB\n", (inqbuf + 8), (diskcap[0] + bit(10)) >> 11);
        !           225:     sddevs[id] = c;
        !           226:     sddevs[id]->state = SDIDLE;
        !           227:     sddevs[id]->plim[0]. base = 0;
        !           228:     sddevs[id]->plim[0]. size = diskcap[0];
        !           229:     sddevs[id]->actf = sddevs[id]->actl = NULL;
        !           230:     return 1;
        !           231: }   /* sdload() */
        !           232: 
        !           233: #if REMOVABLE_MEDIA
        !           234: static int rmsdload(id)
        !           235: register int id;
        !           236: {
        !           237:     register sdctrl_p c;
        !           238:     register srb_p r;
        !           239:     int timeout;
        !           240:     long diskcap[2];
        !           241: 
        !           242:     c = kalloc(sizeof(sdctrl_t));
        !           243:     if (!c) {
        !           244:         printf("\tout of memory in rmsdload(): ");
        !           245:         return 0;
        !           246:     }
        !           247: 
        !           248:     memset(c, 0, sizeof(sdctrl_t));
        !           249:     c->state = SDINIT;
        !           250:     r = &(c->srb);
        !           251:     r->dev = makedev(SCSIMAJOR, SPECIAL | (id << 4));
        !           252:     r->target = id;
        !           253:     r->lun = 0;
        !           254:     r->timeout = 0;
        !           255:     r->cleanup = NULL;
        !           256:     r->xferdir = DMAREAD;
        !           257: 
        !           258:     /* Request Sense to clear reset condition. */
        !           259:     r->buf. space = KRNL_ADDR;
        !           260:     r->buf. addr. caddr = (caddr_t) r->sensebuf;
        !           261:     r->buf. size = sizeof(r->sensebuf);
        !           262:     memset(&(r->cdb), 0, sizeof(cdb_t));
        !           263:     r->cdb. g0. opcode = REQSENSE;
        !           264:     r->cdb. g0. xfr_len = sizeof(r->sensebuf);
        !           265:     startscsi(r);
        !           266:     timeout = 1000000L;
        !           267:     while (r->status == ST_PENDING && --timeout > 0L)
        !           268:         ;
        !           269: 
        !           270:     if (r->status != ST_GOOD) {
        !           271:         printf("\tRequest sense failed: status (0x%x)\n", r->status);
        !           272:         kfree(c);
        !           273:         return 0;
        !           274:     }
        !           275: 
        !           276:     /* Inquiry to make sure that this is a disk drive */
        !           277:     r->buf. space = KRNL_ADDR;
        !           278:     r->buf. addr. caddr = (caddr_t) c->inqbuf;
        !           279:     r->buf. size = sizeof(c->inqbuf);
        !           280:     memset(&(r->cdb), 0, sizeof(cdb_t));
        !           281:     r->cdb. g0. opcode = INQUIRY;
        !           282:     r->cdb. g0. xfr_len = sizeof(c->inqbuf);
        !           283:     startscsi(r);
        !           284:     timeout = 1000000L;
        !           285:     while (r->status == ST_PENDING && --timeout > 0L)
        !           286:         ;
        !           287: 
        !           288:     if (r->status != ST_GOOD) {
        !           289:         printf("\tInquiry failed status: (0x%x)\n", r->status);
        !           290:         kfree(c);
        !           291:         return 0;
        !           292:     }
        !           293:     if (c->inqbuf[0] != 0) {
        !           294:         printf("\tDevice type byte: (0x%x) - not a DASD\n", c->inqbuf[0]);
        !           295:         kfree(c);
        !           296:         return 0;
        !           297:     }
        !           298:     else if ((c->inqbuf[1] & 0x80) == 0)
        !           299:         printf("\tConfiguration error ID %d is fixed media.\n", id);
        !           300: 
        !           301:     /* Get Capacity to set up the drive for use */
        !           302:     r->buf. space = KRNL_ADDR;
        !           303:     r->buf. addr. caddr = (caddr_t) diskcap;
        !           304:     r->buf. size = sizeof(diskcap);
        !           305:     diskcap[0] = diskcap[1] = 0;
        !           306:     memset(&r->cdb, 0, sizeof(cdb_t));
        !           307:     r->cdb. g1. opcode = GETCAPACITY;
        !           308:     startscsi(r);
        !           309:     timeout = 1000000L;
        !           310:     while (r->status == ST_PENDING && --timeout > 0L)
        !           311:         ;
        !           312: 
        !           313:     if (r->status != ST_GOOD) {
        !           314:         printf("\tGet Capacity Failed: 0x%x\n", r->status);
        !           315:         kfree(c);
        !           316:         return 0;
        !           317:     }
        !           318:     flip(diskcap[0]);
        !           319:     flip(diskcap[1]);
        !           320:     printf("Get Capacity results count: %d, size %d\n", diskcap[0], diskcap[1]);
        !           321: /*    if (diskcap[1] != BSIZE) {
        !           322:         printf("\tInvalid Block Size %d Reformat with %d Bytes/Block\n", diskcap[1], BSIZE);
        !           323:         kfree(c);
        !           324:         return 0;
        !           325:     }
        !           326: */
        !           327:     c->inqbuf[36] = '\0';
        !           328:     printf("\t%s %d MB\n", (c->inqbuf + 8), (diskcap[0] + bit(10)) >> 11);
        !           329:     sddevs[id] = c;
        !           330:     sddevs[id]->state = SDIDLE;
        !           331:     sddevs[id]->plim[0]. base = 0;
        !           332:     sddevs[id]->plim[0]. size = diskcap[0];
        !           333:     sddevs[id]->actf = sddevs[id]->actl = NULL;
        !           334:     return 1;
        !           335: }   /* rmsdload() */
        !           336: #endif
        !           337: 
        !           338: #if 0
        !           339: /***********************************************************************
        !           340:  *  sdunload()
        !           341:  *
        !           342:  *  Unload routine.  Right now unused so ifdefed out.
        !           343:  */
        !           344: 
        !           345: static void sdunload(id)
        !           346: register int id;
        !           347: {
        !           348:     if (sddevs[id]) {
        !           349:         kfree(sddevs[id]);
        !           350:         sddevs[id] = NULL;
        !           351:     }
        !           352: }   /* sdunload() */
        !           353: #endif
        !           354: 
        !           355: /***********************************************************************
        !           356:  *  loadptable()
        !           357:  *
        !           358:  *  Read the master boot record from the Fixed disk and set the block
        !           359:  *  limits on the individual partition devices.  Wouldn't it be nice if
        !           360:  *  there were more than four partition slots available?!
        !           361:  */
        !           362: 
        !           363: static int loadptable(dev)
        !           364: register dev_t   dev;
        !           365: {
        !           366:     struct fdisk_s      fp[4];
        !           367:     register sdctrl_p   c;
        !           368:     register int        i;
        !           369: 
        !           370:     if (!partindex(dev))
        !           371:         return 0;
        !           372: 
        !           373:     if (fdisk(makedev(major(dev), (minor(dev) & ~PARTMASK) | SPECIAL), fp)) {
        !           374:         for (c = sddevs[tid(dev)], i = 1; i < 5; ++i) {
        !           375:             c->plim[i]. base = fp[i-1]. p_base;
        !           376:             c->plim[i]. size = fp[i-1]. p_size;
        !           377:         }
        !           378:         return 1;
        !           379:     }
        !           380:     else {
        !           381:         printf("fdisk failed\n");
        !           382:         return -1;
        !           383:     }
        !           384: }   /* loadptable() */
        !           385: 
        !           386: /***********************************************************************
        !           387:  *  sdopen()
        !           388:  *
        !           389:  *  Open Entry point for SCSI DASD devices.
        !           390:  */
        !           391: 
        !           392: static void sdopen(dev /*, mode */)
        !           393: dev_t   dev;
        !           394: /* int     mode; */
        !           395: {
        !           396:     register sdctrl_p c;
        !           397: 
        !           398:     c = sddevs[tid(dev)];
        !           399:     if (!c || loadptable(dev) == -1) {
        !           400:         u. u_error = ENXIO;
        !           401:         return;
        !           402:     }
        !           403:     ++c->lastclose;
        !           404:     return;
        !           405: }   /* sdopen() */
        !           406: 
        !           407: /***********************************************************************
        !           408:  *  sdclose()
        !           409:  *
        !           410:  *  Close the SCSI DASD device at dev.
        !           411:  */
        !           412: 
        !           413: static void sdclose(dev)
        !           414: dev_t   dev;
        !           415: {
        !           416:     register sdctrl_p c;
        !           417: 
        !           418:     c = sddevs[tid(dev)];
        !           419:     if (!c)
        !           420:         u. u_error = ENXIO;
        !           421:     else if (c->lastclose)
        !           422:         --c->lastclose;
        !           423: }   /* sdclose() */
        !           424: 
        !           425: /***********************************************************************
        !           426:  *  sdfinish()
        !           427:  *
        !           428:  *  Finish up a fixed disk srb.
        !           429:  */
        !           430: 
        !           431: static void sdfinish(r)
        !           432: register srb_p r;
        !           433: {
        !           434:     register sdctrl_p   c;
        !           435:     register BUF        *bp;
        !           436:     extsense_p          e;
        !           437: 
        !           438:     c = sddevs[r->target];
        !           439:     bp = c->actf;
        !           440:     switch (c->state) {
        !           441:     case SDIO:
        !           442:         switch (r->status) {
        !           443:         case ST_GOOD:
        !           444:             bp->b_resid = bp->b_count - r->buf. size;
        !           445:             break;
        !           446:         case ST_CHKCOND:
        !           447:             r->timeout = 4;
        !           448:             r->buf. space = KRNL_ADDR;
        !           449:             r->buf. addr. caddr = (caddr_t) r->sensebuf;
        !           450:             r->buf. size = sizeof(r->sensebuf);
        !           451:             r->xferdir = DMAREAD;
        !           452:             memset(&(r->cdb), 0, sizeof(cdb_t));
        !           453:             r->cdb. g0. opcode = REQSENSE;
        !           454:             r->cdb. g0. lun_lba = (r->lun << 5);
        !           455:             r->cdb. g0. xfr_len = r->buf. size;
        !           456:             if (startscsi(r))
        !           457:                 c->state = SDSENSE;
        !           458:             return;
        !           459:         default:
        !           460:             devmsg(r->dev,
        !           461:                    "%s failed at block %d: status (0x%x)",
        !           462:                    (bp->b_req == BREAD) ? "Read" : "Write",
        !           463:                    bp->b_bno,
        !           464:                    r->status);
        !           465:             bp->b_resid = bp->b_count;
        !           466:             bp->b_flag |= BFERR;
        !           467:             break;
        !           468:         }
        !           469:         break;
        !           470:     case SDSENSE:
        !           471:         if (r->status != ST_GOOD)
        !           472:             devmsg(r->dev, "%s sense failed at block %d",
        !           473:                        (bp->b_req == BREAD) ? "Read" : "Write",
        !           474:                        bp->b_bno);
        !           475:         else {
        !           476:             e = r->sensebuf;
        !           477:             printsense(r->dev,
        !           478:                        (bp->b_req == BREAD) ? "Read failed" : "Write failed",
        !           479:                        e);
        !           480:             if ((e->errorcode & 0x70) == 0x70 && (e->sensekey & 0x0f) == 0x01)
        !           481:                 bp->b_resid = bp->b_count - r->buf. size;
        !           482:             else {
        !           483:                 bp->b_resid = bp->b_count;
        !           484:                 bp->b_flag |= BFERR;
        !           485:             }
        !           486:         }
        !           487:         break;
        !           488:     default:
        !           489:         bp->b_resid = bp->b_count;
        !           490:         bp->b_flag |= BFERR;
        !           491:         break;
        !           492:     }
        !           493:     c->actf = c->actf->b_actf;
        !           494:     bdone(bp);
        !           495:     c->state = SDIDLE;
        !           496:     sdstart(c);
        !           497:     return;
        !           498: }   /* sdfinish() */
        !           499: 
        !           500: /***********************************************************************
        !           501:  *  sdstart()
        !           502:  *
        !           503:  *  Start/restart the Fixed disk request queue.
        !           504:  */
        !           505: 
        !           506: static void sdstart(c)
        !           507: sdctrl_p c;
        !           508: {
        !           509:     register BUF        *bp;
        !           510:     register g1cmd_p    g1;
        !           511:     register srb_p  r = &(c->srb);
        !           512:     unsigned long       blkcnt;
        !           513:     int                 i;
        !           514: 
        !           515:     if (!(bp = c->actf) || c->state != SDIDLE)
        !           516:         return;
        !           517: 
        !           518:     i = partindex(bp->b_dev);
        !           519:     blkcnt = bp->b_count >> 9;
        !           520:     if (bp->b_bno + blkcnt > c->plim[i]. size)
        !           521:         blkcnt = c->plim[i]. size - bp->b_bno;
        !           522: 
        !           523:     r->dev = bp->b_dev;
        !           524:     r->target = tid(bp->b_dev);
        !           525:     r->lun = lun(bp->b_dev);
        !           526:     r->timeout = 4;
        !           527:     r->buf. space = SYSGLBL_ADDR;
        !           528:     r->buf. addr. paddr = bp->b_paddr;
        !           529:     r->buf. size = (blkcnt << 9);
        !           530:     r->xferdir = (bp->b_req == BREAD) ? DMAREAD : DMAWRITE;
        !           531:     r->cleanup = &sdfinish;
        !           532:     g1 = &(r->cdb. g1);
        !           533:     memset(g1, 0, sizeof(cdb_t));
        !           534:     g1->opcode = (bp->b_req == BREAD) ? G1READ : G1WRITE;
        !           535:     g1->lun = (r->lun << 5);
        !           536:     g1->lba = c->plim[i]. base + bp->b_bno;
        !           537:     flip(g1->lba);
        !           538:     g1->xfr_len = blkcnt;
        !           539:     flip(g1->xfr_len);
        !           540:     if (startscsi(r))
        !           541:         c->state = SDIO;
        !           542: }   /* sdstart() */
        !           543: 
        !           544: /***********************************************************************
        !           545:  *  sdblock()
        !           546:  *
        !           547:  *  Block/strategy entry point for SCSI fixed disks.
        !           548:  */
        !           549: 
        !           550: static void sdblock(bp)
        !           551: register BUF    *bp;
        !           552: {
        !           553:     int i, s;
        !           554:     register sdctrl_p c;
        !           555: 
        !           556:     c = sddevs[tid(bp->b_dev)];
        !           557:     i = partindex(bp->b_dev);
        !           558: 
        !           559:     bp->b_resid = bp->b_count;
        !           560:     if (bp->b_bno > c->plim[i]. size || (bp->b_count & (BSIZE-1)) != 0) {
        !           561:         bp->b_flag |= BFERR;
        !           562:         bdone(bp);
        !           563:         return;
        !           564:     }
        !           565: 
        !           566:     if (bp->b_bno == c->plim[i]. size) {
        !           567:         if (bp->b_req != BREAD)
        !           568:             bp->b_flag |= BFERR;
        !           569:         bdone(bp);
        !           570:         return;
        !           571:     }
        !           572: 
        !           573:     s = sphi();
        !           574:     bp->b_actf = NULL;
        !           575:     if (!c->actf)
        !           576:         c->actf = bp;
        !           577:     else
        !           578:         c->actl->b_actf = bp;
        !           579:     c->actl = bp;
        !           580:     while (c->state == SDIDLE && c->actf)
        !           581:         sdstart(c);
        !           582:     spl(s);
        !           583: }   /* sdblock() */
        !           584: 
        !           585: /***********************************************************************
        !           586:  *  sdread()
        !           587:  *
        !           588:  *  Read entry point for SCSI DASD devices.
        !           589:  */
        !           590: 
        !           591: static void sdread(dev, iop)
        !           592: dev_t       dev;
        !           593: register IO *iop;
        !           594: {
        !           595:     register sdctrl_p c;
        !           596: 
        !           597:     c = sddevs[tid(dev)];
        !           598:     ioreq(&(c->buf), iop, dev, BREAD, BFIOC | BFRAW);
        !           599: }   /* sdread() */
        !           600: 
        !           601: /***********************************************************************
        !           602:  *  sdwrite()
        !           603:  *
        !           604:  *  Write entry point for SCSI DASD devices.
        !           605:  */
        !           606: 
        !           607: static void sdwrite(dev, iop)
        !           608: dev_t       dev;
        !           609: register IO *iop;
        !           610: {
        !           611:     register sdctrl_p c;
        !           612: 
        !           613:     c = sddevs[tid(dev)];
        !           614:     ioreq(&(c->buf), iop, dev, BWRITE, BFIOC | BFRAW);
        !           615: }   /* sdwrite() */
        !           616: 
        !           617: /***********************************************************************
        !           618:  *  sdioctl()
        !           619:  *
        !           620:  *  I/O Control for DASD's right now.  The options here are for the
        !           621:  *  self configuring SCSI kernel.
        !           622:  */
        !           623: 
        !           624: static void sdioctl(dev, cmd, vec)
        !           625: register dev_t  dev;
        !           626: register int    cmd;
        !           627: char            *vec;
        !           628: {
        !           629:     register sdctrl_p   c = sddevs[tid(dev)];
        !           630:     int                 s;
        !           631:     hdparm_t            hdp;
        !           632: 
        !           633:     switch (cmd) {
        !           634:     case HDGETA:
        !           635:         haihdgeta(&hdp, c->plim[0]. size);
        !           636:         kucopy(&hdp, vec, sizeof(hdparm_t));
        !           637:         break;
        !           638:     case HDSETA:
        !           639:         if (ukcopy(vec, &hdp, sizeof(hdparm_t)))
        !           640:             haihdseta(&hdp);
        !           641:         break;
        !           642:     default:
        !           643:         if (c->lastclose > 1) {
        !           644:             u. u_error = EACCES;    /* Only one open on this device */
        !           645:             return;
        !           646:         }
        !           647: 
        !           648:         s = sphi();
        !           649:         while (c->state != SDIDLE)
        !           650:             /* Where is the wakeup for this sleep? */
        !           651:             if (x_sleep(&(c->state), pridisk, slpriSigCatch, "sdioctl")) {
        !           652:                 u. u_error = EINTR;
        !           653:                 return;
        !           654:             }
        !           655:         c->state = SDIOCTL;
        !           656:         haiioctl(&(c->srb), cmd, vec);
        !           657:         c->state = SDIDLE;
        !           658:         spl(s);
        !           659:         break;
        !           660:     }
        !           661: }   /* sdioctl() */
        !           662: 
        !           663: /* End of file */

unix.superglobalmegacorp.com

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