Mercurial > illumos > wpa
changeset 14035:9992f781c89a
3770 ipmi drivers hangs due to attach/detach/attach cycle
Reviewed by: Hans Rosenfeld <hans.rosenfeld@nexenta.com>
Reviewed by: Albert Lee <trisk@nexenta.com>
Reviewed by: Saso Kiselkov <skiselkov.ml@gmail.com>
Approved by: Richard Lowe <richlowe@richlowe.net>
author | Alek Pinchuk <alek@nexenta.com> |
---|---|
date | Fri, 24 May 2013 12:35:17 -0500 |
parents | e4eb37f33d60 |
children | 9f368de5660f 10b779d783d1 |
files | usr/src/uts/intel/io/ipmi/ipmi.c usr/src/uts/intel/io/ipmi/ipmi_main.c usr/src/uts/intel/io/ipmi/ipmivars.h |
diffstat | 3 files changed, 50 insertions(+), 11 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/intel/io/ipmi/ipmi.c Thu May 23 13:07:25 2013 -0400 +++ b/usr/src/uts/intel/io/ipmi/ipmi.c Fri May 24 12:35:17 2013 -0500 @@ -28,6 +28,7 @@ /* * Copyright 2012, Joyent, Inc. All rights reserved. + * Copyright 2013, Nexenta Systems, Inc. All rights reserved. */ #include <sys/devops.h> @@ -178,6 +179,18 @@ } void +ipmi_shutdown(struct ipmi_softc *sc) +{ + taskq_destroy(sc->ipmi_kthread); + + cv_destroy(&sc->ipmi_request_added); + mutex_destroy(&sc->ipmi_lock); + + cv_destroy(&slplock); + mutex_destroy(&slpmutex); +} + +boolean_t ipmi_startup(struct ipmi_softc *sc) { struct ipmi_request *req; @@ -195,7 +208,7 @@ error = sc->ipmi_startup(sc); if (error) { cmn_err(CE_WARN, "Failed to initialize interface: %d", error); - return; + return (B_FALSE); } /* Send a GET_DEVICE_ID request. */ @@ -206,22 +219,22 @@ if (error == EWOULDBLOCK) { cmn_err(CE_WARN, "Timed out waiting for GET_DEVICE_ID"); ipmi_free_request(req); - return; + return (B_FALSE); } else if (error) { cmn_err(CE_WARN, "Failed GET_DEVICE_ID: %d", error); ipmi_free_request(req); - return; + return (B_FALSE); } else if (req->ir_compcode != 0) { cmn_err(CE_WARN, "Bad completion code for GET_DEVICE_ID: %d", req->ir_compcode); ipmi_free_request(req); - return; + return (B_FALSE); } else if (req->ir_replylen < 5) { cmn_err(CE_WARN, "Short reply for GET_DEVICE_ID: %d", req->ir_replylen); ipmi_free_request(req); - return; + return (B_FALSE); } cmn_err(CE_CONT, "!device rev. %d, firmware rev. %d.%d%d, " @@ -235,8 +248,11 @@ req = ipmi_alloc_driver_request(IPMI_ADDR(IPMI_APP_REQUEST, 0), IPMI_CLEAR_FLAGS, 1, 0); - if ((error = ipmi_submit_driver_request(sc, req, 0)) != 0) + if ((error = ipmi_submit_driver_request(sc, req, 0)) != 0) { cmn_err(CE_WARN, "Failed to clear IPMI flags: %d\n", error); + ipmi_free_request(req); + return (B_FALSE); + } /* Magic numbers */ if (req->ir_compcode == 0xc0) { @@ -272,7 +288,7 @@ if ((error = ipmi_submit_driver_request(sc, req, 0)) != 0) { cmn_err(CE_WARN, "Failed to check IPMI watchdog: %d\n", error); ipmi_free_request(req); - return; + return (B_FALSE); } if (req->ir_compcode == 0x00) { @@ -284,4 +300,6 @@ */ } ipmi_free_request(req); + + return (B_TRUE); }
--- a/usr/src/uts/intel/io/ipmi/ipmi_main.c Thu May 23 13:07:25 2013 -0400 +++ b/usr/src/uts/intel/io/ipmi/ipmi_main.c Fri May 24 12:35:17 2013 -0500 @@ -21,6 +21,7 @@ /* * Copyright 2012, Joyent, Inc. All rights reserved. + * Copyright 2013, Nexenta Systems, Inc. All rights reserved. */ /* @@ -487,6 +488,14 @@ if (cmd != DDI_ATTACH) return (DDI_FAILURE); + /* this driver only supports one device instance */ + if (ddi_get_instance(dip) != 0) { + cmn_err(CE_WARN, + "!not attaching to non-zero device instance %d", + ddi_get_instance(dip)); + return (DDI_FAILURE); + } + if (get_smbios_ipmi_info() == DDI_FAILURE) return (DDI_FAILURE); @@ -518,7 +527,11 @@ /* Create ID space for open devs. ID 0 is reserved. */ minor_ids = id_space_create("ipmi_id_space", 1, 128); - ipmi_startup(sc); + if (ipmi_startup(sc) != B_TRUE) { + ipmi_shutdown(sc); + return (DDI_FAILURE); + } + ipmi_attached = B_TRUE; return (DDI_SUCCESS); @@ -540,13 +553,14 @@ sc->ipmi_detaching = 1; cv_signal(&sc->ipmi_request_added); + ipmi_shutdown(sc); ddi_remove_minor_node(dip, NULL); ipmi_dip = NULL; - taskq_destroy(sc->ipmi_kthread); list_destroy(&dev_list); id_space_destroy(minor_ids); + sc->ipmi_detaching = 0; ipmi_attached = B_FALSE; return (DDI_SUCCESS); } @@ -566,7 +580,10 @@ ipmi_poll, ddi_prop_op, NULL, /* streamtab */ - D_NEW | D_MP /* flags */ + D_NEW | D_MP, /* flags */ + CB_REV, + nodev, /* awread */ + nodev /* awrite */ }; static struct dev_ops ipmi_ops = {
--- a/usr/src/uts/intel/io/ipmi/ipmivars.h Thu May 23 13:07:25 2013 -0400 +++ b/usr/src/uts/intel/io/ipmi/ipmivars.h Fri May 24 12:35:17 2013 -0500 @@ -28,6 +28,7 @@ /* * Copyright 2012, Joyent, Inc. All rights reserved. + * Copyright 2013, Nexenta Systems, Inc. All rights reserved. */ #ifndef _IPMIVARS_H_ @@ -179,9 +180,12 @@ void ipmi_free_request(struct ipmi_request *); /* Interface attach routines. */ -void ipmi_startup(struct ipmi_softc *sc); +boolean_t ipmi_startup(struct ipmi_softc *sc); int ipmi_kcs_attach(struct ipmi_softc *); +/* Interface detach cleanup */ +void ipmi_shutdown(struct ipmi_softc *sc); + #ifdef __cplusplus } #endif