summaryrefslogtreecommitdiff
path: root/sys/dev/softraid.c
diff options
context:
space:
mode:
authorMarco Peereboom <marco@cvs.openbsd.org>2009-06-11 19:43:00 +0000
committerMarco Peereboom <marco@cvs.openbsd.org>2009-06-11 19:43:00 +0000
commit5d2d546082ffef5bdb2d921b766595505bb631a8 (patch)
treed62b395bb9f54f7ae99b94a85138e152cf02c13c /sys/dev/softraid.c
parent1a9363650f46e664c969188b567d6865088e964e (diff)
Create a hotplug callback mechanism.
Diffstat (limited to 'sys/dev/softraid.c')
-rw-r--r--sys/dev/softraid.c89
1 files changed, 72 insertions, 17 deletions
diff --git a/sys/dev/softraid.c b/sys/dev/softraid.c
index ea734fd9f60..0c681a11e49 100644
--- a/sys/dev/softraid.c
+++ b/sys/dev/softraid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid.c,v 1.147 2009/06/10 21:37:17 marco Exp $ */
+/* $OpenBSD: softraid.c,v 1.148 2009/06/11 19:42:59 marco Exp $ */
/*
* Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org>
@@ -144,6 +144,30 @@ void sr_meta_chunks_create(struct sr_softc *,
void sr_meta_init(struct sr_discipline *,
struct sr_chunk_head *);
+/* hotplug magic */
+void sr_disk_attach(struct disk *, int);
+
+struct sr_hotplug_list {
+ void (*sh_hotplug)(struct sr_discipline *,
+ struct disk *, int);
+ struct sr_discipline *sh_sd;
+
+ SLIST_ENTRY(sr_hotplug_list) shl_link;
+};
+SLIST_HEAD(sr_hotplug_list_head, sr_hotplug_list);
+
+struct sr_hotplug_list_head sr_hotplug_callbacks;
+extern void (*softraid_disk_attach)(struct disk *, int);
+
+/* scsi glue */
+struct scsi_adapter sr_switch = {
+ sr_scsi_cmd, sr_minphys, NULL, NULL, sr_scsi_ioctl
+};
+
+struct scsi_device sr_dev = {
+ NULL, NULL, NULL, NULL
+};
+
/* native metadata format */
int sr_meta_native_bootprobe(struct sr_softc *,
struct device *, struct sr_metadata_list_head *);
@@ -1206,29 +1230,54 @@ sr_meta_native_write(struct sr_discipline *sd, dev_t dev,
B_WRITE));
}
-struct scsi_adapter sr_switch = {
- sr_scsi_cmd, sr_minphys, NULL, NULL, sr_scsi_ioctl
-};
+void
+sr_hotplug_register(struct sr_discipline *sd, void *func)
+{
+ struct sr_hotplug_list *mhe;
-struct scsi_device sr_dev = {
- NULL, NULL, NULL, NULL
-};
+ DNPRINTF(SR_D_MISC, "%s: sr_hotplug_register: %p\n",
+ DEVNAME(sd->sd_sc), func);
-void sr_disk_attach(struct disk *, int);
+ /* make sure we aren't on the list yet */
+ SLIST_FOREACH(mhe, &sr_hotplug_callbacks, shl_link)
+ if (mhe->sh_hotplug == func)
+ return;
-extern void (*softraid_disk_attach)(struct disk *, int);
+ mhe = malloc(sizeof(struct sr_hotplug_list), M_DEVBUF,
+ M_WAITOK | M_ZERO);
+ mhe->sh_hotplug = func;
+ mhe->sh_sd = sd;
+ SLIST_INSERT_HEAD(&sr_hotplug_callbacks, mhe, shl_link);
+}
+
+void
+sr_hotplug_unregister(struct sr_discipline *sd, void *func)
+{
+ struct sr_hotplug_list *mhe;
+
+ DNPRINTF(SR_D_MISC, "%s: sr_hotplug_unregister: %s %p\n",
+ DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, func);
+
+ /* make sure we are on the list yet */
+ SLIST_FOREACH(mhe, &sr_hotplug_callbacks, shl_link)
+ if (mhe->sh_hotplug == func) {
+ SLIST_REMOVE(&sr_hotplug_callbacks, mhe,
+ sr_hotplug_list, shl_link);
+ free(mhe, M_DEVBUF);
+ if (SLIST_EMPTY(&sr_hotplug_callbacks))
+ SLIST_INIT(&sr_hotplug_callbacks);
+ return;
+ }
+}
void
sr_disk_attach(struct disk *diskp, int action)
{
- switch (action) {
- case 1:
- /* disk arrived */
- break;
- case -1:
- /* disk departed */
- break;
- }
+ struct sr_hotplug_list *mhe;
+
+ SLIST_FOREACH(mhe, &sr_hotplug_callbacks, shl_link)
+ if (mhe->sh_sd->sd_ready)
+ mhe->sh_hotplug(mhe->sh_sd, diskp, action);
}
int
@@ -1246,6 +1295,8 @@ sr_attach(struct device *parent, struct device *self, void *aux)
rw_init(&sc->sc_lock, "sr_lock");
+ SLIST_INIT(&sr_hotplug_callbacks);
+
if (bio_register(&sc->sc_dev, sr_ioctl) != 0)
printf("%s: controller registration failed", DEVNAME(sc));
else
@@ -2312,6 +2363,8 @@ sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user)
if (sd->sd_vol_status == BIOC_SVREBUILD)
kthread_create_deferred(sr_rebuild, sd);
+ sd->sd_ready = 1;
+
return (rv);
unwind:
sr_discipline_shutdown(sd);
@@ -2422,6 +2475,8 @@ sr_discipline_shutdown(struct sr_discipline *sd)
s = splbio();
+ sd->sd_ready = 0;
+
if (sd->sd_shutdownhook)
shutdownhook_disestablish(sd->sd_shutdownhook);