Annotation of driverkit/libDriver/User/volDriver.m, revision 1.1.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.