version 1.4, 2015/12/21 10:25:04
|
version 1.5, 2015/12/21 11:44:20
|
Line 71 CFATTACH_DECL3_NEW(xxx, sizeof(struct xx
|
Line 71 CFATTACH_DECL3_NEW(xxx, sizeof(struct xx
|
extern struct cfdriver xxx_cd; |
extern struct cfdriver xxx_cd; |
extern struct cfdriver xxx_cd; |
extern struct cfdriver xxx_cd; |
|
|
|
#ifdef PSEUDODEVICE |
|
static void xxxattach(int num); |
|
#endif |
|
|
|
static int xxx_init(device_t); |
|
static int xxx_finish(device_t); |
|
|
static int xxxdone(struct buf *); |
static int xxxdone(struct buf *); |
|
|
|
|
Line 87 static int xxxdone(struct buf *);
|
Line 94 static int xxxdone(struct buf *);
|
|
|
---- |
---- |
|
|
## Attachment and Standard driver interface |
## Pseudo-Device Attachment and Standard driver interface |
|
|
<pre><code> |
<pre><code> |
|
#ifdef PSEUDODEVICE |
void |
void |
xxxattach(struct xxx_softc *sc) |
xxxattach(int num) |
{ |
{ |
device_t self = sc->sc_dv; |
int error; |
struct dk_softc *dksc = &sc->sc_dk; |
|
|
|
dk_init(dksc, self, DKTYPE_xxx); |
|
disk_init(&dksc->sc_dkdev, dksc->sc_xname, &xxdkdriver); |
|
|
|
dk_attach(dksc); |
|
disk_attach(&dksc->sc_dkdev); |
|
// initialize dksc->sc_dkdev.dk_geom |
|
|
|
bufq_alloc(&dksc->sc_bufq, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK); |
error = config_cfattach_attach(xxx_cd.cd_name, &xxx_ca); |
|
if (error) { |
|
aprint_error("%s: unable to register cfattach %d\n", |
|
xxx_cd.cd_name, error); |
|
return; |
|
} |
|
|
// possibly deferred with config_interrupts() |
// some global initialization |
dkwedge_discover(&dksc->sc_dkdev); |
|
} |
} |
|
#endif |
|
|
static int |
static int |
xxxopen(dev_t dev, int flags, int fmt, struct lwp *l) |
xxxopen(dev_t dev, int flags, int fmt, struct lwp *l) |
Line 224 xxxdone(struct xxx_softc *sc, struct buf
|
Line 229 xxxdone(struct xxx_softc *sc, struct buf
|
|
|
---- |
---- |
|
|
|
## Startup and Shutdown |
|
|
|
<pre><code> |
|
static int |
|
xxx_init(device_t self) |
|
{ |
|
struct xxx_softc *sc = device_private(self); |
|
struct dk_softc *dksc = &sc->sc_dk; |
|
|
|
dk_init(dksc, self, DKTYPE_xxx); |
|
disk_init(&dksc->sc_dkdev, dksc->sc_xname, &xxdkdriver); |
|
|
|
dk_attach(dksc); |
|
disk_attach(&dksc->sc_dkdev); |
|
// initialize dksc->sc_dkdev.dk_geom |
|
|
|
bufq_alloc(&dksc->sc_bufq, BUFQ_DISK_DEFAULT_STRAT, BUFQ_SORT_RAWBLOCK); |
|
|
|
// possibly deferred with config_interrupts() |
|
dkwedge_discover(&dksc->sc_dkdev); |
|
|
|
return 0; |
|
} |
|
|
|
static int |
|
xxx_finish(device_t self) |
|
{ |
|
struct xxx_softc *sc = device_private(self); |
|
struct dk_softc *dksc = &sc->sc_dksc; |
|
|
|
dkwedge_delall(&dksc->sc_dkdev); |
|
|
|
dk_drain(dksc); |
|
bufq_free(dksc->sc_bufq); |
|
|
|
dk_detach(dksc); |
|
disk_detach(&dksc->sc_dkdev); |
|
disk_destroy(&dksc->sc_dkdev); |
|
|
|
return 0; |
|
} |
|
</code></pre> |
|
|
|
---- |
|
|
## Autoconf interface |
## Autoconf interface |
|
|
<pre><code> |
<pre><code> |
Line 236 xxx_match(device_t self, cfdata_t cfdata
|
Line 286 xxx_match(device_t self, cfdata_t cfdata
|
static void |
static void |
xxx_attach(device_t parent, device_t self, void *aux) |
xxx_attach(device_t parent, device_t self, void *aux) |
{ |
{ |
|
#ifndef _MODULE |
|
xxx_init(self); |
|
#endif |
} |
} |
|
|
static void |
static void |
xxx_detach(device_t self, int flags) |
xxx_detach(device_t self, int flags) |
{ |
{ |
struct xxx_softc *sc = device_private(self); |
#ifndef _MODULE |
struct dk_softc *dksc = &sc->sc_dksc; |
xxx_finish(self); |
|
#endif |
|
} |
|
</code></pre> |
|
|
dkwedge_delall(&dksc->sc_dkdev); |
---- |
|
|
dk_drain(dksc); |
## Kernel module interface |
bufq_free(dksc->sc_bufq); |
|
|
|
dk_detach(dksc); |
<pre><code> |
disk_detach(&dksc->sc_dkdev); |
MODULE(MODULE_CLASS_DRIVER, xxx, "dk_subr"); |
disk_destroy(&dksc->sc_dkdev); |
|
|
static int |
|
xxx_modcmd(modcmd_t cmd, void *data) |
|
{ |
|
int error; |
|
#ifdef _MODULE |
|
int bmajor, cmajor; |
|
#endif |
|
|
|
error = 0; |
|
switch (cmd) { |
|
case MODULE_CMD_INIT: |
|
#ifdef _MODULE |
|
bmajor = cmajor = -1; |
|
error = devsw_attach("xxx", &xxx_bdevsw, &bmajor, |
|
&xxx_cdevsw, &cmajor); |
|
if (error) { |
|
aprint_error("%s: devsw_attach failed %d\n", |
|
xxx_cd.cd_name, error); |
|
break; |
|
} |
|
error = config_cfdriver_attach(&xxx_cd); |
|
if (error) { |
|
aprint_error("%s: config_cfdriver_attach failed %d\n", |
|
xxx_cd.cd_name, error); |
|
devsw_detach(&xxx_bdevsw, &xxx_cdevsw); |
|
break; |
|
} |
|
error = config_cfattach_attach(&xxx_cd); |
|
if (error) { |
|
aprint_error("%s: config_cfattach_attach failed %d\n", |
|
xxx_cd.cd_name, error); |
|
config_cfdriver_detach(&xxx_cd); |
|
devsw_detach(&xxx_bdevsw, &xxx_cdevsw); |
|
break; |
|
} |
|
// some global initialization |
|
|
|
// magic happens to create device instances |
|
|
|
// sometimes by calling config_attach_pseudo |
|
// sometimes by faking structures manually |
|
// using config_attach_loc might be possible |
|
// sometimes by calling xxxattach(0) which |
|
// uses one of the methods |
|
#endif |
|
break; |
|
case MODULE_CMD_FINI: |
|
// magic happens to destroy device instances |
|
|
|
// some global finalization |
|
#ifdef _MODULE |
|
error = config_cfattach_detach(&xxx_cd.cd_name, &xxx_ca); |
|
if (error) |
|
break; |
|
config_cfdriver_detach(&xxx_cd); |
|
devsw_detach(&xxx_bdevsw, &xxx_cdevsw); |
|
#endif |
|
break; |
|
case MODULE_CMD_STAT: |
|
error = ENOTTY; |
|
break; |
|
default: |
|
error = ENOTTY; |
|
break; |
|
} |
|
|
|
return error; |
} |
} |
</code></pre> |
</code></pre> |
|
|