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
_init()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
_fini()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
_info(struct modinfo * modinfop)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
arcflushclose(dev_t dev,int flag,int otyp,cred_t * crepd)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
arcflushopen(dev_t * devp,int flag,int otyp,cred_t * credp)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
arcflushioctl(dev_t dev,int cmd,intptr_t arg,int mode,cred_t * credp,int * rvalp)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
arcflushattach(dev_info_t * devi,ddi_attach_cmd_t cmd)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
arcflushdetach(dev_info_t * devi,ddi_detach_cmd_t cmd)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
arcflushinfo(dev_info_t * dip,ddi_info_cmd_t infocmd,void * arg,void ** result)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