19e86db79SHyon Kim /*
29e86db79SHyon Kim * CDDL HEADER START
39e86db79SHyon Kim *
49e86db79SHyon Kim * The contents of this file are subject to the terms of the
59e86db79SHyon Kim * Common Development and Distribution License (the "License").
69e86db79SHyon Kim * You may not use this file except in compliance with the License.
79e86db79SHyon Kim *
89e86db79SHyon Kim * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99e86db79SHyon Kim * or http://www.opensolaris.org/os/licensing.
109e86db79SHyon Kim * See the License for the specific language governing permissions
119e86db79SHyon Kim * and limitations under the License.
129e86db79SHyon Kim *
139e86db79SHyon Kim * When distributing Covered Code, include this CDDL HEADER in each
149e86db79SHyon Kim * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159e86db79SHyon Kim * If applicable, add the following below this CDDL HEADER, with the
169e86db79SHyon Kim * fields enclosed by brackets "[]" replaced with your own identifying
179e86db79SHyon Kim * information: Portions Copyright [yyyy] [name of copyright owner]
189e86db79SHyon Kim *
199e86db79SHyon Kim * CDDL HEADER END
209e86db79SHyon Kim */
219e86db79SHyon Kim
229e86db79SHyon Kim /*
239e86db79SHyon Kim * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
249e86db79SHyon Kim * Use is subject to license terms.
259e86db79SHyon Kim */
269e86db79SHyon Kim
279e86db79SHyon Kim
289e86db79SHyon Kim #include <sys/byteorder.h>
299e86db79SHyon Kim #include <sun_sas.h>
309e86db79SHyon Kim
319e86db79SHyon Kim /*
329e86db79SHyon Kim * creates a handle each time Sun_sas_OpenAdapter() is called.
339e86db79SHyon Kim *
349e86db79SHyon Kim * a open_handle_struct was created to keep track of which handles are currently
359e86db79SHyon Kim * open. This prevents a user from using an old handle that corresponds to
369e86db79SHyon Kim * an hba that has already been closed.
379e86db79SHyon Kim */
389e86db79SHyon Kim HBA_HANDLE
CreateHandle(int adapterIndex)399e86db79SHyon Kim CreateHandle(int adapterIndex)
409e86db79SHyon Kim {
419e86db79SHyon Kim const char ROUTINE[] = "CreateHandle";
429e86db79SHyon Kim struct open_handle *new_open_handle;
439e86db79SHyon Kim HBA_UINT32 new_handle_index;
449e86db79SHyon Kim HBA_UINT8 max_handle_wrap = 0;
459e86db79SHyon Kim
469e86db79SHyon Kim if (global_hba_head == NULL) {
479e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
489e86db79SHyon Kim "an error as occurred. global_hba_head is "
499e86db79SHyon Kim "NULL. Library may not be loaded yet.");
509e86db79SHyon Kim return (HANDLE_ERROR);
519e86db79SHyon Kim }
529e86db79SHyon Kim
539e86db79SHyon Kim while (RetrieveIndex(open_handle_index) != -1) {
549e86db79SHyon Kim open_handle_index = open_handle_index + 1;
559e86db79SHyon Kim if (open_handle_index == 0) {
569e86db79SHyon Kim /*
579e86db79SHyon Kim * If open_handle_index wraps back to zero again,
589e86db79SHyon Kim * that means all handles are currently in use.
599e86db79SHyon Kim * Spec only allows for 16 bits of handles
609e86db79SHyon Kim */
619e86db79SHyon Kim if (max_handle_wrap == 1) {
629e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
639e86db79SHyon Kim "Max number of handles reached.");
649e86db79SHyon Kim return (HANDLE_ERROR);
659e86db79SHyon Kim }
669e86db79SHyon Kim open_handle_index = 1;
679e86db79SHyon Kim max_handle_wrap = 1;
689e86db79SHyon Kim }
699e86db79SHyon Kim }
709e86db79SHyon Kim
719e86db79SHyon Kim new_handle_index = open_handle_index;
729e86db79SHyon Kim if ((new_open_handle = (struct open_handle *)calloc(1,
739e86db79SHyon Kim sizeof (struct open_handle))) == NULL) {
749e86db79SHyon Kim OUT_OF_MEMORY(ROUTINE);
759e86db79SHyon Kim return (HANDLE_ERROR);
769e86db79SHyon Kim }
779e86db79SHyon Kim (void) memset(new_open_handle, 0, sizeof (struct open_handle));
789e86db79SHyon Kim new_open_handle->adapterIndex = adapterIndex;
799e86db79SHyon Kim new_open_handle->handle = new_handle_index;
809e86db79SHyon Kim
819e86db79SHyon Kim lock(&open_handles_lock);
829e86db79SHyon Kim
839e86db79SHyon Kim /* add new open handle struct to the open_handles list */
849e86db79SHyon Kim if (global_hba_head->open_handles == NULL) {
859e86db79SHyon Kim global_hba_head->open_handles = new_open_handle;
869e86db79SHyon Kim } else {
879e86db79SHyon Kim new_open_handle->next = global_hba_head->open_handles;
889e86db79SHyon Kim global_hba_head->open_handles = new_open_handle;
899e86db79SHyon Kim }
909e86db79SHyon Kim
919e86db79SHyon Kim unlock(&open_handles_lock);
929e86db79SHyon Kim open_handle_index = open_handle_index + 1;
939e86db79SHyon Kim if (open_handle_index == 0) {
949e86db79SHyon Kim open_handle_index = 1;
959e86db79SHyon Kim }
969e86db79SHyon Kim
979e86db79SHyon Kim return (new_handle_index);
989e86db79SHyon Kim }
999e86db79SHyon Kim
1009e86db79SHyon Kim /*
1019e86db79SHyon Kim * given a handle, returns the adapterIndex number.
1029e86db79SHyon Kim *
1039e86db79SHyon Kim * This functions checkes to see if the given handle corresponds to an open
1049e86db79SHyon Kim * HBA. If it does, the adapterIndex is returned.
1059e86db79SHyon Kim */
1069e86db79SHyon Kim int
RetrieveIndex(HBA_HANDLE handle)1079e86db79SHyon Kim RetrieveIndex(HBA_HANDLE handle)
1089e86db79SHyon Kim {
1099e86db79SHyon Kim
1109e86db79SHyon Kim struct open_handle *open_handle_ptr;
1119e86db79SHyon Kim
1129e86db79SHyon Kim lock(&open_handles_lock);
1139e86db79SHyon Kim
1149e86db79SHyon Kim open_handle_ptr = RetrieveOpenHandle(handle);
1159e86db79SHyon Kim
1169e86db79SHyon Kim unlock(&open_handles_lock);
1179e86db79SHyon Kim if (open_handle_ptr == NULL) {
1189e86db79SHyon Kim return (-1);
1199e86db79SHyon Kim }
1209e86db79SHyon Kim
1219e86db79SHyon Kim return (open_handle_ptr->adapterIndex);
1229e86db79SHyon Kim }
1239e86db79SHyon Kim /*
1249e86db79SHyon Kim * Given a handle, returns the open_handle structure
1259e86db79SHyon Kim * The routine assumes that the open_handles_lock has already
1269e86db79SHyon Kim * been taken.
1279e86db79SHyon Kim */
1289e86db79SHyon Kim struct open_handle *
RetrieveOpenHandle(HBA_HANDLE handle)1299e86db79SHyon Kim RetrieveOpenHandle(HBA_HANDLE handle)
1309e86db79SHyon Kim {
1319e86db79SHyon Kim
1329e86db79SHyon Kim const char ROUTINE[] = "RetrieveOpenHandle";
1339e86db79SHyon Kim struct open_handle *open_handle_ptr = NULL;
1349e86db79SHyon Kim
1359e86db79SHyon Kim if (global_hba_head == NULL) {
136*0778188fSHengqing Hu log(LOG_DEBUG, ROUTINE, "No adapter is found.");
1379e86db79SHyon Kim return (NULL);
1389e86db79SHyon Kim }
1399e86db79SHyon Kim
1409e86db79SHyon Kim for (open_handle_ptr = global_hba_head->open_handles;
1419e86db79SHyon Kim open_handle_ptr != NULL;
1429e86db79SHyon Kim open_handle_ptr = open_handle_ptr->next) {
1439e86db79SHyon Kim if (open_handle_ptr->handle == handle) {
1449e86db79SHyon Kim break;
1459e86db79SHyon Kim }
1469e86db79SHyon Kim }
1479e86db79SHyon Kim
1489e86db79SHyon Kim return (open_handle_ptr);
1499e86db79SHyon Kim }
1509e86db79SHyon Kim
1519e86db79SHyon Kim /*
1529e86db79SHyon Kim * Given an adapterIndex, this functions returns a pointer to the handle
1539e86db79SHyon Kim * structure. This handle structure holds the hba's information
1549e86db79SHyon Kim * Caller must take all_hbas_lock first.
1559e86db79SHyon Kim */
1569e86db79SHyon Kim struct sun_sas_hba *
RetrieveHandle(int index)1579e86db79SHyon Kim RetrieveHandle(int index)
1589e86db79SHyon Kim {
1599e86db79SHyon Kim struct sun_sas_hba *hba_ptr = NULL;
1609e86db79SHyon Kim
1619e86db79SHyon Kim for (hba_ptr = global_hba_head; hba_ptr != NULL;
1629e86db79SHyon Kim hba_ptr = hba_ptr->next) {
1639e86db79SHyon Kim if (hba_ptr->index == index)
1649e86db79SHyon Kim break;
1659e86db79SHyon Kim }
1669e86db79SHyon Kim
1679e86db79SHyon Kim return (hba_ptr);
1689e86db79SHyon Kim }
1699e86db79SHyon Kim
1709e86db79SHyon Kim /*
1719e86db79SHyon Kim * Given an adapterIndex, this functions returns a pointer to the handle
1729e86db79SHyon Kim * structure and extracts it from the global list.
1739e86db79SHyon Kim *
1749e86db79SHyon Kim * all_hbas_lock must be taken already.
1759e86db79SHyon Kim */
1769e86db79SHyon Kim struct sun_sas_hba *
ExtractHandle(int index)1779e86db79SHyon Kim ExtractHandle(int index)
1789e86db79SHyon Kim {
1799e86db79SHyon Kim struct sun_sas_hba *last = NULL;
1809e86db79SHyon Kim struct sun_sas_hba *hba_ptr = NULL;
1819e86db79SHyon Kim
1829e86db79SHyon Kim for (hba_ptr = global_hba_head;
1839e86db79SHyon Kim hba_ptr != NULL;
1849e86db79SHyon Kim last = hba_ptr, hba_ptr = hba_ptr->next) {
1859e86db79SHyon Kim if (hba_ptr->index == index) {
1869e86db79SHyon Kim if (last) {
1879e86db79SHyon Kim last->next = hba_ptr->next;
1889e86db79SHyon Kim } else {
1899e86db79SHyon Kim /* Hmm, must be the head of the list. */
1909e86db79SHyon Kim global_hba_head = hba_ptr->next;
1919e86db79SHyon Kim }
1929e86db79SHyon Kim hba_ptr->next = NULL; /* Zap it to be safe */
1939e86db79SHyon Kim break;
1949e86db79SHyon Kim }
1959e86db79SHyon Kim }
1969e86db79SHyon Kim
1979e86db79SHyon Kim return (hba_ptr);
1989e86db79SHyon Kim }
1999e86db79SHyon Kim
2009e86db79SHyon Kim
2019e86db79SHyon Kim /*
2029e86db79SHyon Kim * Given an handle, this functions returns a pointer to the handle structure
2039e86db79SHyon Kim * for that hba
2049e86db79SHyon Kim *
2059e86db79SHyon Kim * Caller must take all_hbas_lock first.
2069e86db79SHyon Kim */
2079e86db79SHyon Kim struct sun_sas_hba *
Retrieve_Sun_sasHandle(HBA_HANDLE handle)2089e86db79SHyon Kim Retrieve_Sun_sasHandle(HBA_HANDLE handle)
2099e86db79SHyon Kim {
2109e86db79SHyon Kim const char ROUTINE[] = "Retrieve_Sun_sasHandle";
2119e86db79SHyon Kim struct sun_sas_hba *handle_struct = NULL;
2129e86db79SHyon Kim int index;
2139e86db79SHyon Kim
2149e86db79SHyon Kim /* Retrieve fp device path from handle */
2159e86db79SHyon Kim index = RetrieveIndex(handle);
2169e86db79SHyon Kim if (index == -1) {
2179e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
2189e86db79SHyon Kim "handle could not be found.");
2199e86db79SHyon Kim return (handle_struct);
2209e86db79SHyon Kim }
2219e86db79SHyon Kim lock(&open_handles_lock);
2229e86db79SHyon Kim handle_struct = RetrieveHandle(index);
2239e86db79SHyon Kim if (handle_struct == NULL) {
2249e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
2259e86db79SHyon Kim "could not find index in the handle list.");
2269e86db79SHyon Kim unlock(&open_handles_lock);
2279e86db79SHyon Kim return (handle_struct);
2289e86db79SHyon Kim }
2299e86db79SHyon Kim unlock(&open_handles_lock);
2309e86db79SHyon Kim
2319e86db79SHyon Kim return (handle_struct);
2329e86db79SHyon Kim }
2339e86db79SHyon Kim
2349e86db79SHyon Kim /*
2359e86db79SHyon Kim * Take a mutex lock. The routine will try, and if it fails,
2369e86db79SHyon Kim * it will loop for a while and retry. If it fails many times,
2379e86db79SHyon Kim * it will start writing to the log file.
2389e86db79SHyon Kim */
2399e86db79SHyon Kim void
lock(mutex_t * mp)2409e86db79SHyon Kim lock(mutex_t *mp)
2419e86db79SHyon Kim {
2429e86db79SHyon Kim int status;
2439e86db79SHyon Kim int loop = 0;
2449e86db79SHyon Kim const char ROUTINE[] = "lock";
2459e86db79SHyon Kim
2469e86db79SHyon Kim do {
2479e86db79SHyon Kim loop++;
2489e86db79SHyon Kim status = mutex_trylock(mp);
2499e86db79SHyon Kim switch (status) {
2509e86db79SHyon Kim case 0:
2519e86db79SHyon Kim break;
2529e86db79SHyon Kim case EFAULT:
2539e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
2549e86db79SHyon Kim "Lock failed: fault 0x%x", mp);
2559e86db79SHyon Kim break;
2569e86db79SHyon Kim case EINVAL:
2579e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
2589e86db79SHyon Kim "Lock failed: invalid 0x%x", mp);
2599e86db79SHyon Kim break;
2609e86db79SHyon Kim case EBUSY:
2619e86db79SHyon Kim if (loop > DEADLOCK_WARNING) {
2629e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
2639e86db79SHyon Kim "Lock busy, possible deadlock:0x%x",
2649e86db79SHyon Kim mp);
2659e86db79SHyon Kim }
2669e86db79SHyon Kim break;
2679e86db79SHyon Kim case EOWNERDEAD:
2689e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
2699e86db79SHyon Kim "Lock failed: owner dead 0x%x",
2709e86db79SHyon Kim mp);
2719e86db79SHyon Kim break;
2729e86db79SHyon Kim case ELOCKUNMAPPED:
2739e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
2749e86db79SHyon Kim "Lock failed: unmapped 0x%x",
2759e86db79SHyon Kim mp);
2769e86db79SHyon Kim break;
2779e86db79SHyon Kim case ENOTRECOVERABLE:
2789e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
2799e86db79SHyon Kim "Lock failed: not recoverable 0x%x", mp);
2809e86db79SHyon Kim default:
2819e86db79SHyon Kim if (loop > DEADLOCK_WARNING) {
2829e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
2839e86db79SHyon Kim "Lock failed: %s 0x%x",
2849e86db79SHyon Kim strerror(status), mp);
2859e86db79SHyon Kim break;
2869e86db79SHyon Kim }
2879e86db79SHyon Kim }
2889e86db79SHyon Kim
2899e86db79SHyon Kim if (status) {
2909e86db79SHyon Kim (void) sleep(LOCK_SLEEP);
2919e86db79SHyon Kim }
2929e86db79SHyon Kim
2939e86db79SHyon Kim } while (status);
2949e86db79SHyon Kim }
2959e86db79SHyon Kim
2969e86db79SHyon Kim /*
2979e86db79SHyon Kim * Unlock a mutex lock.
2989e86db79SHyon Kim */
2999e86db79SHyon Kim void
unlock(mutex_t * mp)3009e86db79SHyon Kim unlock(mutex_t *mp)
3019e86db79SHyon Kim {
3029e86db79SHyon Kim (void) mutex_unlock(mp);
3039e86db79SHyon Kim }
3049e86db79SHyon Kim
3059e86db79SHyon Kim
3069e86db79SHyon Kim /*
3079e86db79SHyon Kim * Get the Port WWN of the first adapter port. This routine
3089e86db79SHyon Kim * is used by the old V1 interfaces so that they can call
3099e86db79SHyon Kim * the new V2 interfaces and exhibit the same behavior.
3109e86db79SHyon Kim * In the event of error the WWN will be zero.
3119e86db79SHyon Kim *
3129e86db79SHyon Kim * This function will transition to PAA state but it will not
3139e86db79SHyon Kim * verfiy whether data is stale or not
3149e86db79SHyon Kim */
3159e86db79SHyon Kim HBA_WWN
getFirstAdapterPortWWN(HBA_HANDLE handle)3169e86db79SHyon Kim getFirstAdapterPortWWN(HBA_HANDLE handle)
3179e86db79SHyon Kim {
3189e86db79SHyon Kim const char ROUTINE[] = "getFirstAdapterPortWWN";
3199e86db79SHyon Kim HBA_WWN pwwn = {0, 0, 0, 0, 0, 0, 0, 0};
3209e86db79SHyon Kim struct sun_sas_hba *hba_ptr = NULL;
3219e86db79SHyon Kim int index = 0;
3229e86db79SHyon Kim HBA_STATUS status;
3239e86db79SHyon Kim
3249e86db79SHyon Kim lock(&all_hbas_lock);
3259e86db79SHyon Kim index = RetrieveIndex(handle);
3269e86db79SHyon Kim lock(&open_handles_lock);
3279e86db79SHyon Kim hba_ptr = RetrieveHandle(index);
3289e86db79SHyon Kim if (hba_ptr == NULL) {
3299e86db79SHyon Kim log(LOG_DEBUG, ROUTINE, "Invalid handle %08lx", handle);
3309e86db79SHyon Kim unlock(&open_handles_lock);
3319e86db79SHyon Kim unlock(&all_hbas_lock);
3329e86db79SHyon Kim return (pwwn); /* zero WWN */
3339e86db79SHyon Kim }
3349e86db79SHyon Kim
3359e86db79SHyon Kim /* Check for stale data */
3369e86db79SHyon Kim status = verifyAdapter(hba_ptr);
3379e86db79SHyon Kim if (status != HBA_STATUS_OK) {
3389e86db79SHyon Kim log(LOG_DEBUG, ROUTINE, "Verify adapter failed");
3399e86db79SHyon Kim unlock(&open_handles_lock);
3409e86db79SHyon Kim unlock(&all_hbas_lock);
3419e86db79SHyon Kim return (pwwn);
3429e86db79SHyon Kim }
3439e86db79SHyon Kim
3449e86db79SHyon Kim if (hba_ptr->first_port == NULL) {
3459e86db79SHyon Kim /* This is probably an internal failure of the library */
3469e86db79SHyon Kim if (hba_ptr->device_path) {
3479e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
3489e86db79SHyon Kim "Internal failure: Adapter %s contains no "
3499e86db79SHyon Kim "port data", hba_ptr->device_path);
3509e86db79SHyon Kim } else {
3519e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
3529e86db79SHyon Kim "Internal failure: Adapter at index %d contains "
3539e86db79SHyon Kim " no support data", hba_ptr->index);
3549e86db79SHyon Kim }
3559e86db79SHyon Kim unlock(&open_handles_lock);
3569e86db79SHyon Kim unlock(&all_hbas_lock);
3579e86db79SHyon Kim return (pwwn); /* zero WWN */
3589e86db79SHyon Kim }
3599e86db79SHyon Kim /* Set the WWN now and return it */
3609e86db79SHyon Kim pwwn = hba_ptr->first_port->port_attributes.PortSpecificAttribute.\
3619e86db79SHyon Kim SASPort->LocalSASAddress;
3629e86db79SHyon Kim unlock(&open_handles_lock);
3639e86db79SHyon Kim unlock(&all_hbas_lock);
3649e86db79SHyon Kim
3659e86db79SHyon Kim return (pwwn);
3669e86db79SHyon Kim }
3679e86db79SHyon Kim
3689e86db79SHyon Kim u_longlong_t
wwnConversion(uchar_t * wwn)3699e86db79SHyon Kim wwnConversion(uchar_t *wwn)
3709e86db79SHyon Kim {
3719e86db79SHyon Kim u_longlong_t tmp;
3729e86db79SHyon Kim (void) memcpy(&tmp, wwn, sizeof (u_longlong_t));
3739e86db79SHyon Kim tmp = ntohll(tmp);
3749e86db79SHyon Kim return (tmp);
3759e86db79SHyon Kim }
3769e86db79SHyon Kim
3779e86db79SHyon Kim /*
3789e86db79SHyon Kim * Using ioctl to send uscsi command out
3799e86db79SHyon Kim */
3809e86db79SHyon Kim HBA_STATUS
send_uscsi_cmd(const char * devpath,struct uscsi_cmd * ucmd)3819e86db79SHyon Kim send_uscsi_cmd(const char *devpath, struct uscsi_cmd *ucmd)
3829e86db79SHyon Kim {
3839e86db79SHyon Kim const char ROUTINE[] = "send_uscsi_cmd";
3849e86db79SHyon Kim int fd;
3859e86db79SHyon Kim HBA_STATUS ret;
3869e86db79SHyon Kim
3879e86db79SHyon Kim /* set default timeout to 200 */
3889e86db79SHyon Kim ucmd->uscsi_timeout = 200;
3899e86db79SHyon Kim
3909e86db79SHyon Kim /* reset errno. */
3919e86db79SHyon Kim errno = 0;
3929e86db79SHyon Kim if ((fd = open(devpath, O_RDONLY | O_NDELAY)) == -1) {
3939e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
3949e86db79SHyon Kim "open devpath %s failed: %s", devpath, strerror(errno));
3959e86db79SHyon Kim return (HBA_STATUS_ERROR);
3969e86db79SHyon Kim }
3979e86db79SHyon Kim
3989e86db79SHyon Kim if (ioctl(fd, USCSICMD, ucmd) == -1) {
3999e86db79SHyon Kim if (errno == EBUSY) {
4009e86db79SHyon Kim ret = HBA_STATUS_ERROR_BUSY;
4019e86db79SHyon Kim } else if (errno == EAGAIN) {
4029e86db79SHyon Kim ret = HBA_STATUS_ERROR_TRY_AGAIN;
4039e86db79SHyon Kim } else {
4049e86db79SHyon Kim ret = HBA_STATUS_ERROR;
4059e86db79SHyon Kim }
4069e86db79SHyon Kim log(LOG_DEBUG, ROUTINE,
4079e86db79SHyon Kim "ioctl send uscsi to devpath: %s failed: %s",
4089e86db79SHyon Kim devpath, strerror(errno));
4099e86db79SHyon Kim (void) close(fd);
4109e86db79SHyon Kim return (ret);
4119e86db79SHyon Kim }
4129e86db79SHyon Kim
4139e86db79SHyon Kim (void) close(fd);
4149e86db79SHyon Kim
4159e86db79SHyon Kim return (HBA_STATUS_OK);
4169e86db79SHyon Kim }
4179e86db79SHyon Kim
4189e86db79SHyon Kim /*
4199e86db79SHyon Kim * Check whether the given Domain Address is valid.
4209e86db79SHyon Kim */
4219e86db79SHyon Kim HBA_STATUS
validateDomainAddress(struct sun_sas_port * hba_port_ptr,HBA_WWN DomainAddr)4229e86db79SHyon Kim validateDomainAddress(struct sun_sas_port *hba_port_ptr, HBA_WWN DomainAddr)
4239e86db79SHyon Kim {
4249e86db79SHyon Kim if (hba_port_ptr->first_phy != NULL &&
4259e86db79SHyon Kim wwnConversion(hba_port_ptr->first_phy->
4269e86db79SHyon Kim phy.domainPortWWN.wwn) ==
4279e86db79SHyon Kim wwnConversion(DomainAddr.wwn)) {
4289e86db79SHyon Kim return (HBA_STATUS_OK);
4299e86db79SHyon Kim }
4309e86db79SHyon Kim return (HBA_STATUS_ERROR);
4319e86db79SHyon Kim }
432