|
|
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.