summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--usr/src/uts/intel/io/ipmi/ipmi_main.c25
1 files changed, 22 insertions, 3 deletions
diff --git a/usr/src/uts/intel/io/ipmi/ipmi_main.c b/usr/src/uts/intel/io/ipmi/ipmi_main.c
index 812314f54e..d682c5d892 100644
--- a/usr/src/uts/intel/io/ipmi/ipmi_main.c
+++ b/usr/src/uts/intel/io/ipmi/ipmi_main.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2012, Joyent, Inc. All rights reserved.
+ * Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright 2013, Nexenta Systems, Inc. All rights reserved.
*/
@@ -65,6 +65,7 @@ static struct ipmi_softc softc;
static struct ipmi_softc *sc = &softc;
static list_t dev_list;
static id_space_t *minor_ids;
+static kmutex_t dev_list_lock;
#define PTRIN(p) ((void *)(uintptr_t)(p))
#define PTROUT(p) ((uintptr_t)(p))
@@ -130,10 +131,14 @@ lookup_ipmidev_by_dev(dev_t dev)
{
ipmi_device_t *p;
+ mutex_enter(&dev_list_lock);
for (p = list_head(&dev_list); p; p = list_next(&dev_list, p)) {
- if (dev == p->ipmi_dev)
+ if (dev == p->ipmi_dev) {
+ mutex_exit(&dev_list_lock);
return (p);
+ }
}
+ mutex_exit(&dev_list_lock);
return (NULL);
}
@@ -171,7 +176,9 @@ ipmi_open(dev_t *devp, int flag, int otyp, cred_t *cred)
*devp = makedevice(getmajor(*devp), minor);
dev->ipmi_dev = *devp;
+ mutex_enter(&dev_list_lock);
list_insert_head(&dev_list, dev);
+ mutex_exit(&dev_list_lock);
return (0);
}
@@ -206,7 +213,9 @@ ipmi_close(dev_t dev, int flag, int otyp, cred_t *cred)
ipmi_free_request(req);
}
+ mutex_enter(&dev_list_lock);
list_remove(&dev_list, dp);
+ mutex_exit(&dev_list_lock);
id_free(minor_ids, getminor(dev));
kmem_free(dp->ipmi_pollhead, sizeof (pollhead_t));
kmem_free(dp, sizeof (ipmi_device_t));
@@ -523,12 +532,17 @@ ipmi_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
list_create(&dev_list, sizeof (ipmi_device_t),
offsetof(ipmi_device_t, ipmi_node));
+ mutex_init(&dev_list_lock, NULL, MUTEX_DRIVER, NULL);
/* Create ID space for open devs. ID 0 is reserved. */
minor_ids = id_space_create("ipmi_id_space", 1, 128);
if (ipmi_startup(sc) != B_TRUE) {
ipmi_shutdown(sc);
+ id_space_destroy(minor_ids);
+ mutex_destroy(&dev_list_lock);
+ list_destroy(&dev_list);
+ ddi_remove_minor_node(dip, NULL);
return (DDI_FAILURE);
}
@@ -546,8 +560,12 @@ ipmi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
if (ipmi_found == B_FALSE)
return (DDI_SUCCESS);
- if (!list_is_empty(&dev_list))
+ mutex_enter(&dev_list_lock);
+ if (!list_is_empty(&dev_list)) {
+ mutex_exit(&dev_list_lock);
return (DDI_FAILURE);
+ }
+ mutex_exit(&dev_list_lock);
/* poke the taskq so that it can terminate */
sc->ipmi_detaching = 1;
@@ -557,6 +575,7 @@ ipmi_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
ddi_remove_minor_node(dip, NULL);
ipmi_dip = NULL;
+ mutex_destroy(&dev_list_lock);
list_destroy(&dev_list);
id_space_destroy(minor_ids);