summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/stmsboot/stmsboot_util.c3
-rw-r--r--usr/src/common/devid/devid_scsi.c236
-rw-r--r--usr/src/head/devid.h11
-rw-r--r--usr/src/lib/libdevid/libdevid.h27
-rw-r--r--usr/src/lib/libdevid/mapfile-vers6
-rw-r--r--usr/src/uts/common/io/scsi/impl/scsi_hba.c98
-rw-r--r--usr/src/uts/common/sys/scsi/scsi_address.h21
-rw-r--r--usr/src/uts/common/sys/sunddi.h3
8 files changed, 270 insertions, 135 deletions
diff --git a/usr/src/cmd/stmsboot/stmsboot_util.c b/usr/src/cmd/stmsboot/stmsboot_util.c
index 06af0ca964..97c14fae44 100644
--- a/usr/src/cmd/stmsboot/stmsboot_util.c
+++ b/usr/src/cmd/stmsboot/stmsboot_util.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -39,6 +39,7 @@
#include <locale.h>
#include <libintl.h>
#include <devid.h>
+#include <sys/libdevid.h>
#include <sys/modctl.h> /* for MAXMODCONFNAME */
#include <sys/scsi/adapters/scsi_vhci.h>
diff --git a/usr/src/common/devid/devid_scsi.c b/usr/src/common/devid/devid_scsi.c
index 38c0192098..45aaacbf0d 100644
--- a/usr/src/common/devid/devid_scsi.c
+++ b/usr/src/common/devid/devid_scsi.c
@@ -29,6 +29,11 @@
* Solaris devid / guid values.
*/
+#ifndef _KERNEL
+#include <stdio.h>
+#endif /* _KERNEL */
+
+#include <sys/inttypes.h>
#include <sys/types.h>
#include <sys/stropts.h>
#include <sys/debug.h>
@@ -1214,38 +1219,233 @@ ctoi(char c)
return (c);
}
+/* ====NOTE: The scsi_* interfaces are not related to devids :NOTE==== */
+
/*
- * Function: devid_str_to_wwn
+ * Function: scsi_wwnstr_to_wwn
*
- * Description: This routine translates wwn from string to uint64 type.
+ * Description: This routine translates wwn from wwnstr string to uint64 wwn.
*
- * Arguments: string - the string wwn to be transformed
- * wwn - the pointer to 64 bit wwn
+ * Arguments: wwnstr - the string wwn to be transformed
+ * wwnp - the pointer to 64 bit wwn
*/
int
-#ifdef _KERNEL
-ddi_devid_str_to_wwn(const char *string, uint64_t *wwn)
-#else /* !_KERNEL */
-devid_str_to_wwn(const char *string, uint64_t *wwn)
-#endif /* _KERNEL */
+scsi_wwnstr_to_wwn(const char *wwnstr, uint64_t *wwnp)
{
- int i;
- char cl, ch;
- uint64_t tmp;
+ int i;
+ char cl, ch;
+ uint64_t tmp;
- if (wwn == NULL || strlen(string) != 16) {
+ if (wwnp == NULL)
+ return (DDI_FAILURE);
+ *wwnp = 0;
+
+ if (wwnstr == NULL)
+ return (DDI_FAILURE);
+
+ /* Skip leading 'w' if wwnstr is in unit-address form */
+ if (*wwnstr == 'w')
+ wwnstr++;
+
+ if (strlen(wwnstr) != 16)
return (DDI_FAILURE);
- }
- *wwn = 0;
for (i = 0; i < 8; i++) {
- ch = ctoi(*string++);
- cl = ctoi(*string++);
+ ch = ctoi(*wwnstr++);
+ cl = ctoi(*wwnstr++);
if (cl == -1 || ch == -1) {
return (DDI_FAILURE);
}
tmp = (ch << 4) + cl;
- *wwn = (*wwn << 8) | tmp;
+ *wwnp = (*wwnp << 8) | tmp;
}
return (DDI_SUCCESS);
}
+
+/*
+ * Function: scsi_wwn_to_wwnstr
+ *
+ * Description: This routine translates from a uint64 wwn to a wwnstr
+ *
+ * Arguments:
+ * wwn - the 64 bit wwn
+ * unit_address_form - do we want a leading 'w'?
+ * wwnstr - allow caller to perform wwnstr allocation.
+ * If non-NULL, don't use scsi_free_wwnstr(),
+ * and make sure you provide 18/17 bytes of space.
+ */
+char *
+scsi_wwn_to_wwnstr(uint64_t wwn, int unit_address_form, char *wwnstr)
+{
+ int len;
+
+ /* make space for leading 'w' */
+ if (unit_address_form)
+ len = 1 + 16 + 1; /* "w0123456789abcdef\0" */
+ else
+ len = 16 + 1; /* "0123456789abcdef\0" */
+
+ if (wwnstr == NULL) {
+ /* We allocate, caller uses scsi_free_wwnstr(). */
+ if ((wwnstr = DEVID_MALLOC(len)) == NULL)
+ return (NULL);
+ }
+
+ if (unit_address_form)
+ (void) snprintf(wwnstr, len, "w%016" PRIx64, wwn);
+ else
+ (void) snprintf(wwnstr, len, "%016" PRIx64, wwn);
+ return (wwnstr);
+}
+
+/*
+ * Function: scsi_wwnstr_hexcase
+ *
+ * Description: This routine switches a wwnstr to upper/lower case hex
+ * (a wwnstr uses lower-case hex by default).
+ *
+ * Arguments:
+ * wwnstr - the pointer to the wwnstr string.
+ * upper_case_hex - non-zero will convert to upper_case hex
+ * zero will convert to lower case hex.
+ */
+void
+scsi_wwnstr_hexcase(char *wwnstr, int upper_case_hex)
+{
+ char *s;
+ char c;
+
+ for (s = wwnstr; *s; s++) {
+ c = *s;
+ if ((upper_case_hex != 0) &&
+ ((c >= 'a') && (c <= 'f')))
+ c -= ('a' - 'A'); /* lower to upper */
+ else if ((upper_case_hex == 0) &&
+ ((c >= 'A') && (c <= 'F')))
+ c += ('a' - 'A'); /* upper to lower */
+ *s = c;
+ }
+}
+
+/*
+ * Function: scsi_wwnstr_free
+ *
+ * Description: This routine frees a wwnstr returned by a call
+ * to scsi_wwn_to_strwwn with a NULL wwnstr argument.
+ *
+ * Arguments:
+ * wwnstr - the pointer to the wwnstr string to free.
+ */
+void
+scsi_free_wwnstr(char *wwnstr)
+{
+#ifdef _KERNEL
+ kmem_free(wwnstr, strlen(wwnstr) + 1);
+#else /* _KERNEL */
+ free(wwnstr);
+#endif /* _KERNEL */
+}
+
+/*
+ * Function: scsi_lun_to_lun64/scsi_lun64_to_lun
+ *
+ * Description: Convert between normalized (SCSI-3) LUN format, as
+ * described by scsi_lun_t, and a normalized lun64_t
+ * representation (used by Solaris SCSI_ADDR_PROP_LUN64
+ * "lun64" property). The normalized representation maps
+ * in a compatible way to SCSI-2 LUNs. See scsi_address.h
+ *
+ * SCSI-3 LUNs are 64 bits. SCSI-2 LUNs are 3 bits (up to
+ * 5 bits in non-compliant implementations). SCSI-3 will
+ * pass a (64-bit) scsi_lun_t, but we need a
+ * representation from which we can for example, make
+ * device names. For unit-address compatibility, we represent
+ * 64-bit LUN numbers in such a way that they appear like they
+ * would have under SCSI-2. This means that the single level
+ * LUN number is in the lowest byte with the second,
+ * third, and fourth level LUNs represented in
+ * successively higher bytes. In particular, if (and only
+ * if) the first byte of a 64 bit LUN is zero, denoting
+ * "Peripheral Device Addressing Method" and "Bus
+ * Identifier" zero, then the target implements LUNs
+ * compatible in spirit with SCSI-2 LUNs (although under
+ * SCSI-3 there may be up to 256 of them). Under SCSI-3
+ * rules, a target is *required* to use this format if it
+ * contains 256 or fewer Logical Units, none of which are
+ * dependent logical units. These routines have knowledge
+ * of the structure and size of a scsi_lun_t.
+ *
+ * NOTE: We tolerate vendors that use "Single level LUN structure using
+ * peripheral device addressing method" with a non-zero bus identifier
+ * (spec says bus identifier must be zero). Described another way, we let
+ * the non-'addressing method' bits of sl_lun1_msb contribute to our lun64
+ * value).
+ */
+scsi_lun64_t
+scsi_lun_to_lun64(scsi_lun_t lun)
+{
+ scsi_lun64_t lun64;
+
+ /*
+ * Check to see if we have a single level lun that uses the
+ * "Peripheral Device" addressing method. If so, the lun64 value is
+ * kept in Solaris 'unit-address compatibility' form.
+ */
+ if (((lun.sl_lun2_msb == 0) && (lun.sl_lun2_lsb == 0) &&
+ (lun.sl_lun3_msb == 0) && (lun.sl_lun3_lsb == 0) &&
+ (lun.sl_lun4_msb == 0) && (lun.sl_lun4_lsb == 0)) &&
+ ((lun.sl_lun1_msb & SCSI_LUN_AM_MASK) == SCSI_LUN_AM_PDEV)) {
+ /*
+ * LUN has Solaris 'unit-address compatibility' form, construct
+ * lun64 value from non-'addressing method' bits of msb and lsb.
+ */
+ lun64 = ((lun.sl_lun1_msb & ~SCSI_LUN_AM_MASK) << 8) |
+ lun.sl_lun1_lsb;
+ } else {
+ /*
+ * LUN does not have a Solaris 'unit-address compatibility'
+ * form, construct lun64 value in full 64 bit LUN format.
+ */
+ lun64 =
+ ((scsi_lun64_t)lun.sl_lun1_msb << 56) |
+ ((scsi_lun64_t)lun.sl_lun1_lsb << 48) |
+ ((scsi_lun64_t)lun.sl_lun2_msb << 40) |
+ ((scsi_lun64_t)lun.sl_lun2_lsb << 32) |
+ ((scsi_lun64_t)lun.sl_lun3_msb << 24) |
+ ((scsi_lun64_t)lun.sl_lun3_lsb << 16) |
+ ((scsi_lun64_t)lun.sl_lun4_msb << 8) |
+ (scsi_lun64_t)lun.sl_lun4_lsb;
+ }
+ return (lun64);
+}
+
+scsi_lun_t
+scsi_lun64_to_lun(scsi_lun64_t lun64)
+{
+ scsi_lun_t lun;
+
+ if (lun64 <= (((0xFF & ~SCSI_LUN_AM_MASK) << 8) | 0xFF)) {
+ /*
+ * lun64 is in Solaris 'unit-address compatibility' form.
+ */
+ lun.sl_lun1_msb = SCSI_LUN_AM_PDEV | (lun64 >> 8);
+ lun.sl_lun1_lsb = (uchar_t)lun64;
+ lun.sl_lun2_msb = 0;
+ lun.sl_lun2_lsb = 0;
+ lun.sl_lun3_msb = 0;
+ lun.sl_lun3_lsb = 0;
+ lun.sl_lun4_msb = 0;
+ lun.sl_lun4_lsb = 0;
+ } else {
+ /* lun64 is in full 64 bit LUN format. */
+ lun.sl_lun1_msb = (uchar_t)(lun64 >> 56);
+ lun.sl_lun1_lsb = (uchar_t)(lun64 >> 48);
+ lun.sl_lun2_msb = (uchar_t)(lun64 >> 40);
+ lun.sl_lun2_lsb = (uchar_t)(lun64 >> 32);
+ lun.sl_lun3_msb = (uchar_t)(lun64 >> 24);
+ lun.sl_lun3_lsb = (uchar_t)(lun64 >> 16);
+ lun.sl_lun4_msb = (uchar_t)(lun64 >> 8);
+ lun.sl_lun4_lsb = (uchar_t)(lun64);
+ }
+ return (lun);
+}
diff --git a/usr/src/head/devid.h b/usr/src/head/devid.h
index 55ff93df64..b8129d1da0 100644
--- a/usr/src/head/devid.h
+++ b/usr/src/head/devid.h
@@ -20,15 +20,13 @@
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _DEVID_H
#define _DEVID_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#ifndef _KERNEL
#include <sys/types.h>
#endif /* _KERNEL */
@@ -57,13 +55,6 @@ extern char *devid_str_encode(ddi_devid_t devid, char *minor_name);
extern int devid_str_decode(char *devidstr,
ddi_devid_t *retdevid, char **retminor_name);
extern void devid_str_free(char *devidstr);
-extern int devid_scsi_encode(int version, char *driver_name,
- uchar_t *inq, size_t inq_len, uchar_t *inq80,
- size_t inq80_len, uchar_t *inq83, size_t inq83_len,
- ddi_devid_t *ret_devid);
-extern char *devid_to_guid(ddi_devid_t devid);
-extern void devid_free_guid(char *guid);
-extern int devid_str_to_wwn(const char *string, uint64_t *wwn);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libdevid/libdevid.h b/usr/src/lib/libdevid/libdevid.h
index 348d602ecd..f5df7c10e6 100644
--- a/usr/src/lib/libdevid/libdevid.h
+++ b/usr/src/lib/libdevid/libdevid.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,15 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBDEVID_H
#define _LIBDEVID_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <errno.h>
#include <sys/param.h>
#include <sys/sunddi.h>
@@ -45,6 +42,24 @@ extern "C" {
*/
extern int devid_str_compare(char *devid1_str, char *devid2_str);
+extern int devid_scsi_encode(int version, char *driver_name, uchar_t *inq,
+ size_t inq_len, uchar_t *inq80, size_t inq80_len,
+ uchar_t *inq83, size_t inq83_len, ddi_devid_t *devid);
+
+extern char *devid_to_guid(ddi_devid_t devid);
+extern void devid_free_guid(char *guid);
+
+extern int scsi_wwnstr_to_wwn(const char *wwnstr, uint64_t *wwnp);
+extern char *scsi_wwn_to_wwnstr(uint64_t wwn,
+ int unit_address_form, char *wwnstr);
+extern void scsi_wwnstr_hexcase(char *wwnstr, int lower_case);
+extern void scsi_free_wwnstr(char *wwnstr);
+
+#ifdef SCSI_ADDR_PROP_LUN64
+extern scsi_lun64_t scsi_lun_to_lun64(scsi_lun_t lun);
+extern scsi_lun_t scsi_lun64_to_lun(scsi_lun64_t lun64);
+#endif /* SCSI_ADDR_PROP_LUN64 */
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/lib/libdevid/mapfile-vers b/usr/src/lib/libdevid/mapfile-vers
index ff4526da63..48d9e987ad 100644
--- a/usr/src/lib/libdevid/mapfile-vers
+++ b/usr/src/lib/libdevid/mapfile-vers
@@ -62,6 +62,12 @@ SUNWprivate_1.1 {
devid_scsi_encode;
devid_str_compare;
devid_to_guid;
+ scsi_free_wwnstr;
+ scsi_lun64_to_lun;
+ scsi_lun_to_lun64;
+ scsi_wwn_to_wwnstr;
+ scsi_wwnstr_hexcase;
+ scsi_wwnstr_to_wwn;
local:
*;
};
diff --git a/usr/src/uts/common/io/scsi/impl/scsi_hba.c b/usr/src/uts/common/io/scsi/impl/scsi_hba.c
index a25dfb4266..8ddf03a11b 100644
--- a/usr/src/uts/common/io/scsi/impl/scsi_hba.c
+++ b/usr/src/uts/common/io/scsi/impl/scsi_hba.c
@@ -1302,7 +1302,7 @@ smp_busctl_initchild(dev_info_t *child)
goto failure;
}
- if (ddi_devid_str_to_wwn(smp_wwn, &wwn)) {
+ if (scsi_wwnstr_to_wwn(smp_wwn, &wwn)) {
goto failure;
}
@@ -2750,102 +2750,6 @@ scsi_hba_bus_power(dev_info_t *self, void *impl_arg, pm_bus_power_op_t op,
}
/*
- * Convert between normalized (SCSI-3) LUN format, as described by
- * scsi_lun_t, and a normalized lun64_t representation. The normalized
- * representation maps in a compatible way to SCSI-2 LUNs.
- *
- * SCSI-3 LUNs are 64 bits. SCSI-2 LUNs are 3 bits (up to 5 bits in
- * some non-compliant implementations). SCSI-3 will pass a (64-bit)
- * scsi_lun_t, but we need a representation from which we can for example,
- * make device names. For compatibility we represent 64-bit LUN numbers
- * in such a way that they appear like they would have under SCSI-2.
- * This means that the single level LUN number is in the lowest byte with
- * the second, third, and fourth level LUNs represented in successively
- * higher bytes. In particular, if (and only if) the first byte of a 64
- * bit LUN is zero, denoting "Peripheral Device Addressing Method" and
- * "Bus Identifier" zero, then the target implements LUNs compatible in
- * spirit with SCSI-2 LUNs (although under SCSI-3 there may be up to
- * 256 of them). Under SCSI-3 rules, a target is *required* to use
- * this format if it contains 256 or fewer Logical Units, none of which
- * are dependent logical units.
- *
- * These routines have knowledge of the structure and size of a scsi_lun_t.
- *
- * XXX Should these function be rewritten to take the scsi_lun_t *?
- */
-scsi_lun64_t
-scsi_lun_to_lun64(scsi_lun_t lun)
-{
- scsi_lun64_t lun64;
-
- /* check address method and bus identifier */
- if (lun.sl_lun1_msb == 0) {
- /* single-level LUN */
- lun64 = lun.sl_lun1_lsb; /* extract the 8-bit LUN */
-
- /* Ensure rest of LUN is zero, which it is supposed to be */
- if ((lun.sl_lun2_msb == 0) && (lun.sl_lun2_lsb == 0) &&
- (lun.sl_lun3_msb == 0) && (lun.sl_lun3_lsb == 0) &&
- (lun.sl_lun4_msb == 0) && (lun.sl_lun4_lsb == 0)) {
- return (lun64);
- }
-
- /* Oops, we got a bad scsi_lun_t. Leave it in 64-bit form */
- SCSI_HBA_LOG((_LOG(WARN), NULL, NULL,
- "lun_to_lun64 bad lun %" PRIx64, *(scsi_lun64_t *)&lun));
- }
-
- /*
- * We have a big LUN that is not backward compatible.
- * Construct a 64 bit number using the right byte order.
- */
- lun64 =
- ((scsi_lun64_t)lun.sl_lun1_msb << 56) |
- ((scsi_lun64_t)lun.sl_lun1_lsb << 48) |
- ((scsi_lun64_t)lun.sl_lun2_msb << 40) |
- ((scsi_lun64_t)lun.sl_lun2_lsb << 32) |
- ((scsi_lun64_t)lun.sl_lun3_msb << 24) |
- ((scsi_lun64_t)lun.sl_lun3_lsb << 16) |
- ((scsi_lun64_t)lun.sl_lun4_msb << 8) |
- (scsi_lun64_t)lun.sl_lun4_lsb;
- return (lun64);
-}
-
-scsi_lun_t
-scsi_lun64_to_lun(scsi_lun64_t lun64)
-{
- scsi_lun_t lun;
-
- if (lun64 < 256) {
- /* This LUN is in compatibility format */
- lun.sl_lun1_msb = 0;
- lun.sl_lun1_lsb = (uchar_t)lun64;
- lun.sl_lun2_msb = 0;
- lun.sl_lun2_lsb = 0;
- lun.sl_lun3_msb = 0;
- lun.sl_lun3_lsb = 0;
- lun.sl_lun4_msb = 0;
- lun.sl_lun4_lsb = 0;
- } else {
- /* This in full 64 bit LUN format */
- lun.sl_lun1_msb = (uchar_t)(lun64 >> 56);
- lun.sl_lun1_lsb = (uchar_t)(lun64 >> 48);
- lun.sl_lun2_msb = (uchar_t)(lun64 >> 40);
- lun.sl_lun2_lsb = (uchar_t)(lun64 >> 32);
- lun.sl_lun3_msb = (uchar_t)(lun64 >> 24);
- lun.sl_lun3_lsb = (uchar_t)(lun64 >> 16);
- lun.sl_lun4_msb = (uchar_t)(lun64 >> 8);
- lun.sl_lun4_lsb = (uchar_t)(lun64);
-
- /* Oops, bad LUN -- this is required to be nonzero */
- if (lun.sl_lun1_msb == 0)
- SCSI_HBA_LOG((_LOG(WARN), NULL, NULL,
- "lun64_to_lun bad lun %" PRIlun64, lun64));
- }
- return (lun);
-}
-
-/*
* Return the lun from an address string. Either the lun is after the
* first ',' or the entire addr is the lun. Return SCSI_LUN64_ILLEGAL
* if the format is incorrect.
diff --git a/usr/src/uts/common/sys/scsi/scsi_address.h b/usr/src/uts/common/sys/scsi/scsi_address.h
index ce6078b4fa..ec70e72b78 100644
--- a/usr/src/uts/common/sys/scsi/scsi_address.h
+++ b/usr/src/uts/common/sys/scsi/scsi_address.h
@@ -147,6 +147,27 @@ typedef struct scsi_lun {
uchar_t sl_lun4_lsb; /* fourth level */
} scsi_lun_t;
+/* SCSI standard defined lun addressing methods (in sl_lunX_msb) */
+#define SCSI_LUN_AM_MASK 0xC0 /* Address Method Mask */
+#define SCSI_LUN_AM_PDEV 0x00 /* Peripheral device AM */
+#define SCSI_LUN_AM_FLAT 0x40 /* Flat space AM */
+#define SCSI_LUN_AM_LUN 0x80 /* Logical unit AM */
+#define SCSI_LUN_AM_EFLAT 0xC0 /* Extended flat space AM */
+#define SCSI_LUN_AM_ELUN 0xC0 /* Extended logical unit AM */
+
+#ifdef _KERNEL
+/* SCSI LUN conversion between SCSI_ADDR_PROP_LUN64 and SCSI standard forms */
+scsi_lun64_t scsi_lun_to_lun64(scsi_lun_t lun);
+scsi_lun_t scsi_lun64_to_lun(scsi_lun64_t lun64);
+
+/* SCSI WWN conversion (property values should be in unit_address form) */
+int scsi_wwnstr_to_wwn(const char *wwnstr, uint64_t *wwnp);
+char *scsi_wwn_to_wwnstr(uint64_t wwn,
+ int unit_address_form, char *wwnstr);
+void scsi_wwnstr_hexcase(char *wwnstr, int lower_case);
+void scsi_free_wwnstr(char *wwnstr);
+#endif /* _KERNEL */
+
#ifdef __cplusplus
}
#endif
diff --git a/usr/src/uts/common/sys/sunddi.h b/usr/src/uts/common/sys/sunddi.h
index c82df79adc..ad7f568090 100644
--- a/usr/src/uts/common/sys/sunddi.h
+++ b/usr/src/uts/common/sys/sunddi.h
@@ -2012,9 +2012,6 @@ void
ddi_devid_free_guid(char *guid);
int
-ddi_devid_str_to_wwn(const char *string, uint64_t *wwn);
-
-int
ddi_lyr_get_devid(dev_t dev, ddi_devid_t *ret_devid);
int