1*21b926adSArne Jansen #include <sys/modctl.h> 2*21b926adSArne Jansen #include <sys/ddi.h> 3*21b926adSArne Jansen #include <sys/sunddi.h> 4*21b926adSArne Jansen #include <sys/devops.h> 5*21b926adSArne Jansen #include <sys/conf.h> 6*21b926adSArne Jansen #include <sys/cpuvar.h> 7*21b926adSArne Jansen #include <sys/kobj.h> 8*21b926adSArne Jansen #include <sys/spa.h> 9*21b926adSArne Jansen #include <sys/arc.h> 10*21b926adSArne Jansen #include <sys/vfs.h> 11*21b926adSArne Jansen #include <sys/dnlc.h> 12*21b926adSArne Jansen 13*21b926adSArne Jansen static dev_info_t *arcflushdevi; 14*21b926adSArne Jansen 15*21b926adSArne Jansen #define FTAG ((char *)(uintptr_t)__func__) 16*21b926adSArne Jansen 17*21b926adSArne Jansen static int arcflushioctl(dev_t dev, int cmd, intptr_t arg, int mode, 18*21b926adSArne Jansen cred_t *credp, int *rvalp); 19*21b926adSArne Jansen static int arcflushclose(dev_t dev, int flag, int otyp, cred_t *crepd); 20*21b926adSArne Jansen static int arcflushopen(dev_t *devp, int flag, int otyp, cred_t *credp); 21*21b926adSArne Jansen 22*21b926adSArne Jansen static struct cb_ops arcflush_cb_ops = { 23*21b926adSArne Jansen arcflushopen, /* open */ 24*21b926adSArne Jansen arcflushclose, /* close */ 25*21b926adSArne Jansen nodev, /* strategy */ 26*21b926adSArne Jansen nodev, /* print */ 27*21b926adSArne Jansen nodev, /* dump */ 28*21b926adSArne Jansen nodev, /* read */ 29*21b926adSArne Jansen nodev, /* write */ 30*21b926adSArne Jansen arcflushioctl, /* ioctl */ 31*21b926adSArne Jansen nodev, /* devmap */ 32*21b926adSArne Jansen nodev, /* mmap */ 33*21b926adSArne Jansen nodev, /* segmap */ 34*21b926adSArne Jansen nochpoll, /* poll */ 35*21b926adSArne Jansen ddi_prop_op, /* prop_op */ 36*21b926adSArne Jansen (struct streamtab *)0, /* streamtab */ 37*21b926adSArne Jansen D_NEW | D_64BIT | D_MP, /* flags */ 38*21b926adSArne Jansen CB_REV, 39*21b926adSArne Jansen nodev, 40*21b926adSArne Jansen nodev 41*21b926adSArne Jansen }; 42*21b926adSArne Jansen 43*21b926adSArne Jansen static int arcflushattach(dev_info_t *, ddi_attach_cmd_t); 44*21b926adSArne Jansen static int arcflushdetach(dev_info_t *, ddi_detach_cmd_t); 45*21b926adSArne Jansen static int arcflushinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); 46*21b926adSArne Jansen 47*21b926adSArne Jansen static struct dev_ops arcflush_ops = { 48*21b926adSArne Jansen DEVO_REV, /* devo_rev */ 49*21b926adSArne Jansen 0, /* refcnt */ 50*21b926adSArne Jansen arcflushinfo, /* info */ 51*21b926adSArne Jansen nulldev, /* identify */ 52*21b926adSArne Jansen nulldev, /* probe */ 53*21b926adSArne Jansen arcflushattach, /* attach */ 54*21b926adSArne Jansen arcflushdetach, /* detach */ 55*21b926adSArne Jansen nodev, /* reset */ 56*21b926adSArne Jansen &arcflush_cb_ops, /* driver operations */ 57*21b926adSArne Jansen (struct bus_ops *)NULL, /* bus operations */ 58*21b926adSArne Jansen NULL /* power */ 59*21b926adSArne Jansen }; 60*21b926adSArne Jansen 61*21b926adSArne Jansen static struct modldrv modldrv = { 62*21b926adSArne Jansen &mod_driverops, /* type of module - a driver */ 63*21b926adSArne Jansen "arcflush driver", 64*21b926adSArne Jansen &arcflush_ops, 65*21b926adSArne Jansen }; 66*21b926adSArne Jansen 67*21b926adSArne Jansen static struct modlinkage modlinkage = { 68*21b926adSArne Jansen MODREV_1, 69*21b926adSArne Jansen { (void *)&modldrv, NULL } 70*21b926adSArne Jansen }; 71*21b926adSArne Jansen 72*21b926adSArne Jansen int 73*21b926adSArne Jansen _init() 74*21b926adSArne Jansen { 75*21b926adSArne Jansen int error = mod_install(&modlinkage); 76*21b926adSArne Jansen return (error); 77*21b926adSArne Jansen } 78*21b926adSArne Jansen 79*21b926adSArne Jansen int 80*21b926adSArne Jansen _fini() 81*21b926adSArne Jansen { 82*21b926adSArne Jansen int error; 83*21b926adSArne Jansen 84*21b926adSArne Jansen error = mod_remove(&modlinkage); 85*21b926adSArne Jansen return (error); 86*21b926adSArne Jansen } 87*21b926adSArne Jansen 88*21b926adSArne Jansen int 89*21b926adSArne Jansen _info(struct modinfo *modinfop) 90*21b926adSArne Jansen { 91*21b926adSArne Jansen int error; 92*21b926adSArne Jansen 93*21b926adSArne Jansen error = mod_info(&modlinkage, modinfop); 94*21b926adSArne Jansen return error; 95*21b926adSArne Jansen } 96*21b926adSArne Jansen 97*21b926adSArne Jansen static int 98*21b926adSArne Jansen arcflushclose(dev_t dev, int flag, int otyp, cred_t *crepd) 99*21b926adSArne Jansen { 100*21b926adSArne Jansen if (otyp != OTYP_CHR) 101*21b926adSArne Jansen return (EINVAL); 102*21b926adSArne Jansen 103*21b926adSArne Jansen return (0); 104*21b926adSArne Jansen } 105*21b926adSArne Jansen 106*21b926adSArne Jansen static int 107*21b926adSArne Jansen arcflushopen(dev_t *devp, int flag, int otyp, cred_t *credp) 108*21b926adSArne Jansen { 109*21b926adSArne Jansen if (otyp != OTYP_CHR) 110*21b926adSArne Jansen return (EINVAL); 111*21b926adSArne Jansen if (drv_priv(credp) != 0) 112*21b926adSArne Jansen return (EPERM); 113*21b926adSArne Jansen 114*21b926adSArne Jansen return (0); 115*21b926adSArne Jansen } 116*21b926adSArne Jansen 117*21b926adSArne Jansen static int 118*21b926adSArne Jansen arcflushioctl(dev_t dev, int cmd, intptr_t arg, int mode, 119*21b926adSArne Jansen cred_t *credp, int *rvalp) 120*21b926adSArne Jansen { 121*21b926adSArne Jansen spa_t *spa; 122*21b926adSArne Jansen int ret; 123*21b926adSArne Jansen char name[MAXPATHLEN + 1]; 124*21b926adSArne Jansen vfs_t *vfsp; 125*21b926adSArne Jansen 126*21b926adSArne Jansen if (ddi_copyin((void *)arg, name, MAXPATHLEN, mode) != 0) 127*21b926adSArne Jansen return EFAULT; 128*21b926adSArne Jansen name[MAXPATHLEN] = 0; 129*21b926adSArne Jansen 130*21b926adSArne Jansen switch (cmd) { 131*21b926adSArne Jansen case 0xf10053: 132*21b926adSArne Jansen ret = spa_open(name, &spa, FTAG); 133*21b926adSArne Jansen if (ret != 0) 134*21b926adSArne Jansen return (ret); 135*21b926adSArne Jansen arc_flush(spa, FALSE); 136*21b926adSArne Jansen spa_close(spa, FTAG); 137*21b926adSArne Jansen break; 138*21b926adSArne Jansen case 0xf10054: 139*21b926adSArne Jansen vfsp = vfs_mntpoint2vfsp(name); 140*21b926adSArne Jansen if (vfsp == NULL) 141*21b926adSArne Jansen return (EINVAL); 142*21b926adSArne Jansen dnlc_purge_vfsp(vfsp, 0); 143*21b926adSArne Jansen break; 144*21b926adSArne Jansen default: 145*21b926adSArne Jansen return ENOTTY; 146*21b926adSArne Jansen } 147*21b926adSArne Jansen 148*21b926adSArne Jansen return (0); 149*21b926adSArne Jansen } 150*21b926adSArne Jansen 151*21b926adSArne Jansen /*ARGSUSED*/ 152*21b926adSArne Jansen static int 153*21b926adSArne Jansen arcflushattach(dev_info_t *devi, ddi_attach_cmd_t cmd) 154*21b926adSArne Jansen { 155*21b926adSArne Jansen if (cmd != DDI_ATTACH) { 156*21b926adSArne Jansen return (DDI_FAILURE); 157*21b926adSArne Jansen } 158*21b926adSArne Jansen 159*21b926adSArne Jansen if (ddi_create_minor_node(devi, "arcflush", S_IFCHR, 0, DDI_PSEUDO, 0) 160*21b926adSArne Jansen == DDI_FAILURE) { 161*21b926adSArne Jansen cmn_err(CE_NOTE, "arcflushattach fail: " 162*21b926adSArne Jansen "ddi_create_minor_node\n"); 163*21b926adSArne Jansen return (DDI_FAILURE); 164*21b926adSArne Jansen } 165*21b926adSArne Jansen ddi_report_dev(devi); 166*21b926adSArne Jansen 167*21b926adSArne Jansen arcflushdevi = devi; 168*21b926adSArne Jansen 169*21b926adSArne Jansen return (DDI_SUCCESS); 170*21b926adSArne Jansen } 171*21b926adSArne Jansen 172*21b926adSArne Jansen static int 173*21b926adSArne Jansen arcflushdetach(dev_info_t *devi, ddi_detach_cmd_t cmd) 174*21b926adSArne Jansen { 175*21b926adSArne Jansen if (cmd != DDI_DETACH) { 176*21b926adSArne Jansen return (DDI_FAILURE); 177*21b926adSArne Jansen } 178*21b926adSArne Jansen 179*21b926adSArne Jansen arcflushdevi = NULL; 180*21b926adSArne Jansen 181*21b926adSArne Jansen ddi_prop_remove_all(devi); 182*21b926adSArne Jansen ddi_remove_minor_node(devi, NULL); 183*21b926adSArne Jansen 184*21b926adSArne Jansen return (DDI_SUCCESS); 185*21b926adSArne Jansen } 186*21b926adSArne Jansen 187*21b926adSArne Jansen /* ARGSUSED */ 188*21b926adSArne Jansen static int 189*21b926adSArne Jansen arcflushinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result) 190*21b926adSArne Jansen { 191*21b926adSArne Jansen int error; 192*21b926adSArne Jansen switch (infocmd) { 193*21b926adSArne Jansen case DDI_INFO_DEVT2DEVINFO: 194*21b926adSArne Jansen *result = (void *)arcflushdevi; 195*21b926adSArne Jansen error = DDI_SUCCESS; 196*21b926adSArne Jansen break; 197*21b926adSArne Jansen case DDI_INFO_DEVT2INSTANCE: 198*21b926adSArne Jansen *result = (void *)0; 199*21b926adSArne Jansen error = DDI_SUCCESS; 200*21b926adSArne Jansen break; 201*21b926adSArne Jansen default: 202*21b926adSArne Jansen error = DDI_FAILURE; 203*21b926adSArne Jansen } 204*21b926adSArne Jansen return (error); 205*21b926adSArne Jansen } 206