File:  [MW Coherent from dump] / coherent / d / PS2_KERNEL / io.286 / shmcon.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Wed May 29 04:56:39 2019 UTC (7 years ago) by root
Branches: MarkWilliams, MAIN
CVS tags: relic, HEAD
coherent

/* $Header: /var/lib/cvsd/repos/coherent/coherent/d/PS2_KERNEL/io.286/shmcon.c,v 1.1.1.1 2019/05/29 04:56:39 root Exp $
 *
 *	The  information  contained herein  is a trade secret  of INETCO
 *	Systems, and is confidential information.   It is provided under
 *	a license agreement,  and may be copied or disclosed  only under
 *	the terms of that agreement.   Any reproduction or disclosure of
 *	this  material  without  the express  written  authorization  of
 *	INETCO Systems or persuant to the license agreement is unlawful.
 *
 *	Copyright (c) 1987, 1985, 1984.
 *	An unpublished work by INETCO Systems, Ltd.
 *	All rights reserved.
 */

/*
 * System V Compatible Shared Memory Device Driver
 *
 *	This device driver provides System V compatible shared memory operations.
 *	Operations are performed through the shared memory device (/dev/shm).
 *	and are implemented as ioctl calls from shmctl, shmget, shmat, shmdt
 *	utilities.
 *
 *			Author: Allan Cornish, INETCO Systems Ltd., Sep 1984
 *
 * $Log: shmcon.c,v $
 * Revision 1.1.1.1  2019/05/29 04:56:39  root
 * coherent
 *
 * Revision 1.1  92/07/17  15:24:47  bin
 * Initial revision
 * 
 * Revision 2.1	88/09/03  13:12:40	src
 * *** empty log message ***
 * 
 * Revision 1.1	88/03/24  17:06:36	src
 * Initial revision
 * 
 * 87/03/02	Allan Cornish		/usr/src/sys/i8086/drv/shmcon.c
 * Shmioctl() now supports long key [was short] on SHMGET operations.
 * This allows compatability with System V.
 *
 * 85/10/16	Allan Cornish
 * Driver split into shmcon.c, shm.c [driver implementation, system V shm].
 *
 * 85/07/22	Allan Cornish
 * Shmget, shmctl now return immediately if u.u_error is set.
 *
 * 85/07/19	Allan Cornish
 * Separation of io_seek into shmid and off improved through type casting.
 * Errno set to EFAULT if fucopy() or ufcopy() report no bytes transferred.
 * This would occur if an user address fault occurred.
 *
 * 85/07/03	Allan Cornish
 * Replaced use of EDOM with EIDRM.
 * Replaced shmaccess() by calls to ipcaccess(), increasing shared ipc code.
 * Eliminated shmlock() and shmunlock(), as shared memory use is synchronous.
 *
 * 84/09/30	Allan Cornish
 * Initial Revision.
 */

#include <coherent.h>
#include <sched.h>
#include <types.h>
#include <errno.h>
#include <stat.h>
#include <con.h>
#include <seg.h>
#include <shm.h>

#ifndef	EIDRM
#define	EIDRM	EDOM
#endif

/*
 * Functions.
 */

int shmload();
int shmread();
int shmwrite();
int shmioctl();
int nulldev();
int nonedev();

/*
 * Device Configuration.
 */

CON shmcon = {
	DFCHR,			/* Flags			*/
	24,			/* Major Index			*/
	nulldev,		/* Open				*/
	nulldev,		/* Close			*/
	nonedev,		/* Block			*/
	shmread,		/* Read				*/
	shmwrite,		/* Write			*/
	shmioctl,		/* Ioctl			*/
	nulldev,		/* Power fail			*/
	nulldev,		/* Timeout			*/
	shmload,		/* Load				*/
	nulldev			/* Unload			*/
};

unsigned NSHMID = 16;
struct shmid_ds *shmids;
struct seg **shmsegs;

/*
 * Shared Memory Device Load.
 */

