summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/io/mac/mac.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/uts/common/io/mac/mac.c')
-rw-r--r--usr/src/uts/common/io/mac/mac.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/usr/src/uts/common/io/mac/mac.c b/usr/src/uts/common/io/mac/mac.c
index 3bc71547de..d564add30d 100644
--- a/usr/src/uts/common/io/mac/mac.c
+++ b/usr/src/uts/common/io/mac/mac.c
@@ -33,6 +33,7 @@
#include <sys/types.h>
#include <sys/conf.h>
#include <sys/id_space.h>
+#include <sys/esunddi.h>
#include <sys/stat.h>
#include <sys/mkdev.h>
#include <sys/stream.h>
@@ -507,6 +508,19 @@ mac_open(const char *macname, mac_handle_t *mhp)
if ((err = mac_hold(macname, &mip)) != 0)
return (err);
+ /*
+ * Hold the dip associated to the MAC to prevent it from being
+ * detached. For a softmac, its underlying dip is held by the
+ * mi_open() callback.
+ *
+ * This is done to be more tolerant with some defective drivers,
+ * which incorrectly handle mac_unregister() failure in their
+ * xxx_detach() routine. For example, some drivers ignore the
+ * failure of mac_unregister() and free all resources that
+ * that are needed for data transmition.
+ */
+ e_ddi_hold_devi(mip->mi_dip);
+
rw_enter(&mip->mi_gen_lock, RW_WRITER);
if ((mip->mi_oref != 0) ||
@@ -521,6 +535,7 @@ mac_open(const char *macname, mac_handle_t *mhp)
*/
if ((err = mip->mi_open(mip->mi_driver)) != 0) {
rw_exit(&mip->mi_gen_lock);
+ ddi_release_devi(mip->mi_dip);
mac_rele(mip);
return (err);
}
@@ -578,6 +593,7 @@ mac_close(mac_handle_t mh)
}
rw_exit(&mip->mi_gen_lock);
+ ddi_release_devi(mip->mi_dip);
mac_rele(mip);
}