printf("DDB symbols added: %d bytes\n", curp->sym_symsize);
printf("DDB symbols added: %ld bytes\n", curp->sym_symsize);
lkmioctl(dev, cmd, data, flag, p)	dev_t dev;	u_long cmd;	caddr_t data;	int flag;	struct proc *p;{	int error = 0, i;	struct lmc_resrv *resrvp;	struct lmc_loadbuf *loadbufp;	struct lmc_unload *unloadp;	struct lmc_stat	 *statp;	switch(cmd) {	case LMRESERV:		/* reserve pages for a module */	case LMRESERV_O:	/* reserve pages for a module */		if (securelevel > 0)			return EPERM;		if ((flag & FWRITE) == 0) /* only allow this if writing */			return EPERM;		resrvp = (struct lmc_resrv *)data;		if ((curp = lkmalloc()) == NULL) {			error = ENOMEM;		/* no slots available */			break;		}		curp->ver = (cmd == LMRESERV) ? LKM_VERSION : LKM_OLDVERSION;		resrvp->slot = curp->id;	/* return slot */		/*		 * Get memory for module		 */		curp->size = resrvp->size;		curp->area = kmem_alloc(kmem_map, curp->size);/**/		curp->offset = 0;		/* load offset */		resrvp->addr = curp->area; /* ret kernel addr */		if (cmd == LMRESERV && resrvp->sym_size) {			curp->sym_size = resrvp->sym_size;			curp->sym_symsize = resrvp->sym_symsize;			curp->syms = (caddr_t)kmem_alloc(kmem_map, curp->sym_size);			curp->sym_offset = 0;			resrvp->sym_addr = curp->syms; /* ret symbol addr */		} else {			curp->sym_size = 0;			curp->syms = 0;			curp->sym_offset = 0;			if (cmd == LMRESERV)				resrvp->sym_addr = 0;		}#ifdef DEBUG		printf("LKM: LMRESERV (actual   = 0x%08lx)\n", curp->area);		printf("LKM: LMRESERV (syms     = 0x%08x)\n", curp->syms);		printf("LKM: LMRESERV (adjusted = 0x%08lx)\n",			trunc_page(curp->area));#endif	/* DEBUG */		lkm_state = LKMS_RESERVED;		break;	case LMLOADBUF:		/* Copy in; stateful, follows LMRESERV */		if (securelevel > 0)			return EPERM;		if ((flag & FWRITE) == 0) /* only allow this if writing */			return EPERM;		loadbufp = (struct lmc_loadbuf *)data;		if ((lkm_state != LKMS_RESERVED && lkm_state != LKMS_LOADING)		    || loadbufp->cnt < 0		    || loadbufp->cnt > MODIOBUF		    || loadbufp->cnt > curp->size - curp->offset) {			error = ENOMEM;			break;		}		/* copy in buffer full of data */		error = copyin(loadbufp->data, 			(caddr_t)curp->area + curp->offset, loadbufp->cnt);		if (error)			break;		if ((curp->offset + loadbufp->cnt) < curp->size) {			lkm_state = LKMS_LOADING;#ifdef DEBUG			printf("LKM: LMLOADBUF (loading @ %ld of %ld, i = %d)\n",			curp->offset, curp->size, loadbufp->cnt);#endif	/* DEBUG */		} else {			lkm_state = LKMS_LOADING_SYMS;#ifdef DEBUG			printf("LKM: LMLOADBUF (loaded)\n");#endif	/* DEBUG */		}		curp->offset += loadbufp->cnt;		break;	case LMLOADSYMS:	/* Copy in; stateful, follows LMRESERV*/		if ((flag & FWRITE) == 0) /* only allow this if writing */			return EPERM;		loadbufp = (struct lmc_loadbuf *)data;		i = loadbufp->cnt;		if ((lkm_state != LKMS_LOADING &&		     lkm_state != LKMS_LOADING_SYMS)		    || i < 0		    || i > MODIOBUF		    || i > curp->sym_size - curp->sym_offset) {			error = ENOMEM;			break;		}		/* copy in buffer full of data*/		error = copyin(loadbufp->data, curp->syms + curp->sym_offset,		    i);		if (error)			break;		if ((curp->sym_offset + i) < curp->sym_size) {			lkm_state = LKMS_LOADING_SYMS;#ifdef DEBUG			printf( "LKM: LMLOADSYMS (loading @ %d of %d, i = %d)\n",			curp->sym_offset, curp->sym_size, i);#endif	/* DEBUG*/		} else {			lkm_state = LKMS_LOADED;#ifdef DEBUG			printf( "LKM: LMLOADSYMS (loaded)\n");#endif	/* DEBUG*/		}		curp->sym_offset += i;		break;	case LMUNRESRV:		/* discard reserved pages for a module */		if (securelevel > 0)			return EPERM;		if ((flag & FWRITE) == 0) /* only allow this if writing */			return EPERM;		lkmunreserve();	/* coerce state to LKM_IDLE */#ifdef DEBUG		printf("LKM: LMUNRESERV\n");#endif	/* DEBUG */		break;	case LMREADY:		/* module loaded: call entry */		if (securelevel > 0)			return EPERM;		if ((flag & FWRITE) == 0) /* only allow this if writing */			return EPERM;		switch (lkm_state) {		case LKMS_LOADED:			break;		case LKMS_LOADING:		case LKMS_LOADING_SYMS:			if (curp->size - curp->offset > 0)			    /* The remainder must be bss, so we clear it */			    bzero((caddr_t)curp->area + curp->offset,				  curp->size - curp->offset);			break;		default:#ifdef DEBUG			printf("lkm_state is %02x\n", lkm_state);#endif	/* DEBUG */			return ENXIO;		}		curp->entry = (int (*) __P((struct lkm_table *, int, int)))				(*((long *) (data)));#ifdef DEBUG		printf("LKM: call entrypoint %x\n", curp->entry);#endif		/* call entry(load)... (assigns "private" portion) */		error = (*(curp->entry))(curp, LKM_E_LOAD, curp->ver);		if (error) {			/*			 * Module may refuse loading or may have a			 * version mismatch...			 */			lkm_state = LKMS_UNLOADING;	/* for lkmunreserve */			lkmunreserve();			/* free memory */			lkmfree(curp);			/* free slot */			break;		}#ifdef DEBUG		printf("LKM: LMREADY, id=%d, dev=%d\n", curp->id, curp->private.lkm_any->lkm_offset);#endif	/* DEBUG */#ifdef DDB		if (curp->syms && curp->sym_offset >= curp->sym_size) {		    db_add_symbol_table(curp->syms,					curp->syms + curp->sym_symsize,					curp->private.lkm_any->lkm_name,					curp->syms, 					curp->syms + curp->sym_size );		    printf("DDB symbols added: %d bytes\n", curp->sym_symsize);		}#endif		curp->refcnt++;		lkm_state = LKMS_IDLE;		break;	case LMUNLOAD:		/* unload a module */		if (securelevel > 0)			return EPERM;		if ((flag & FWRITE) == 0) /* only allow this if writing */			return EPERM;		unloadp = (struct lmc_unload *)data;		if ((curp = lkmlookup(unloadp->id, unloadp->name, &error)) == NULL)			break; /* error set in lkmlookup */		/* call entry(unload) */		if ((*(curp->entry))(curp, LKM_E_UNLOAD, curp->ver)) {			error = EBUSY;			break;		}		lkm_state = LKMS_UNLOADING;	/* non-idle for lkmunreserve */		lkmunreserve();			/* free memory */		lkmfree(curp);			/* free slot */		break;	case LMSTAT:		/* stat a module by id/name */		/* allow readers and writers to stat */		statp = (struct lmc_stat *)data;		if ((curp = lkmlookup(statp->id, statp->name, &error)) == NULL)			break; /* error set in lkmlookup */		/*		 * Copy out stat information for this module...		 */		statp->id	= curp->id;		statp->offset	= curp->private.lkm_any->lkm_offset;		statp->type	= curp->private.lkm_any->lkm_type;		statp->area	= curp->area;		statp->size	= curp->size / CLBYTES;		statp->private	= (unsigned long)curp->private.lkm_any;		statp->ver	= curp->private.lkm_any->lkm_ver;		copyoutstr(curp->private.lkm_any->lkm_name, 			  statp->name, MAXLKMNAME - 2, NULL);		break;	default:		/* bad ioctl()... */		error = ENOTTY;		break;	}	return (error);}