1/* $NetBSD: ml_ipl.c,v 1.6 2008/05/20 07:08:06 darrenr Exp $ */ 2 3/* 4 * Copyright (C) 1993-2001 by Darren Reed. 5 * 6 * See the IPFILTER.LICENCE file for details on licencing. 7 */ 8/* 9 * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate 10 * its own major char number! Way cool patch! 11 */ 12#include <sys/types.h> 13#include <sys/stat.h> 14#include <sys/time.h> 15#include <sys/file.h> 16#include <sys/conf.h> 17#include <sys/syslog.h> 18#include <sys/buf.h> 19#include <sys/param.h> 20#include <sys/errno.h> 21#include <sys/uio.h> 22#include <sys/vnode.h> 23#include <sundev/mbvar.h> 24#include <sun/autoconf.h> 25#include <sun/vddrv.h> 26#if defined(sun4c) || defined(sun4m) 27#include <sun/openprom.h> 28#endif 29 30#ifndef IPL_NAME 31#define IPL_NAME "/dev/ipl" 32#endif 33 34extern int ipfattach(), iplopen(), iplclose(), iplioctl(), iplread(); 35extern int nulldev(), iplidentify(), errno; 36 37struct cdevsw ipldevsw = 38{ 39 iplopen, iplclose, iplread, nulldev, 40 iplioctl, nulldev, nulldev, nulldev, 41 0, nulldev, 42}; 43 44 45struct dev_ops ipl_ops = 46{ 47 1, 48 iplidentify, 49 ipfattach, 50 iplopen, 51 iplclose, 52 iplread, 53 NULL, /* write */ 54 NULL, /* strategy */ 55 NULL, /* dump */ 56 0, /* psize */ 57 iplioctl, 58 NULL, /* reset */ 59 NULL /* mmap */ 60}; 61 62int ipl_major = 0; 63 64#ifdef sun4m 65struct vdldrv vd = 66{ 67 VDMAGIC_PSEUDO, 68 "ipl", 69 &ipl_ops, 70 NULL, 71 &ipldevsw, 72 0, 73 0, 74 NULL, 75 NULL, 76 NULL, 77 0, 78 1, 79}; 80#else /* sun4m */ 81struct vdldrv vd = 82{ 83 VDMAGIC_PSEUDO, /* magic */ 84 "ipl", /* name */ 85#ifdef sun4c 86 &ipl_ops, /* dev_ops */ 87#else 88 NULL, /* struct mb_ctlr *mb_ctlr */ 89 NULL, /* struct mb_driver *mb_driver */ 90 NULL, /* struct mb_device *mb_device */ 91 0, /* num ctlrs */ 92 1, /* numdevs */ 93#endif /* sun4c */ 94 NULL, /* bdevsw */ 95 &ipldevsw, /* cdevsw */ 96 0, /* block major */ 97 0, /* char major */ 98}; 99#endif /* sun4m */ 100 101extern int vd_unuseddev(); 102extern struct cdevsw cdevsw[]; 103extern int nchrdev; 104 105xxxinit(u_int fc, struct vddrv *vdp, caddr_t vdi, struct vdstat *vds) 106{ 107 struct vdlinkage *v; 108 int i; 109 110 switch (fc) 111 { 112 case VDLOAD: 113 while (ipl_major < nchrdev && 114 cdevsw[ipl_major].d_open != vd_unuseddev) 115 ipl_major++; 116 if (ipl_major == nchrdev) 117 return ENODEV; 118 vd.Drv_charmajor = ipl_major; 119 vdp->vdd_vdtab = (struct vdlinkage *)&vd; 120 return ipl_attach(vdi); 121 case VDUNLOAD: 122 return unload(vdp, vdi); 123 124 case VDSTAT: 125 return 0; 126 127 default: 128 return EIO; 129 } 130} 131 132static 133unload(struct vddrv *vdp, struct vdioctl_unload *vdi) 134{ 135 int i; 136 137 (void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE); 138 return ipfdetach(); 139} 140 141 142static int ipl_attach(vdi) 143struct vdioctl_load *vdi; 144{ 145 struct vnode *vp; 146 struct vattr vattr; 147 int error = 0, fmode = S_IFCHR|0600; 148 149 (void) vn_remove(IPL_NAME, UIO_SYSSPACE, FILE); 150 vattr_null(&vattr); 151 vattr.va_type = MFTOVT(fmode); 152 vattr.va_mode = (fmode & 07777); 153 vattr.va_rdev = ipl_major<<8; 154 155 error = vn_create(IPL_NAME, UIO_SYSSPACE, &vattr, EXCL, 0, &vp); 156 if (error == 0) 157 VN_RELE(vp); 158 return ipfattach(0); 159} 160