Annotation of driverkit/libDriver/User/volDriver.m, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
        !             3:  *
        !             4:  * @APPLE_LICENSE_HEADER_START@
        !             5:  * 
        !             6:  * Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
        !             7:  * Reserved.  This file contains Original Code and/or Modifications of
        !             8:  * Original Code as defined in and that are subject to the Apple Public
        !             9:  * Source License Version 1.1 (the "License").  You may not use this file
        !            10:  * except in compliance with the License.  Please obtain a copy of the
        !            11:  * License at http://www.apple.com/publicsource and read it before using
        !            12:  * this file.
        !            13:  * 
        !            14:  * The Original Code and all software distributed under the License are
        !            15:  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
        !            16:  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
        !            17:  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
        !            18:  * FITNESS FOR A PARTICULAR PURPOSE OR NON- INFRINGEMENT.  Please see the
        !            19:  * License for the specific language governing rights and limitations
        !            20:  * under the License.
        !            21:  * 
        !            22:  * @APPLE_LICENSE_HEADER_END@
        !            23:  */
        !            24: /*     Copyright (c) 1991 NeXT Computer, Inc.  All rights reserved. 
        !            25:  *
        !            26:  * volDriver.m - user-level "emulation" of vol driver. 
        !            27:  *
        !            28:  * a signal 14 delivered to this executable results in a panel response
        !            29:  * action, which is interpreted as a "disk not available" by volCheck.
        !            30:  *
        !            31:  * a signal 1 delivered causes the same action as the death of the 
        !            32:  * WorkSpace - all pending panel requests are ack'd.
        !            33:  *
        !            34:  * HISTORY
        !            35:  * 09-May-91    Doug Mitchell at NeXT
        !            36:  *      Created.
        !            37:  */
        !            38: 
        !            39: #undef DRIVER_PRIVATE
        !            40: #define DRIVER_PRIVATE
        !            41: 
        !            42: #import <objc/objc.h>
        !            43: #import <bsd/sys/types.h>
        !            44: #import <mach/cthreads.h>      /* FIXME - for ASSERT for MD includes...*/
        !            45: #import <kernserv/queue.h>
        !            46: #import <driverkit/generalFuncs.h>
        !            47: #import <bsd/sys/signal.h>
        !            48: #import <driverkit/Device_ddm.h>
        !            49: #import <machkit/NXLock.h>
        !            50: #import <driverkit/volCheck.h>
        !            51: #import "volCheckPrivate.h"
        !            52: #import "volDriver.h"
        !            53: 
        !            54: /*
        !            55:  * Struct for maintaining state of panel requests.
        !            56:  */
        !            57: typedef struct {
        !            58:         queue_chain_t           link;
        !            59:         int                     tag;
        !            60:         vpt_func                fnc;            /* to be called upon receipt of
        !            61:                                                  * vol_panel_resp message */    
        !            62:         void                    *param;
        !            63: } vol_panel_entry_t;
        !            64: 
        !            65: /*
        !            66:  * static data.
        !            67:  */
        !            68: static int volDriverTag;
        !            69: static queue_head_t volDriverPanelQ;
        !            70: static id volDriverLock;               // NXLock - protects above
        !            71: 
        !            72: /*
        !            73:  * Static function prototypes.
        !            74:  */
        !            75: static char *diskTypeToString(int diskType);
        !            76: static char *volStateToString(int volState);
        !            77: static vol_panel_entry_t *vol_panel_get_entry(int tag);
        !            78: static void volDriverSig(int foo);
        !            79: static void volDriverWSDeath(int foo);
        !            80: 
        !            81: /*
        !            82:  * One-time only init.
        !            83:  */
        !            84: void volDriverInit()
        !            85: {
        !            86:        queue_init(&volDriverPanelQ);
        !            87:        volDriverLock = [NXLock new];
        !            88:        signal(SIGALRM, volDriverSig);
        !            89:        signal(SIGHUP, volDriverWSDeath);
        !            90: }
        !            91: 
        !            92: kern_return_t vol_notify_dev(dev_t block_dev, 
        !            93:        dev_t raw_dev,
        !            94:        const char *form_type,
        !            95:        int vol_state,                          /* IND_VS_LABEL, etc. */
        !            96:        const char *dev_str,
        !            97:        int flags)
        !            98: {
        !            99:        
        !           100:        IOLog("Disk Insertion: block_dev 0x%x vol_state %s\n",
        !           101:                block_dev, volStateToString(vol_state));
        !           102:        return(KERN_SUCCESS);
        !           103: }
        !           104: 
        !           105: /*
        !           106:  * Cancel notification message. Called on 'mount' of device.
        !           107:  */
        !           108: void vol_notify_cancel(dev_t device)
        !           109: {
        !           110:        IOLog("Cancelling Alert for dev 0x%x\n", device);
        !           111: }
        !           112: 
        !           113: kern_return_t vol_panel_request(vpt_func fnc,
        !           114:        int panel_type,                         /* PR_PT_DISK_NUM, etc. */
        !           115:        int response_type,                      /* PR_RT_ACK, atc. */
        !           116:        int p1,
        !           117:        int p2,
        !           118:        int p3,
        !           119:        int p4,
        !           120:        char *string1,
        !           121:        char *string2,
        !           122:        void *param,
        !           123:        int *tag)                               /* RETURNED */
        !           124: {
        !           125:        char *disk_string = diskTypeToString(p2);
        !           126:        vol_panel_entry_t *vpe;
        !           127:        
        !           128:        [volDriverLock lock];
        !           129:        
        !           130:        /*
        !           131:         * Record this panel in case of ack or cancel.
        !           132:         */
        !           133:        vpe = IOMalloc(sizeof(*vpe));
        !           134:        vpe->tag = volDriverTag;
        !           135:        vpe->fnc = fnc;
        !           136:        vpe->param = param;
        !           137:        queue_enter(&volDriverPanelQ,
        !           138:                vpe,
        !           139:                vol_panel_entry_t *,
        !           140:                link);
        !           141:                
        !           142:        switch(panel_type) {
        !           143:            case PR_PT_DISK_NUM:
        !           144:                IOLog("Please Insert %s Disk %d in Drive %d (tag %d)\n", 
        !           145:                        disk_string, p1, p3, volDriverTag);
        !           146:                break;
        !           147:            case PR_PT_DISK_LABEL:
        !           148:                IOLog("Please Insert %s Disk \'%s\' in Drive %d (tag %d)\n", 
        !           149:                        disk_string, string1, p3);
        !           150:                break;
        !           151:            case PR_PT_DISK_NUM_W:
        !           152:                IOLog("Wrong Disk: Please Insert %s Disk %d in Drive "
        !           153:                        "%d (tag %d)\n", disk_string, p1, p3);
        !           154:                break;
        !           155:            case PR_PT_DISK_LABEL_W:
        !           156:                IOLog("Wrong Disk: Please Insert %s Disk \'%s\' in "
        !           157:                        "Drive %d (tag %d)\n", disk_string, string1, p3);
        !           158:                break;
        !           159:            case PR_PT_SWAPDEV_FULL:
        !           160:                IOLog("***Swap Device Full***\n");
        !           161:                break;
        !           162:            case PR_PT_FILESYS_FULL:
        !           163:                IOLog("***File System %s Full***\n", string1);
        !           164:                break;
        !           165:            case PR_RT_EJECT_REQ:
        !           166:                IOLog("Please Eject %s Disk %d (tag %d)\n", disk_string, p3);
        !           167:                break;
        !           168:            default:
        !           169:                /* FIXME: what do we do here? */
        !           170:                IOLog("vol_panel_request: bogus panel_type (%d)\n",
        !           171:                        panel_type);
        !           172:                break;
        !           173:        }
        !           174:        *tag = volDriverTag++;
        !           175:        [volDriverLock unlock];
        !           176:        
        !           177:        return(KERN_SUCCESS);
        !           178: }
        !           179: 
        !           180: kern_return_t vol_panel_disk_num(vpt_func fnc,
        !           181:        int volume_num,
        !           182:        int drive_type,                         /* PR_DRIVE_FLOPPY, etc. */
        !           183:        int drive_num,
        !           184:        void *param,
        !           185:        boolean_t wrong_disk,
        !           186:        int *tag)                               /* RETURNED */
        !           187: {
        !           188:         return(vol_panel_request(fnc,
        !           189:                 wrong_disk ? PR_PT_DISK_NUM_W : PR_PT_DISK_NUM,
        !           190:                 PR_RT_ACK,
        !           191:                 volume_num,
        !           192:                 drive_type,
        !           193:                 drive_num,
        !           194:                 0,
        !           195:                 "",
        !           196:                 "",
        !           197:                 param,
        !           198:                 tag));  
        !           199: 
        !           200: }
        !           201: kern_return_t vol_panel_disk_label(vpt_func fnc,
        !           202:        char *label,
        !           203:        int drive_type,                         /* PR_DRIVE_FLOPPY, etc. */
        !           204:        int drive_num,
        !           205:        void *param,
        !           206:        boolean_t wrong_disk,
        !           207:        int *tag)                               /* RETURNED */
        !           208: {
        !           209:        return(vol_panel_request(fnc,
        !           210:                 wrong_disk ? PR_PT_DISK_LABEL_W : PR_PT_DISK_LABEL,
        !           211:                 PR_RT_ACK,
        !           212:                 0,
        !           213:                 drive_type,
        !           214:                 drive_num,
        !           215:                 0,
        !           216:                 label,
        !           217:                 "",
        !           218:                 param,
        !           219:                 tag));
        !           220: }
        !           221: 
        !           222: /*
        !           223:  * Remove an alert panel. Called upon detection of desired disk after putting
        !           224:  * up an alert panel.
        !           225:  */
        !           226: kern_return_t vol_panel_remove(int tag)
        !           227: {
        !           228:        vol_panel_entry_t *vpe;
        !           229: 
        !           230:        [volDriverLock lock];
        !           231:        vpe = vol_panel_get_entry(tag);
        !           232:        if(vpe == NULL) {
        !           233:                IOLog("vol_panel_remove: Nonexistent panel (tag %d)\n",
        !           234:                        tag);
        !           235:        }
        !           236:        else {
        !           237:                IOLog("volDriver: removing panel for tag %d\n", tag);
        !           238:                IOFree(vpe, sizeof(*vpe));
        !           239:        }
        !           240:        [volDriverLock unlock];
        !           241:        return(KERN_SUCCESS);
        !           242: }
        !           243: 
        !           244: /*
        !           245:  * Private functions.
        !           246:  */
        !           247:  
        !           248: static char *diskTypeToString(int diskType)
        !           249: {
        !           250:        switch(diskType) {
        !           251:            case PR_DRIVE_FLOPPY:
        !           252:                return("Floppy");
        !           253:            case PR_DRIVE_OPTICAL:
        !           254:                return("Optical");
        !           255:            case PR_DRIVE_SCSI:
        !           256:                return("SCSI");
        !           257:            default: 
        !           258:                return("");
        !           259:        }
        !           260: }
        !           261: 
        !           262: static char *volStateToString(int volState)
        !           263: {
        !           264:        switch(volState) {
        !           265:            case IND_VS_LABEL:
        !           266:                return("IND_VS_LABEL");
        !           267:            case IND_VS_FORMATTED:
        !           268:                return("IND_VS_FORMATTED");
        !           269:            case IND_VS_UNFORMATTED:
        !           270:                return("IND_VS_UNFORMATTED");
        !           271:            default:
        !           272:                return("Unknown volState");
        !           273:        }
        !           274: }
        !           275: 
        !           276: static vol_panel_entry_t *vol_panel_get_entry(int tag) {
        !           277: 
        !           278:         /*
        !           279:          * get and remove vol_panel_entry associated with 'tag' from 
        !           280:         * volDriverPanelQ. Returns NULL if entry not found.
        !           281:         * volDriverLock should be held on entry.
        !           282:          */
        !           283:         
        !           284:         vol_panel_entry_t *vpe;
        !           285: 
        !           286:         vpe = (vol_panel_entry_t *)queue_first(&volDriverPanelQ);
        !           287:         while(!queue_end(&volDriverPanelQ, (queue_entry_t)vpe)) {
        !           288:                 if(vpe->tag == tag) {
        !           289:                         /*
        !           290:                          * Found it. 
        !           291:                          */
        !           292:                         queue_remove(&volDriverPanelQ,
        !           293:                                 vpe,
        !           294:                                 vol_panel_entry_t *,
        !           295:                                 link);
        !           296:                         return(vpe);
        !           297:                 }
        !           298:                 vpe = (vol_panel_entry_t *)vpe->link.next;
        !           299:         }
        !           300:         /*
        !           301:          * Not found. 
        !           302:          */
        !           303:         return(NULL);
        !           304: }
        !           305: 
        !           306: /*
        !           307:  * Signal catcher to emulate WS's panel response message. All we can do
        !           308:  * is cancel the last request which went out.
        !           309:  */
        !           310: static void volDriverSig(int foo)
        !           311: {
        !           312:        vol_panel_entry_t *vpe;
        !           313:        
        !           314:        [volDriverLock lock];
        !           315:        vpe = vol_panel_get_entry(volDriverTag - 1);
        !           316:        if(vpe == NULL) {
        !           317:                IOLog("volDriverSig: Couldn't find entry for tag %d\n",
        !           318:                        volDriverTag - 1);
        !           319:                goto done;
        !           320:        }
        !           321:        /*
        !           322:         * Perform callout if necessary, then dispose of entry.
        !           323:         */
        !           324:        xpr_vc("volDriverSig: doing VOL_PANEL_RESP callout\n", 1,2,3,4,5);
        !           325:        if(vpe->fnc) {
        !           326:                (*vpe->fnc)(vpe->param, 
        !           327:                        vpe->tag, 
        !           328:                        0);             // 'value'
        !           329:        }
        !           330:        IOFree(vpe, sizeof(*vpe));
        !           331: done:
        !           332:        [volDriverLock unlock];
        !           333:        return;
        !           334: }
        !           335: 
        !           336: /*
        !           337:  * Signal catcher to abort all pending panels. Emulates death of workspace.
        !           338:  */
        !           339: static void volDriverWSDeath(int foo)
        !           340: {
        !           341:        vol_panel_entry_t *vpe;
        !           342: 
        !           343:        /*
        !           344:         * Ack and dispose of every vol_panel_entry in volDriverPanelQ.
        !           345:         */
        !           346:        xpr_vc("volDriverWSDeath\n", 1,2,3,4,5);
        !           347:        while(!queue_empty(&volDriverPanelQ)) {
        !           348:                vpe = (vol_panel_entry_t *)queue_first(&volDriverPanelQ);
        !           349:                queue_remove(&volDriverPanelQ,
        !           350:                        vpe,
        !           351:                        vol_panel_entry_t *,
        !           352:                        link);
        !           353:                xpr_vc("volDriverWSDeath: doing VOL_PANEL_RESP "
        !           354:                        "callout\n", 1,2,3,4,5);
        !           355:                if(vpe->fnc) {
        !           356:                        (*vpe->fnc)(vpe->param, 
        !           357:                                vpe->tag, 
        !           358:                                0);        /* as in "disk not 
        !           359:                                            * available" */
        !           360:                }
        !           361:                IOFree(vpe, sizeof(*vpe));
        !           362:        }
        !           363: }
        !           364: 
        !           365: static int manual_poll;
        !           366: 
        !           367: int vol_check_manual_poll()
        !           368: {
        !           369:        if(manual_poll) {
        !           370:                manual_poll = 0;
        !           371:                return(1);
        !           372:        }
        !           373:        else {
        !           374:                return(0);
        !           375:        }
        !           376: }
        !           377: 
        !           378: /*
        !           379:  * Internal version of ioctl(DKIOCCHECKINSERT).
        !           380:  */
        !           381: void vol_check_set_poll()
        !           382: {
        !           383:        manual_poll = 1;
        !           384: }

unix.superglobalmegacorp.com

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