|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.