--- wikisrc/users/mlelstv/disk-driver-template.mdwn 2015/12/21 11:44:20 1.5 +++ wikisrc/users/mlelstv/disk-driver-template.mdwn 2016/12/08 11:39:34 1.12 @@ -25,7 +25,7 @@ const struct bdevsw xxx_bdevsww= { .d_dump = xxxdump, .d_psize = xxxsize, .d_discard = xxxdiscard, - .d_flag = D_DISK + .d_flag = D_DISK | D_MPSAFE }; const struct cdevsw xxx_cdevsw = { @@ -40,7 +40,7 @@ const struct cdevsw xxx_cdevsw = { .d_mmap = nommap, .d_kqfilter = nokqfilter, .d_discard = xxxdiscard, - .d_flag = D_DISK + .d_flag = D_DISK | D_MPSAFE }; static void xxxminphys(struct buf *bp); @@ -54,17 +54,25 @@ static const struct dkdriver xxxdkdriver .d_open = xxxopen, .d_close = xxxclose, .d_strategy = xxxstrategy, - .d_iosize = xxx_iosize, .d_minphys = xxxminphys, .d_diskstart = xxx_diskstart, - .d_dumpblocks = xxx_dumpblocks, - .d_lastclose = xxx_lastclose, - .d_discard = xxx_discard + .d_discard = xxx_discard, + .d_dumpblocks = xxx_dumpblocks, /* optional */ + .d_iosize = xxx_iosize, /* optional */ + .d_lastclose = xxx_lastclose, /* optional */ + .d_firstopen = xxx_firstopen, /* optional */ + .d_label = xxx_label, /* optional */ }; static int xxx_match(device_t, cfdata_t, void *); static void xxx_attach(device_t, device_t, void *); static int xxx_detach(device_t, int); +static int xxx_activate(device_t, enum devact); + +struct xxx_softc { + struct dk_softc sc_dksc; /* generic disk interface */ + // private data +}; CFATTACH_DECL3_NEW(xxx, sizeof(struct xxx_softc), xxx_match, xxx_attach, xxx_detach, NULL, NULL, NULL, DVF_DETACH_SHUTDOWN); @@ -72,7 +80,9 @@ CFATTACH_DECL3_NEW(xxx, sizeof(struct xx extern struct cfdriver xxx_cd; #ifdef PSEUDODEVICE -static void xxxattach(int num); +static void xxxattach(int); +static device_t xxx_create(int); +static int xxx_destroy(device_t); #endif static int xxx_init(device_t); @@ -101,6 +111,7 @@ static int xxxdone(struct buf *); void xxxattach(int num) { +#ifndef _MODULE int error; error = config_cfattach_attach(xxx_cd.cd_name, &xxx_ca); @@ -111,6 +122,43 @@ xxxattach(int num) } // some global initialization +#endif +} + +static device_t +xxx_create(int unit) +{ + cfdata_t cf; + device_t dv; + + cf = malloc(sizeof(*cf), M_DEVBUF, M_WAITOK); + cf->cf_name = xxx_cd.cd_name; + cf->cf_atname = xxx_cd.cd_name; + cf->cf_unit = unit; + cf->cf_fstate = FSTATE_STAR; + + dv = config_attach_pseudo(cf); + if (dv == NULL) { + aprint_error("%s: failed to attach pseudo device\n", + xxx_cd.cd_name); + free(cf, M_DEVBUF); + } + + return dv; +} + +static int +xxx_destroy(device_t dv) +{ + int error; + cfdata_t cf; + + cf = device_cfdata(dv); + error = config_detach(dev, DETACH_QUIET); + if (error) + return error; + free(cf, M_DEVBUF); + return 0; } #endif @@ -298,6 +346,19 @@ xxx_detach(device_t self, int flags) xxx_finish(self); #endif } + +static int +xxx_activate(device_t self, enum devact act) +{ + // switch (act) { + // case DVACT_ACTIVATE: + // return 0; + // case DVACT_DEACTIVATE: + // return 0; + // } + + return EOPNOTSUPP; +} ---- @@ -344,18 +405,12 @@ xxx_modcmd(modcmd_t cmd, void *data) } // 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 +#ifdef PSEUDODEVICE + xxxattach(0); #endif break; case MODULE_CMD_FINI: - // magic happens to destroy device instances - + // outside of #ifdef _MODULE to allow removal of builtins // some global finalization #ifdef _MODULE error = config_cfattach_detach(&xxx_cd.cd_name, &xxx_ca); @@ -383,6 +438,14 @@ xxx_modcmd(modcmd_t cmd, void *data)

 static int
+xxx_firstopen(device_t dv)
+{
+	// private startup
+
+	return 0;
+}
+
+static int
 xxx_lastclose(device_t dv)
 {
 	// private cleanup
@@ -401,6 +464,7 @@ static int
 xxx_dumpblocks(device_t dv, void *va, daddr_t blkno, int nblk)
 {
 	// issue polling I/O to dump a page
+	// return error
 }
 
 static void
@@ -413,7 +477,16 @@ static int
 xxx_discard(device_t dv, off_t pos, off_t len)
 {
 	// issue request to discard bytes
+	// return error
 }
+
+static void
+xxx_label(device_t dv, struct disklabel *lp)
+{
+	// lp is initialized for generic disk
+	// augment with driver specific information
+}
+
 
---- @@ -432,12 +505,6 @@ xxxstrategy(struct buf *bp) // wake up I/O thread } -static int -xxx_diskstart(device_t dv, struct buf *bp) -{ - // issue I/O for bp -} - static void xxxdone(struct xxx_softc *sc, struct buf *bp) { @@ -448,7 +515,7 @@ xxxdone(struct xxx_softc *sc, struct buf } static void -xxx_IOTHREAD(struct dk_softc *dksc) +xxx_iothread(struct dk_softc *dksc) { while (!shutting_down) { if (dk_strategy_pending(dksc))