1 /* @(#)scsi-os2.c	1.26 06/11/26 Copyright 1998 J. Schilling, C. Wohlgemuth */
2 #ifndef lint
3 static	char __sccsid[] =
4 	"@(#)scsi-os2.c	1.26 06/11/26 Copyright 1998 J. Schilling, C. Wohlgemuth";
5 #endif
6 /*
7  *	Interface for the OS/2 ASPI-Router ASPIROUT.SYS ((c) D. Dorau).
8  *		This additional driver is a prerequisite for using cdrecord.
9  *		Get it from HOBBES or LEO.
10  *
11  *	Warning: you may change this source, but if you do that
12  *	you need to change the _scg_version and _scg_auth* string below.
13  *	You may not return "schily" for an SCG_AUTHOR request anymore.
14  *	Choose your name instead of "schily" and make clear that the version
15  *	string is related to a modified source.
16  *
17  *	XXX it currently uses static SRB and for this reason is not reentrant
18  *
19  *	Copyright (c) 1998 J. Schilling
20  *	Copyright (c) 1998 C. Wohlgemuth for this interface.
21  */
22 /*
23  * The contents of this file are subject to the terms of the
24  * Common Development and Distribution License, Version 1.0 only
25  * (the "License").  You may not use this file except in compliance
26  * with the License.
27  *
28  * See the file CDDL.Schily.txt in this distribution for details.
29  * A copy of the CDDL is also available via the Internet at
30  * http://www.opensource.org/licenses/cddl1.txt
31  *
32  * The following exceptions apply:
33  * CDDL �3.6 needs to be replaced by: "You may create a Larger Work by
34  * combining Covered Software with other code if all other code is governed by
35  * the terms of a license that is OSI approved (see www.opensource.org) and
36  * you may distribute the Larger Work as a single product. In such a case,
37  * You must make sure the requirements of this License are fulfilled for
38  * the Covered Software."
39  *
40  * When distributing Covered Code, include this CDDL HEADER in each
41  * file and include the License file CDDL.Schily.txt from this distribution.
42  */
43 
44 #undef	sense
45 
46 /*#define	DEBUG*/
47 
48 /* For AspiRouter */
49 #include "scg/srb_os2.h"
50 
51 /*
52  *	Warning: you may change this source, but if you do that
53  *	you need to change the _scg_version and _scg_auth* string below.
54  *	You may not return "schily" for an SCG_AUTHOR request anymore.
55  *	Choose your name instead of "schily" and make clear that the version
56  *	string is related to a modified source.
57  */
58 LOCAL	char	_scg_trans_version[] = "scsi-os2.c-1.26";	/* The version for this transport*/
59 
60 #define	FILE_OPEN			0x0001
61 #define	OPEN_SHARE_DENYREADWRITE	0x0010
62 #define	OPEN_ACCESS_READWRITE		0x0002
63 #define	DC_SEM_SHARED			0x01
64 #define	OBJ_TILE			0x0040
65 #define	PAG_READ			0x0001
66 #define	PAG_WRITE			0x0002
67 #define	PAG_COMMIT			0x0010
68 
69 typedef unsigned long LHANDLE;
70 typedef unsigned long ULONG;
71 typedef unsigned char *PSZ;
72 typedef unsigned short USHORT;
73 typedef unsigned char UCHAR;
74 
75 typedef LHANDLE	HFILE;
76 typedef ULONG	HEV;
77 
78 #define	MAX_SCG		16	/* Max # of SCSI controllers */
79 #define	MAX_TGT		16
80 #define	MAX_LUN		8
81 
82 struct scg_local {
83 	int	dummy;
84 };
85 #define	scglocal(p)	((struct scg_local *)((p)->local))
86 
87 #define	MAX_DMA_OS2	(63*1024) /* ASPI-Router allows up to 64k */
88 
89 LOCAL	void	*buffer		= NULL;
90 LOCAL	HFILE	driver_handle	= 0;
91 LOCAL	HEV	postSema	= 0;
92 
93 LOCAL	BOOL	open_driver	__PR((SCSI *scgp));
94 LOCAL	BOOL	close_driver	__PR((void));
95 LOCAL	ULONG	wait_post	__PR((ULONG ulTimeOut));
96 LOCAL	BOOL 	init_buffer	__PR((void* mem));
97 LOCAL	void	exit_func	__PR((void));
98 LOCAL	void	set_error	__PR((SRB *srb, struct scg_cmd *sp));
99 
100 
101 LOCAL void
exit_func()102 exit_func()
103 {
104 	if (!close_driver())
105 		js_fprintf(stderr, "Cannot close OS/2-ASPI-Router!\n");
106 }
107 
108 /*
109  * Return version information for the low level SCSI transport code.
110  * This has been introduced to make it easier to trace down problems
111  * in applications.
112  */
113 LOCAL char *
scgo_version(scgp,what)114 scgo_version(scgp, what)
115 	SCSI	*scgp;
116 	int	what;
117 {
118 	if (scgp != (SCSI *)0) {
119 		switch (what) {
120 
121 		case SCG_VERSION:
122 			return (_scg_trans_version);
123 		/*
124 		 * If you changed this source, you are not allowed to
125 		 * return "schily" for the SCG_AUTHOR request.
126 		 */
127 		case SCG_AUTHOR:
128 			return (_scg_auth_schily);
129 		case SCG_SCCS_ID:
130 			return (__sccsid);
131 		}
132 	}
133 	return ((char *)0);
134 }
135 
136 LOCAL int
scgo_help(scgp,f)137 scgo_help(scgp, f)
138 	SCSI	*scgp;
139 	FILE	*f;
140 {
141 	__scg_help(f, "ASPI", "Generic transport independent SCSI",
142 		"", "bus,target,lun", "1,2,0", TRUE, FALSE);
143 	return (0);
144 }
145 
146 LOCAL int
scgo_open(scgp,device)147 scgo_open(scgp, device)
148 	SCSI	*scgp;
149 	char	*device;
150 {
151 	int	busno	= scg_scsibus(scgp);
152 	int	tgt	= scg_target(scgp);
153 	int	tlun	= scg_lun(scgp);
154 
155 	if (busno >= MAX_SCG || tgt >= MAX_TGT || tlun >= MAX_LUN) {
156 		errno = EINVAL;
157 		if (scgp->errstr)
158 			js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
159 				"Illegal value for busno, target or lun '%d,%d,%d'",
160 				busno, tgt, tlun);
161 		return (-1);
162 	}
163 
164 	if ((device != NULL && *device != '\0') || (busno == -2 && tgt == -2)) {
165 		errno = EINVAL;
166 		if (scgp->errstr)
167 			js_snprintf(scgp->errstr, SCSI_ERRSTR_SIZE,
168 				"Open by 'devname' not supported on this OS");
169 		return (-1);
170 	}
171 
172 	if (scgp->local == NULL) {
173 		scgp->local = malloc(sizeof (struct scg_local));
174 		if (scgp->local == NULL)
175 			return (0);
176 	}
177 
178 	if (!open_driver(scgp))	/* Try to open ASPI-Router */
179 		return (-1);
180 	atexit(exit_func);	/* Install Exit Function which closes the ASPI-Router */
181 
182 	/*
183 	 * Success after all
184 	 */
185 	return (1);
186 }
187 
188 LOCAL int
scgo_close(scgp)189 scgo_close(scgp)
190 	SCSI	*scgp;
191 {
192 	exit_func();
193 	return (0);
194 }
195 
196 LOCAL long
scgo_maxdma(scgp,amt)197 scgo_maxdma(scgp, amt)
198 	SCSI	*scgp;
199 	long	amt;
200 {
201 	long maxdma = MAX_DMA_OS2;
202 	return (maxdma);
203 }
204 
205 LOCAL void *
scgo_getbuf(scgp,amt)206 scgo_getbuf(scgp, amt)
207 	SCSI	*scgp;
208 	long	amt;
209 {
210 	ULONG rc;
211 
212 #ifdef DEBUG
213 	js_fprintf((FILE *)scgp->errfile, "scgo_getbuf: %ld bytes\n", amt);
214 #endif
215 	rc = DosAllocMem(&buffer, amt, OBJ_TILE | PAG_READ | PAG_WRITE | PAG_COMMIT);
216 
217 	if (rc) {
218 		js_fprintf((FILE *)scgp->errfile, "Cannot allocate buffer.\n");
219 		return ((void *)0);
220 	}
221 	scgp->bufbase = buffer;
222 
223 #ifdef DEBUG
224 	js_fprintf((FILE *)scgp->errfile, "Buffer allocated at: 0x%x\n", scgp->bufbase);
225 #endif
226 
227 	/* Lock memory */
228 	if (init_buffer(scgp->bufbase))
229 		return (scgp->bufbase);
230 
231 	js_fprintf((FILE *)scgp->errfile, "Cannot lock memory buffer.\n");
232 	return ((void *)0); /* Error */
233 }
234 
235 LOCAL void
scgo_freebuf(scgp)236 scgo_freebuf(scgp)
237 	SCSI	*scgp;
238 {
239 	if (scgp->bufbase && DosFreeMem(scgp->bufbase)) {
240 		js_fprintf((FILE *)scgp->errfile,
241 		"Cannot free buffer memory for ASPI-Router!\n"); /* Free our memory buffer if not already done */
242 	}
243 	if (buffer == scgp->bufbase)
244 		buffer = NULL;
245 	scgp->bufbase = NULL;
246 }
247 
248 LOCAL int
scgo_numbus(scgp)249 scgo_numbus(scgp)
250 	SCSI	*scgp;
251 {
252 	return (MAX_SCG);
253 }
254 
255 LOCAL BOOL
scgo_havebus(scgp,busno)256 scgo_havebus(scgp, busno)
257 	SCSI	*scgp;
258 	int	busno;
259 {
260 	register int	t;
261 	register int	l;
262 
263 	if (busno < 0 || busno >= MAX_SCG)
264 		return (FALSE);
265 
266 	return (TRUE);
267 }
268 
269 LOCAL int
scgo_fileno(scgp,busno,tgt,tlun)270 scgo_fileno(scgp, busno, tgt, tlun)
271 	SCSI	*scgp;
272 	int	busno;
273 	int	tgt;
274 	int	tlun;
275 {
276 	if (busno < 0 || busno >= MAX_SCG ||
277 	    tgt < 0 || tgt >= MAX_TGT ||
278 	    tlun < 0 || tlun >= MAX_LUN)
279 		return (-1);
280 
281 	/*
282 	 * Return fake
283 	 */
284 	return (1);
285 }
286 
287 
288 LOCAL int
scgo_initiator_id(scgp)289 scgo_initiator_id(scgp)
290 	SCSI	*scgp;
291 {
292 	return (-1);
293 }
294 
295 LOCAL int
scgo_isatapi(scgp)296 scgo_isatapi(scgp)
297 	SCSI	*scgp;
298 {
299 	return (FALSE);
300 }
301 
302 
303 LOCAL int
scgo_reset(scgp,what)304 scgo_reset(scgp, what)
305 	SCSI	*scgp;
306 	int	what;
307 {
308 	ULONG	rc;				/* return value */
309 	ULONG	cbreturn;
310 	ULONG	cbParam;
311 	BOOL	success;
312 static	SRB	SRBlock;			/* XXX makes it non reentrant */
313 
314 	if (what == SCG_RESET_NOP)
315 		return (0);
316 	if (what != SCG_RESET_BUS) {
317 		errno = EINVAL;
318 		return (-1);
319 	}
320 	/*
321 	 * XXX Does this reset TGT or BUS ???
322 	 */
323 	SRBlock.cmd		= SRB_Reset;		/* reset device		*/
324 	SRBlock.ha_num		= scg_scsibus(scgp);	/* host adapter number	*/
325 	SRBlock.flags		= SRB_Post;		/* posting enabled	*/
326 	SRBlock.u.res.target	= scg_target(scgp);	/* target id		*/
327 	SRBlock.u.res.lun	= scg_lun(scgp);	/* target LUN		*/
328 
329 	rc = DosDevIOCtl(driver_handle, 0x92, 0x02, (void*) &SRBlock, sizeof (SRB), &cbParam,
330 			(void*) &SRBlock, sizeof (SRB), &cbreturn);
331 	if (rc) {
332 		js_fprintf((FILE *)scgp->errfile,
333 				"DosDevIOCtl() failed in resetDevice.\n");
334 		return (1);			/* DosDevIOCtl failed */
335 	} else {
336 		success = wait_post(40000);	/** wait for SRB being processed */
337 		if (success)
338 			return (2);
339 	}
340 	if (SRBlock.status != SRB_Done)
341 		return (3);
342 #ifdef DEBUG
343 	js_fprintf((FILE *)scgp->errfile,
344 		"resetDevice of host: %d target: %d lun: %d successful.\n", scg_scsibus(scgp), scg_target(scgp), scg_lun(scgp));
345 	js_fprintf((FILE *)scgp->errfile,
346 		"SRBlock.ha_status: 0x%x, SRBlock.target_status: 0x%x, SRBlock.satus: 0x%x\n",
347 				SRBlock.u.cmd.ha_status, SRBlock.u.cmd.target_status, SRBlock.status);
348 #endif
349 	return (0);
350 }
351 
352 /*
353  * Set error flags
354  */
355 LOCAL void
set_error(srb,sp)356 set_error(srb, sp)
357 	SRB	*srb;
358 	struct scg_cmd	*sp;
359 {
360 	switch (srb->status) {
361 
362 	case SRB_InvalidCmd:		/* 0x80 Invalid SCSI request	    */
363 	case SRB_InvalidHA:		/* 0x81 Invalid host adapter number */
364 	case SRB_BadDevice:		/* 0x82 SCSI device not installed   */
365 		sp->error = SCG_FATAL;
366 		sp->ux_errno = EINVAL;	/* Should we ever return != EIO	    */
367 		sp->ux_errno = EIO;
368 		break;
369 
370 
371 	case SRB_Busy:			/* 0x00 SCSI request in progress    */
372 	case SRB_Aborted:		/* 0x02 SCSI aborted by host	    */
373 	case SRB_BadAbort:		/* 0x03 Unable to abort SCSI request */
374 	case SRB_Error:			/* 0x04 SCSI request completed with error */
375 	default:
376 		sp->error = SCG_RETRYABLE;
377 		sp->ux_errno = EIO;
378 		break;
379 	}
380 }
381 
382 LOCAL int
scgo_send(scgp)383 scgo_send(scgp)
384 	SCSI	*scgp;
385 {
386 	struct scg_cmd	*sp = scgp->scmd;
387 	ULONG	rc;				/* return value */
388 static	SRB	SRBlock;			/* XXX makes it non reentrant */
389 	Ulong	cbreturn;
390 	Ulong	cbParam;
391 	UCHAR*	ptr;
392 
393 	if (scgp->fd < 0) {			/* Set in scgo_open() */
394 		sp->error = SCG_FATAL;
395 		return (0);
396 	}
397 
398 	if (sp->cdb_len > sizeof (SRBlock.u.cmd.cdb_st)) { /* commandsize too big */
399 		sp->error = SCG_FATAL;
400 		sp->ux_errno = EINVAL;
401 		js_fprintf((FILE *)scgp->errfile,
402 			"sp->cdb_len > SRBlock.u.cmd.cdb_st. Fatal error in scgo_send, exiting...\n");
403 		return (-1);
404 	}
405 
406 	/* clear command block */
407 	fillbytes((caddr_t)&SRBlock.u.cmd.cdb_st, sizeof (SRBlock.u.cmd.cdb_st), '\0');
408 	/* copy cdrecord command into SRB */
409 	movebytes(&sp->cdb, &SRBlock.u.cmd.cdb_st, sp->cdb_len);
410 
411 	/* Build SRB command block */
412 	SRBlock.cmd = SRB_Command;
413 	SRBlock.ha_num = scg_scsibus(scgp);	/* host adapter number */
414 
415 	SRBlock.flags = SRB_Post;		/* flags */
416 
417 	SRBlock.u.cmd.target	= scg_target(scgp); /* Target SCSI ID */
418 	SRBlock.u.cmd.lun	= scg_lun(scgp); /* Target SCSI LUN */
419 	SRBlock.u.cmd.data_len	= sp->size;	/* # of bytes transferred */
420 	SRBlock.u.cmd.data_ptr	= 0;		/* pointer to data buffer */
421 	SRBlock.u.cmd.sense_len	= sp->sense_len; /* length of sense buffer */
422 
423 	SRBlock.u.cmd.link_ptr	= 0;		/* pointer to next SRB */
424 	SRBlock.u.cmd.cdb_len	= sp->cdb_len;	/* SCSI command length */
425 
426 	/* Specify direction */
427 	if (sp->flags & SCG_RECV_DATA) {
428 		SRBlock.flags |= SRB_Read;
429 	} else {
430 		if (sp->size > 0) {
431 			SRBlock.flags |= SRB_Write;
432 			if (scgp->bufbase != sp->addr) { /* Copy only if data not in ASPI-Mem */
433 				movebytes(sp->addr, scgp->bufbase, sp->size);
434 			}
435 		} else {
436 			SRBlock.flags |= SRB_NoTransfer;
437 		}
438 	}
439 	sp->error	= SCG_NO_ERROR;
440 	sp->sense_count	= 0;
441 	sp->u_scb.cmd_scb[0] = 0;
442 	sp->resid	= 0;
443 
444 	/* execute SCSI	command */
445 	rc = DosDevIOCtl(driver_handle, 0x92, 0x02,
446 			(void*) &SRBlock, sizeof (SRB), &cbParam,
447 			(void*) &SRBlock, sizeof (SRB), &cbreturn);
448 
449 	if (rc) {		/* An error occured */
450 		js_fprintf((FILE *)scgp->errfile,
451 				"DosDevIOCtl() in sendCommand failed.\n");
452 		sp->error = SCG_FATAL;
453 		sp->ux_errno = EIO;	/* Sp�ter vielleicht errno einsetzen */
454 		return (rc);
455 	} else {
456 		/* Wait until the command is processed */
457 		rc = wait_post(sp->timeout*1000);
458 		if (rc) {	/* An error occured */
459 			if (rc == 640) {
460 				/* Timeout */
461 				sp->error = SCG_TIMEOUT;
462 				sp->ux_errno = EIO;
463 				js_fprintf((FILE *)scgp->errfile,
464 						"Timeout during SCSI-Command.\n");
465 				return (1);
466 			}
467 			sp->error = SCG_FATAL;
468 			sp->ux_errno = EIO;
469 			js_fprintf((FILE *)scgp->errfile,
470 					"Fatal Error during DosWaitEventSem().\n");
471 			return (1);
472 		}
473 
474 		/* The command is processed */
475 		if (SRBlock.status == SRB_Done) {	/* succesful completion */
476 #ifdef DEBUG
477 			js_fprintf((FILE *)scgp->errfile,
478 				"Command successful finished. SRBlock.status=0x%x\n\n", SRBlock.status);
479 #endif
480 			sp->sense_count = 0;
481 			sp->resid = 0;
482 			if (sp->flags & SCG_RECV_DATA) {	/* We read data */
483 				if (sp->addr && sp->size) {
484 					if (scgp->bufbase != sp->addr)	/* Copy only if data not in ASPI-Mem */
485 						movebytes(scgp->bufbase, sp->addr, SRBlock.u.cmd.data_len);
486 					ptr = (UCHAR*)sp->addr;
487 					sp->resid = sp->size - SRBlock.u.cmd.data_len; /*nicht �bertragene bytes. Korrekt berechnet???*/
488 				}
489 			}	/* end of if (sp->flags & SCG_RECV_DATA) */
490 			if (SRBlock.u.cmd.target_status == SRB_CheckStatus) { /* Sense data valid */
491 				sp->sense_count	= (int)SRBlock.u.cmd.sense_len;
492 				if (sp->sense_count > sp->sense_len)
493 					sp->sense_count = sp->sense_len;
494 
495 				ptr = (UCHAR*)&SRBlock.u.cmd.cdb_st;
496 				ptr += SRBlock.u.cmd.cdb_len;
497 
498 				fillbytes(&sp->u_sense.Sense, sizeof (sp->u_sense.Sense), '\0');
499 				movebytes(ptr, &sp->u_sense.Sense, sp->sense_len);
500 
501 				sp->u_scb.cmd_scb[0] = SRBlock.u.cmd.target_status;
502 				sp->ux_errno = EIO;	/* Sp�ter differenzieren? */
503 			}
504 			return (0);
505 		}
506 		/* SCSI-Error occured */
507 		set_error(&SRBlock, sp);
508 
509 		if (SRBlock.u.cmd.target_status == SRB_CheckStatus) {	/* Sense data valid */
510 			sp->sense_count	= (int)SRBlock.u.cmd.sense_len;
511 			if (sp->sense_count > sp->sense_len)
512 				sp->sense_count = sp->sense_len;
513 
514 			ptr = (UCHAR*)&SRBlock.u.cmd.cdb_st;
515 			ptr += SRBlock.u.cmd.cdb_len;
516 
517 			fillbytes(&sp->u_sense.Sense, sizeof (sp->u_sense.Sense), '\0');
518 			movebytes(ptr, &sp->u_sense.Sense, sp->sense_len);
519 
520 			sp->u_scb.cmd_scb[0] = SRBlock.u.cmd.target_status;
521 		}
522 		if (sp->flags & SCG_RECV_DATA) {
523 			if (sp->addr && sp->size) {
524 				if (scgp->bufbase != sp->addr)	/* Copy only if data not in ASPI-Mem */
525 					movebytes(scgp->bufbase, sp->addr, SRBlock.u.cmd.data_len);
526 			}
527 		}
528 #ifdef	really
529 		sp->resid	= SRBlock.u.cmd.data_len; /* XXXXX Got no Data ????? */
530 #else
531 		sp->resid	= sp->size - SRBlock.u.cmd.data_len;
532 #endif
533 		return (1);
534 	}
535 }
536 
537 /***************************************************************************
538  *									   *
539  *  BOOL open_driver()							   *
540  *									   *
541  *  Opens the ASPI Router device driver and sets device_handle.		   *
542  *  Returns:								   *
543  *    TRUE - Success							   *
544  *    FALSE - Unsuccessful opening of device driver			   *
545  *									   *
546  *  Preconditions: ASPI Router driver has be loaded			   *
547  *									   *
548  ***************************************************************************/
549 LOCAL BOOL
open_driver(scgp)550 open_driver(scgp)
551 	SCSI	*scgp;
552 {
553 	ULONG	rc;			/* return value */
554 	ULONG	ActionTaken;		/* return value	*/
555 	USHORT	openSemaReturn;		/* return value	*/
556 	ULONG	cbreturn;
557 	ULONG	cbParam;
558 
559 	if (driver_handle)		/* ASPI-Router already opened	*/
560 		return (TRUE);
561 
562 	rc = DosOpen((PSZ) "aspirou$",	/* open driver*/
563 			&driver_handle,
564 			&ActionTaken,
565 			0,
566 			0,
567 			FILE_OPEN,
568 			OPEN_SHARE_DENYREADWRITE | OPEN_ACCESS_READWRITE,
569 			NULL);
570 	if (rc) {
571 		js_fprintf((FILE *)scgp->errfile,
572 				"Cannot open ASPI-Router!\n");
573 
574 		return (FALSE);		/* opening failed -> return false*/
575 	}
576 
577 	/* Init semaphore */
578 	if (DosCreateEventSem(NULL, &postSema,	/* create event semaphore */
579 				DC_SEM_SHARED, 0)) {
580 		DosClose(driver_handle);
581 		js_fprintf((FILE *)scgp->errfile,
582 				"Cannot create event semaphore!\n");
583 
584 		return (FALSE);
585 	}
586 	rc = DosDevIOCtl(driver_handle, 0x92, 0x03,	/* pass semaphore handle */
587 			(void*) &postSema, sizeof (HEV), /* to driver		 */
588 			&cbParam, (void*) &openSemaReturn,
589 			sizeof (USHORT), &cbreturn);
590 
591 	if (rc||openSemaReturn) {			/* Error */
592 		DosCloseEventSem(postSema);
593 		DosClose(driver_handle);
594 		return (FALSE);
595 	}
596 	return (TRUE);
597 }
598 
599 /***************************************************************************
600  *									   *
601  *  BOOL close_driver()							   *
602  *									   *
603  *  Closes the device driver						   *
604  *  Returns:								   *
605  *    TRUE - Success							   *
606  *    FALSE - Unsuccessful closing of device driver			   *
607  *									   *
608  *  Preconditions: ASPI Router driver has be opened with open_driver	   *
609  *									   *
610  ***************************************************************************/
611 LOCAL BOOL
close_driver()612 close_driver()
613 {
614 	ULONG rc;				/* return value */
615 
616 	if (driver_handle) {
617 		rc = DosClose(driver_handle);
618 		if (rc)
619 			return (FALSE);		/* closing failed -> return false */
620 		driver_handle = 0;
621 		if (DosCloseEventSem(postSema))
622 			js_fprintf(stderr, "Cannot close event semaphore!\n");
623 		if (buffer && DosFreeMem(buffer)) {
624 			js_fprintf(stderr,
625 			"Cannot free buffer memory for ASPI-Router!\n"); /* Free our memory buffer if not already done */
626 		}
627 		buffer = NULL;
628 	}
629 	return (TRUE);
630 }
631 
632 LOCAL ULONG
wait_post(ULONG ulTimeOut)633 wait_post(ULONG ulTimeOut)
634 {
635 	ULONG count = 0;
636 	ULONG rc;					/* return value */
637 
638 /*	rc = DosWaitEventSem(postSema, -1);*/		/* wait forever*/
639 	rc = DosWaitEventSem(postSema, ulTimeOut);
640 	DosResetEventSem(postSema, &count);
641 	return (rc);
642 }
643 
644 LOCAL BOOL
init_buffer(mem)645 init_buffer(mem)
646 	void	*mem;
647 {
648 	ULONG	rc;					/* return value */
649 	USHORT lockSegmentReturn;			/* return value */
650 	Ulong	cbreturn;
651 	Ulong	cbParam;
652 
653 	rc = DosDevIOCtl(driver_handle, 0x92, 0x04,	/* pass buffers pointer */
654 			(void*) mem, sizeof (void*),	/* to driver */
655 			&cbParam, (void*) &lockSegmentReturn,
656 			sizeof (USHORT), &cbreturn);
657 	if (rc)
658 		return (FALSE);				/* DosDevIOCtl failed */
659 	if (lockSegmentReturn)
660 		return (FALSE);				/* Driver could not lock segment */
661 	return (TRUE);
662 }
663 #define	sense	u_sense.Sense
664