diff options
-rw-r--r-- | usr/src/uts/intel/io/ipmi/ipmi_main.c | 25 |
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); |