示例#1
0
文件: gscdd.c 项目: B-Rich/amanda
int
gsc_config(dev_t devno, int cmd, struct uio * uiop)
{
    struct gsc_ddsinfo ddsinfo;
    gsc_softc_t *sp;
    int result, i, unit;
    extern int nodev();
    static struct devsw gsc_dsw = {
	gsc_open,	/* entry point for open routine */
	gsc_close,	/* entry point for close routine */
	nodev,		/* entry point for read routine */
	nodev,		/* entry point for write routine */
	gsc_ioctl,	/* entry point for ioctl routine */
	nodev,		/* entry point for strategy routine */
	0,		/* pointer to tty device structure */
	nodev,		/* entry point for select routine */
	gsc_config,	/* entry point for config routine */
	nodev,		/* entry point for print routine */
	nodev,		/* entry point for dump routine */
	nodev,		/* entry point for mpx routine */
	nodev,		/* entry point for revoke routine */
	NULL,		/* pointer to device specific data */
	NULL,		/* select pointer */
	DEV_MPSAFE
    };

    if (lockl(&config_lock, LOCK_SHORT) != LOCK_SUCC) {
	return (EINVAL);
    }
    unit = minor(devno);
    if (unit < 0 || unit >= MAX_UNITS) {
	Trace2(0, "%d: bad unit %d", __LINE__, unit);
	result = EINVAL;
	unlockl(&config_lock);
	return (result);
    }

    switch (cmd) {
    case CFG_INIT:
	Trace2(2, "CFG_INIT: unit %d nunit %d\n", unit, nunits);
	/*
	 * Initialize softinfo, first time around.
	 */
	if (nunits == 0) {
	    memset(softinfo, 0, sizeof (softinfo));
	}
	/*
	 * Copy in DDS information
	 */
	uiomove((caddr_t) &ddsinfo, sizeof ddsinfo, UIO_WRITE, uiop);
	sp = &softinfo[unit];
	if (sp->iscfg) {
	    Trace1(0, "CFG_INIT: unit %d already configd", unit);
	    result = EBUSY;
	    break;
	}
	lock_alloc(&sp->dd_lock, LOCK_ALLOC_PIN, DD_LOCK, -1);
	lock_alloc(&sp->buf_lock, LOCK_ALLOC_PIN, DD_LOCK, -1);
	simple_lock_init(&sp->dd_lock);
	sp->dev = ddsinfo.busid;
	sp->tgt = ddsinfo.target;
	sp->lun = ddsinfo.lun;
	sp->cbuf.index = sp->rbuf.index = unit;
	/*
	 * If this is the first time through:
	 *   Add entry to the device switch table to call this driver
	 *   Pin driver code.
	 */
	if (nunits == 0) {
	    result = devswadd(devno, &gsc_dsw);
	    if (result != 0) {
		Trace1(0, "CFG_INIT: devswadd result: %d", result);
		break;
	    }
	    result = pincode((int (*) ()) gscdd_intr);
	    if (result) {
		Trace1(0, "CFG_INIT: pincode result: %d", result);
		devswdel(devno);
		break;
	    }
	}
	sp->iscfg = 1;
	result = gsopen(sp);
	if (result) {
	    Trace2(0, "CFG_INIT: gsopen returns %d for unit %d", result, unit);
	    sp->iscfg = 0;
	    gsclose(sp, devno);
	    break;
	}
	if (nunits <= unit)
	    nunits = unit + 1;
	sp->iscfg = 1;
	break;

    case CFG_TERM:
	Trace1(2, "CFG_TERM unit %d", unit);
	result = 0;
	sp = &softinfo[unit];
	if (sp->iscfg == 0) {
	    Trace1(0, "CFG_TERM: unit %d not already configd", unit);
	    result = ENXIO;
	    break;
	} else if (sp->isopen) {
	    Trace1(0, "CFG_TERM: unit %d open", unit);
	    result = EBUSY;
	    break;
	}
	sp->iscfg = 0;	/* block further actions */
	gsclose(sp, devno);
	break;

    default:
	result = EINVAL;
	break;
    }
    unlockl(&config_lock);
    return (result);
}
示例#2
0
/*
 * syscall -	this is the VRMIX system call entry point.
 *
 * NOTE:
 *	THIS SHOULD BE CHANGED TO afs_syscall(), but requires
 *	all the user-level calls to `syscall' to change.
 */
syscall(syscall, p1, p2, p3, p4, p5, p6)
{
    int rval1 = 0, code;
    int monster;
    int retval = 0;
#ifndef AFS_AIX41_ENV
    extern lock_t kernel_lock;
    monster = lockl(&kernel_lock, LOCK_SHORT);
#endif /* !AFS_AIX41_ENV */

    AFS_STATCNT(syscall);
    setuerror(0);
    switch (syscall) {
    case AFSCALL_CALL:
	rval1 = afs_syscall_call(p1, p2, p3, p4, p5, p6);
	break;

    case AFSCALL_SETPAG:
	AFS_GLOCK();
	rval1 = afs_setpag();
	AFS_GUNLOCK();
	break;

    case AFSCALL_PIOCTL:
	AFS_GLOCK();
	rval1 = afs_syscall_pioctl(p1, p2, p3, p4);
	AFS_GUNLOCK();
	break;

    case AFSCALL_ICREATE:
	rval1 = afs_syscall_icreate(p1, p2, p3, p4, p5, p6);
	break;

    case AFSCALL_IOPEN:
	rval1 = afs_syscall_iopen(p1, p2, p3);
	break;

    case AFSCALL_IDEC:
	rval1 = afs_syscall_iincdec(p1, p2, p3, -1);
	break;

    case AFSCALL_IINC:
	rval1 = afs_syscall_iincdec(p1, p2, p3, 1);
	break;

    case AFSCALL_ICL:
	AFS_GLOCK();
	code = Afscall_icl(p1, p2, p3, p4, p5, &retval);
	AFS_GUNLOCK();
	if (!code)
	    rval1 = retval;
	if (!rval1)
	    rval1 = code;
	break;

    default:
	rval1 = EINVAL;
	setuerror(EINVAL);
	break;
    }

  out:
#ifndef AFS_AIX41_ENV
    if (monster != LOCK_NEST)
	unlockl(&kernel_lock);
#endif /* !AFS_AIX41_ENV */
    return getuerror()? -1 : rval1;
}