static
shmload()
{
	register struct shmid_ds * idp;
	register unsigned wanted;
	
	if ( NSHMID == 0 )
		return 0;

	wanted = NSHMID * (sizeof(struct shmid_ds) + sizeof(struct seg *));

	if ( (shmids = kalloc( wanted )) == 0 ) {

		printf("couldn't kalloc %u shared memory ids\n", NSHMID );
		NSHMID = 0;
		return 0;
	}
	shmsegs = (struct seg *) &shmids[ NSHMID ];

	for ( idp = &shmids[NSHMID]; --idp >= shmids; )
		idp->shm_perm.mode = 0;

	return 0;
}

/*
** Shared Memory Read.
*/

static
shmread( dev, iop )

dev_t dev;
register IO *iop;

{
	register struct shmid_ds *idp;
	int shmid;
	unsigned off;
	faddr_t faddr;

	off   = ((unsigned *) &iop->io_seek)[0];
	shmid = ((unsigned *) &iop->io_seek)[1];

	if ( shmid >= NSHMID ) {
		u.u_error = EFAULT;
		return -1;
	}

	idp = &shmids[shmid];

	if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
		u.u_error = EIDRM;
		return -1;
	}

	if ( (ipcaccess(&idp->shm_perm) & SHM_R) == 0 ) {
		u.u_error = EACCES;
		return -1;
	}

	if ( ((long) off + iop->io_ioc) > idp->shm_segsz ) {
		u.u_error = EFAULT;
		return -1;
	}

	FP_SEL(faddr) = FP_SEL(shmsegs[shmid]->s_faddr);
	FP_OFF(faddr) = off;

	if ( ! fucopy( faddr, iop->io_base, iop->io_ioc ) ) {
		u.u_error = EFAULT;
		return -1;
	}

	iop->io_ioc = 0;
	return 0;
}

/*
** Shared Memory Write.
*/

static
shmwrite( dev, iop )

dev_t dev;
register IO *iop;

{
	register struct shmid_ds *idp;
	int shmid;
	unsigned off;
	faddr_t faddr;

	off   = ((unsigned *) &iop->io_seek)[0];
	shmid = ((unsigned *) &iop->io_seek)[1];

	if ( shmid >= NSHMID ) {
		u.u_error = EFAULT;
		return -1;
	}

	idp = &shmids[shmid];

	if ( (idp->shm_perm.mode & IPC_ALLOC) == 0 ) {
		u.u_error = EIDRM;
		return -1;
	}

	if ( (ipcaccess(&idp->shm_perm) & SHM_W) == 0 ) {
		u.u_error = EFAULT;
		return -1;
	}

	if ( ((long) off + iop->io_ioc) > idp->shm_segsz ) {
		u.u_error = EFAULT;
		return -1;
	}

	FP_SEL(faddr) = FP_SEL(shmsegs[shmid]->s_faddr);
	FP_OFF(faddr) = off;

	if ( ! ufcopy(iop->io_base, faddr, iop->io_ioc ) ) {
		u.u_error = EFAULT;
		return -1;
	}

	iop->io_ioc = 0;
	return 0;
}

/*
 * Shared Memory Device Ioctl.
 *
 *	Input:	dev = shared memory device (/dev/shm).
 *		com = command to perform (SHMCTL, SHMGET,SHMAT).
 *		vec = pointer to return value, followed by parameters.
 *
 *	Action:	Initiate command.
 *		Save commands return value in *vec.
 */

static
shmioctl( dev, com, vec )

dev_t dev;
int com;
int *vec;

{
	switch ( com ) {

	case SHMCTL:
		putuwd( vec+0,
			ushmctl( getuwd( vec+1 ),
				 getuwd( vec+2 ),
				 getuwd( vec+3 ) ));
		break;

	case SHMGET:
		putuwd( vec+0,
			ushmget( getuwd( vec+1 ),
				 getuwd( vec+2 ),
				 getuwd( vec+3 ),
				 getuwd( vec+4 ) ));
		break;

	default:
		u.u_error = EINVAL;
		break;
	}
}

unix.superglobalmegacorp.com

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