xref: /onnv-gate/usr/src/uts/common/io/scsi/adapters/pmcs/pmcs_smhba.c (revision 12443:ce751fefbb65)
110696SDavid.Hollister@Sun.COM /*
210696SDavid.Hollister@Sun.COM  * CDDL HEADER START
310696SDavid.Hollister@Sun.COM  *
410696SDavid.Hollister@Sun.COM  * The contents of this file are subject to the terms of the
510696SDavid.Hollister@Sun.COM  * Common Development and Distribution License (the "License").
610696SDavid.Hollister@Sun.COM  * You may not use this file except in compliance with the License.
710696SDavid.Hollister@Sun.COM  *
810696SDavid.Hollister@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910696SDavid.Hollister@Sun.COM  * or http://www.opensolaris.org/os/licensing.
1010696SDavid.Hollister@Sun.COM  * See the License for the specific language governing permissions
1110696SDavid.Hollister@Sun.COM  * and limitations under the License.
1210696SDavid.Hollister@Sun.COM  *
1310696SDavid.Hollister@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
1410696SDavid.Hollister@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510696SDavid.Hollister@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
1610696SDavid.Hollister@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
1710696SDavid.Hollister@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
1810696SDavid.Hollister@Sun.COM  *
1910696SDavid.Hollister@Sun.COM  * CDDL HEADER END
2012060SDavid.Hollister@Sun.COM  */
2112060SDavid.Hollister@Sun.COM /*
2212060SDavid.Hollister@Sun.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
2310696SDavid.Hollister@Sun.COM  */
2410696SDavid.Hollister@Sun.COM /*
2510696SDavid.Hollister@Sun.COM  * This file contains SM-HBA support for PMC-S driver
2610696SDavid.Hollister@Sun.COM  */
2710696SDavid.Hollister@Sun.COM 
2810696SDavid.Hollister@Sun.COM #include <sys/scsi/adapters/pmcs/pmcs.h>
2910696SDavid.Hollister@Sun.COM 
3010696SDavid.Hollister@Sun.COM 
3110696SDavid.Hollister@Sun.COM void
pmcs_smhba_add_hba_prop(pmcs_hw_t * pwp,data_type_t dt,char * prop_name,void * prop_val)3210696SDavid.Hollister@Sun.COM pmcs_smhba_add_hba_prop(pmcs_hw_t *pwp, data_type_t dt,
3310696SDavid.Hollister@Sun.COM     char *prop_name, void *prop_val)
3410696SDavid.Hollister@Sun.COM {
3510696SDavid.Hollister@Sun.COM 	ASSERT(pwp != NULL);
3610696SDavid.Hollister@Sun.COM 
3710696SDavid.Hollister@Sun.COM 	switch (dt) {
3810696SDavid.Hollister@Sun.COM 	case DATA_TYPE_INT32:
3910696SDavid.Hollister@Sun.COM 		if (ddi_prop_update_int(DDI_DEV_T_NONE, pwp->dip,
4010696SDavid.Hollister@Sun.COM 		    prop_name, *(int *)prop_val)) {
4111048SDavid.Hollister@Sun.COM 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
4210696SDavid.Hollister@Sun.COM 			    "%s: %s prop update failed", __func__, prop_name);
4310696SDavid.Hollister@Sun.COM 		}
4410696SDavid.Hollister@Sun.COM 		break;
4510696SDavid.Hollister@Sun.COM 	case DATA_TYPE_STRING:
4610696SDavid.Hollister@Sun.COM 		if (ddi_prop_update_string(DDI_DEV_T_NONE, pwp->dip,
4710696SDavid.Hollister@Sun.COM 		    prop_name, (char *)prop_val)) {
4811048SDavid.Hollister@Sun.COM 			pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
4910696SDavid.Hollister@Sun.COM 			    "%s: %s prop update failed", __func__, prop_name);
5010696SDavid.Hollister@Sun.COM 		}
5110696SDavid.Hollister@Sun.COM 		break;
5210696SDavid.Hollister@Sun.COM 	default:
5311048SDavid.Hollister@Sun.COM 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL, "%s: "
5411048SDavid.Hollister@Sun.COM 		    "Unhandled datatype(%d) for (%s). Skipping prop update.",
5511048SDavid.Hollister@Sun.COM 		    __func__, dt, prop_name);
5610696SDavid.Hollister@Sun.COM 	}
5710696SDavid.Hollister@Sun.COM }
5810696SDavid.Hollister@Sun.COM 
5910696SDavid.Hollister@Sun.COM 
6011090SDavid.Hollister@Sun.COM /*
6111090SDavid.Hollister@Sun.COM  * Called with iport lock held.
6211090SDavid.Hollister@Sun.COM  */
6310696SDavid.Hollister@Sun.COM void
pmcs_smhba_add_iport_prop(pmcs_iport_t * iport,data_type_t dt,char * prop_name,void * prop_val)6410696SDavid.Hollister@Sun.COM pmcs_smhba_add_iport_prop(pmcs_iport_t *iport, data_type_t dt,
6510696SDavid.Hollister@Sun.COM     char *prop_name, void *prop_val)
6610696SDavid.Hollister@Sun.COM {
6710696SDavid.Hollister@Sun.COM 	ASSERT(iport != NULL);
6811090SDavid.Hollister@Sun.COM 	ASSERT(mutex_owned(&iport->lock));
6910696SDavid.Hollister@Sun.COM 
7010696SDavid.Hollister@Sun.COM 	switch (dt) {
7110696SDavid.Hollister@Sun.COM 	case DATA_TYPE_INT32:
7210696SDavid.Hollister@Sun.COM 		if (ddi_prop_update_int(DDI_DEV_T_NONE, iport->dip,
7310696SDavid.Hollister@Sun.COM 		    prop_name, *(int *)prop_val)) {
7411048SDavid.Hollister@Sun.COM 			pmcs_prt(iport->pwp, PMCS_PRT_DEBUG, NULL, NULL,
7510696SDavid.Hollister@Sun.COM 			    "%s: %s prop update failed", __func__, prop_name);
7610696SDavid.Hollister@Sun.COM 		}
7710696SDavid.Hollister@Sun.COM 		break;
7810696SDavid.Hollister@Sun.COM 	case DATA_TYPE_STRING:
7910696SDavid.Hollister@Sun.COM 		if (ddi_prop_update_string(DDI_DEV_T_NONE, iport->dip,
8010696SDavid.Hollister@Sun.COM 		    prop_name, (char *)prop_val)) {
8111048SDavid.Hollister@Sun.COM 			pmcs_prt(iport->pwp, PMCS_PRT_DEBUG, NULL, NULL,
8210696SDavid.Hollister@Sun.COM 			    "%s: %s prop update failed", __func__, prop_name);
8310696SDavid.Hollister@Sun.COM 		}
8410696SDavid.Hollister@Sun.COM 		break;
8510696SDavid.Hollister@Sun.COM 	default:
8611048SDavid.Hollister@Sun.COM 		pmcs_prt(iport->pwp, PMCS_PRT_DEBUG, NULL, NULL, "%s: "
8711048SDavid.Hollister@Sun.COM 		    "Unhandled datatype(%d) for(%s). Skipping prop update.",
8810696SDavid.Hollister@Sun.COM 		    __func__, dt, prop_name);
8910696SDavid.Hollister@Sun.COM 	}
9011090SDavid.Hollister@Sun.COM 
9111090SDavid.Hollister@Sun.COM 	pmcs_smhba_set_phy_props(iport);
9210696SDavid.Hollister@Sun.COM }
9310696SDavid.Hollister@Sun.COM 
9410696SDavid.Hollister@Sun.COM 
9510696SDavid.Hollister@Sun.COM void
pmcs_smhba_add_tgt_prop(pmcs_xscsi_t * tgt,data_type_t dt,char * prop_name,void * prop_val)9610696SDavid.Hollister@Sun.COM pmcs_smhba_add_tgt_prop(pmcs_xscsi_t *tgt, data_type_t dt,
9710696SDavid.Hollister@Sun.COM     char *prop_name, void *prop_val)
9810696SDavid.Hollister@Sun.COM {
9910696SDavid.Hollister@Sun.COM 	ASSERT(tgt != NULL);
10010696SDavid.Hollister@Sun.COM 
10110696SDavid.Hollister@Sun.COM 	switch (dt) {
10210696SDavid.Hollister@Sun.COM 	case DATA_TYPE_INT32:
10310696SDavid.Hollister@Sun.COM 		if (ddi_prop_update_int(DDI_DEV_T_NONE, tgt->dip,
10410696SDavid.Hollister@Sun.COM 		    prop_name, *(int *)prop_val)) {
10511048SDavid.Hollister@Sun.COM 			pmcs_prt(tgt->pwp, PMCS_PRT_DEBUG, NULL, NULL,
10610696SDavid.Hollister@Sun.COM 			    "%s: %s prop update failed", __func__, prop_name);
10710696SDavid.Hollister@Sun.COM 		}
10810696SDavid.Hollister@Sun.COM 		break;
10910696SDavid.Hollister@Sun.COM 	case DATA_TYPE_STRING:
11010696SDavid.Hollister@Sun.COM 		if (ddi_prop_update_string(DDI_DEV_T_NONE, tgt->dip,
11110696SDavid.Hollister@Sun.COM 		    prop_name, (char *)prop_val)) {
11211048SDavid.Hollister@Sun.COM 			pmcs_prt(tgt->pwp, PMCS_PRT_DEBUG, NULL, NULL,
11310696SDavid.Hollister@Sun.COM 			    "%s: %s prop update failed", __func__, prop_name);
11410696SDavid.Hollister@Sun.COM 		}
11510696SDavid.Hollister@Sun.COM 		break;
11610696SDavid.Hollister@Sun.COM 	default:
11711048SDavid.Hollister@Sun.COM 		pmcs_prt(tgt->pwp, PMCS_PRT_DEBUG, NULL, NULL, "%s: "
11811048SDavid.Hollister@Sun.COM 		    "Unhandled datatype(%d) for (%s). Skipping prop update.",
11911048SDavid.Hollister@Sun.COM 		    __func__, dt, prop_name);
12010696SDavid.Hollister@Sun.COM 	}
12110696SDavid.Hollister@Sun.COM }
12210696SDavid.Hollister@Sun.COM 
12310696SDavid.Hollister@Sun.COM /* ARGSUSED */
12410696SDavid.Hollister@Sun.COM void
pmcs_smhba_set_scsi_device_props(pmcs_hw_t * pwp,pmcs_phy_t * pptr,struct scsi_device * sd)12510696SDavid.Hollister@Sun.COM pmcs_smhba_set_scsi_device_props(pmcs_hw_t *pwp, pmcs_phy_t *pptr,
12610696SDavid.Hollister@Sun.COM     struct scsi_device *sd)
12710696SDavid.Hollister@Sun.COM {
128*12443Sdavid.hollister@oracle.com 	char		*paddr, *addr;
12910696SDavid.Hollister@Sun.COM 	int		ua_form = 1;
130*12443Sdavid.hollister@oracle.com 	uint64_t	wwn, pwwn;
13110696SDavid.Hollister@Sun.COM 	pmcs_phy_t	*pphy;
13210696SDavid.Hollister@Sun.COM 
13310696SDavid.Hollister@Sun.COM 	pphy = pptr->parent;
13410696SDavid.Hollister@Sun.COM 
13510696SDavid.Hollister@Sun.COM 	if (pphy != NULL) {
136*12443Sdavid.hollister@oracle.com 		paddr = kmem_zalloc(PMCS_MAX_UA_SIZE, KM_SLEEP);
137*12443Sdavid.hollister@oracle.com 		pwwn = pmcs_barray2wwn(pphy->sas_address);
138*12443Sdavid.hollister@oracle.com 		(void) scsi_wwn_to_wwnstr(pwwn, ua_form, paddr);
139*12443Sdavid.hollister@oracle.com 
14010696SDavid.Hollister@Sun.COM 		addr = kmem_zalloc(PMCS_MAX_UA_SIZE, KM_SLEEP);
141*12443Sdavid.hollister@oracle.com 		wwn = pmcs_barray2wwn(pptr->sas_address);
14210696SDavid.Hollister@Sun.COM 		(void) scsi_wwn_to_wwnstr(wwn, ua_form, addr);
14310696SDavid.Hollister@Sun.COM 
144*12443Sdavid.hollister@oracle.com 		if ((pptr->dtype == SATA) || pptr->virtual) {
14510696SDavid.Hollister@Sun.COM 			(void) scsi_device_prop_update_string(sd,
14610696SDavid.Hollister@Sun.COM 			    SCSI_DEVICE_PROP_PATH,
14710696SDavid.Hollister@Sun.COM 			    SCSI_ADDR_PROP_BRIDGE_PORT, addr);
14810696SDavid.Hollister@Sun.COM 		}
14910696SDavid.Hollister@Sun.COM 		if (pphy->dtype == EXPANDER) {
15010696SDavid.Hollister@Sun.COM 			(void) scsi_device_prop_update_string(sd,
15110696SDavid.Hollister@Sun.COM 			    SCSI_DEVICE_PROP_PATH,
152*12443Sdavid.hollister@oracle.com 			    SCSI_ADDR_PROP_ATTACHED_PORT, paddr);
15310696SDavid.Hollister@Sun.COM 		}
15410696SDavid.Hollister@Sun.COM 		kmem_free(addr, PMCS_MAX_UA_SIZE);
155*12443Sdavid.hollister@oracle.com 		kmem_free(paddr, PMCS_MAX_UA_SIZE);
15610696SDavid.Hollister@Sun.COM 	}
15712060SDavid.Hollister@Sun.COM 
15812060SDavid.Hollister@Sun.COM 	if (pptr->dtype != EXPANDER) {
15912060SDavid.Hollister@Sun.COM 		(void) scsi_device_prop_update_int(sd,
16012060SDavid.Hollister@Sun.COM 		    SCSI_DEVICE_PROP_PATH, SCSI_ADDR_PROP_TARGET_PORT_DEPTH,
16112060SDavid.Hollister@Sun.COM 		    pptr->level);
16212060SDavid.Hollister@Sun.COM 	}
16310696SDavid.Hollister@Sun.COM }
16410696SDavid.Hollister@Sun.COM 
16510696SDavid.Hollister@Sun.COM void
pmcs_smhba_set_phy_props(pmcs_iport_t * iport)16610696SDavid.Hollister@Sun.COM pmcs_smhba_set_phy_props(pmcs_iport_t *iport)
16710696SDavid.Hollister@Sun.COM {
16810696SDavid.Hollister@Sun.COM 	int		i;
16910696SDavid.Hollister@Sun.COM 	size_t		packed_size;
17010696SDavid.Hollister@Sun.COM 	char		*packed_data;
17110696SDavid.Hollister@Sun.COM 	pmcs_hw_t	*pwp = iport->pwp;
17210696SDavid.Hollister@Sun.COM 	pmcs_phy_t	*phy_ptr;
17310696SDavid.Hollister@Sun.COM 	nvlist_t	**phy_props;
17410696SDavid.Hollister@Sun.COM 	nvlist_t	*nvl;
17510696SDavid.Hollister@Sun.COM 
17611090SDavid.Hollister@Sun.COM 	ASSERT(mutex_owned(&iport->lock));
17710696SDavid.Hollister@Sun.COM 	if (iport->nphy == 0) {
17810696SDavid.Hollister@Sun.COM 		return;
17910696SDavid.Hollister@Sun.COM 	}
18010696SDavid.Hollister@Sun.COM 
18110696SDavid.Hollister@Sun.COM 	if (nvlist_alloc(&nvl, NV_UNIQUE_NAME, 0) != 0) {
18211048SDavid.Hollister@Sun.COM 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
18311048SDavid.Hollister@Sun.COM 		    "%s: nvlist_alloc() failed", __func__);
18410696SDavid.Hollister@Sun.COM 	}
18510696SDavid.Hollister@Sun.COM 
18610696SDavid.Hollister@Sun.COM 	phy_props = kmem_zalloc(sizeof (nvlist_t *) * iport->nphy, KM_SLEEP);
18710696SDavid.Hollister@Sun.COM 
18810696SDavid.Hollister@Sun.COM 	for (phy_ptr = list_head(&iport->phys), i = 0;
18910696SDavid.Hollister@Sun.COM 	    phy_ptr != NULL;
19010696SDavid.Hollister@Sun.COM 	    phy_ptr = list_next(&iport->phys, phy_ptr), i++) {
19110696SDavid.Hollister@Sun.COM 		pmcs_lock_phy(phy_ptr);
19210696SDavid.Hollister@Sun.COM 
19310696SDavid.Hollister@Sun.COM 		(void) nvlist_alloc(&phy_props[i], NV_UNIQUE_NAME, 0);
19410696SDavid.Hollister@Sun.COM 
19510696SDavid.Hollister@Sun.COM 		(void) nvlist_add_uint8(phy_props[i], SAS_PHY_ID,
19610696SDavid.Hollister@Sun.COM 		    phy_ptr->phynum);
19710696SDavid.Hollister@Sun.COM 		(void) nvlist_add_int8(phy_props[i], SAS_NEG_LINK_RATE,
19810696SDavid.Hollister@Sun.COM 		    phy_ptr->link_rate);
19910696SDavid.Hollister@Sun.COM 		(void) nvlist_add_int8(phy_props[i], SAS_PROG_MIN_LINK_RATE,
20010696SDavid.Hollister@Sun.COM 		    phy_ptr->state.prog_min_rate);
20110696SDavid.Hollister@Sun.COM 		(void) nvlist_add_int8(phy_props[i], SAS_HW_MIN_LINK_RATE,
20210696SDavid.Hollister@Sun.COM 		    phy_ptr->state.hw_min_rate);
20310696SDavid.Hollister@Sun.COM 		(void) nvlist_add_int8(phy_props[i], SAS_PROG_MAX_LINK_RATE,
20410696SDavid.Hollister@Sun.COM 		    phy_ptr->state.prog_max_rate);
20510696SDavid.Hollister@Sun.COM 		(void) nvlist_add_int8(phy_props[i], SAS_HW_MAX_LINK_RATE,
20610696SDavid.Hollister@Sun.COM 		    phy_ptr->state.hw_max_rate);
20710696SDavid.Hollister@Sun.COM 
20810696SDavid.Hollister@Sun.COM 		pmcs_unlock_phy(phy_ptr);
20910696SDavid.Hollister@Sun.COM 	}
21010696SDavid.Hollister@Sun.COM 
21110696SDavid.Hollister@Sun.COM 	(void) nvlist_add_nvlist_array(nvl, SAS_PHY_INFO_NVL, phy_props,
21210696SDavid.Hollister@Sun.COM 	    iport->nphy);
21310696SDavid.Hollister@Sun.COM 
21410696SDavid.Hollister@Sun.COM 	(void) nvlist_size(nvl, &packed_size, NV_ENCODE_NATIVE);
21510696SDavid.Hollister@Sun.COM 	packed_data = kmem_zalloc(packed_size, KM_SLEEP);
21610696SDavid.Hollister@Sun.COM 	(void) nvlist_pack(nvl, &packed_data, &packed_size,
21710696SDavid.Hollister@Sun.COM 	    NV_ENCODE_NATIVE, 0);
21810696SDavid.Hollister@Sun.COM 
21910696SDavid.Hollister@Sun.COM 	(void) ddi_prop_update_byte_array(DDI_DEV_T_NONE, iport->dip,
22010696SDavid.Hollister@Sun.COM 	    SAS_PHY_INFO, (uchar_t *)packed_data, packed_size);
22110696SDavid.Hollister@Sun.COM 
22210696SDavid.Hollister@Sun.COM 	for (i = 0; i < iport->nphy && phy_props[i] != NULL; i++) {
22310696SDavid.Hollister@Sun.COM 		nvlist_free(phy_props[i]);
22410696SDavid.Hollister@Sun.COM 	}
22510696SDavid.Hollister@Sun.COM 	nvlist_free(nvl);
22610696SDavid.Hollister@Sun.COM 	kmem_free(phy_props, sizeof (nvlist_t *) * iport->nphy);
22710696SDavid.Hollister@Sun.COM 	kmem_free(packed_data, packed_size);
22810696SDavid.Hollister@Sun.COM }
22910696SDavid.Hollister@Sun.COM 
23010696SDavid.Hollister@Sun.COM /*
23110696SDavid.Hollister@Sun.COM  * Called with PHY lock held on phyp
23210696SDavid.Hollister@Sun.COM  */
23310696SDavid.Hollister@Sun.COM void
pmcs_smhba_log_sysevent(pmcs_hw_t * pwp,char * subclass,char * etype,pmcs_phy_t * phyp)23410696SDavid.Hollister@Sun.COM pmcs_smhba_log_sysevent(pmcs_hw_t *pwp, char *subclass, char *etype,
23510696SDavid.Hollister@Sun.COM     pmcs_phy_t *phyp)
23610696SDavid.Hollister@Sun.COM {
23710696SDavid.Hollister@Sun.COM 	nvlist_t	*attr_list;
23810696SDavid.Hollister@Sun.COM 	char		*pname;
23910696SDavid.Hollister@Sun.COM 	char		sas_addr[PMCS_MAX_UA_SIZE];
24010696SDavid.Hollister@Sun.COM 	uint8_t		phynum = 0;
24110696SDavid.Hollister@Sun.COM 	uint8_t		lrate = 0;
24210696SDavid.Hollister@Sun.COM 	uint64_t	wwn;
24310696SDavid.Hollister@Sun.COM 	int		ua_form = 0;
24410696SDavid.Hollister@Sun.COM 
24510696SDavid.Hollister@Sun.COM 	if (pwp->dip == NULL)
24610696SDavid.Hollister@Sun.COM 		return;
24710696SDavid.Hollister@Sun.COM 	if (phyp == NULL)
24810696SDavid.Hollister@Sun.COM 		return;
24910696SDavid.Hollister@Sun.COM 
25010696SDavid.Hollister@Sun.COM 	pname = kmem_zalloc(MAXPATHLEN, KM_NOSLEEP);
25110696SDavid.Hollister@Sun.COM 	if (pname == NULL)
25210696SDavid.Hollister@Sun.COM 		return;
25310696SDavid.Hollister@Sun.COM 
25410696SDavid.Hollister@Sun.COM 	if ((strcmp(subclass, ESC_SAS_PHY_EVENT) == 0) ||
25510696SDavid.Hollister@Sun.COM 	    (strcmp(subclass, ESC_SAS_HBA_PORT_BROADCAST) == 0)) {
25610696SDavid.Hollister@Sun.COM 		ASSERT(phyp != NULL);
25710696SDavid.Hollister@Sun.COM 		(void) strncpy(pname, phyp->path, strlen(phyp->path));
25810696SDavid.Hollister@Sun.COM 		phynum = phyp->phynum;
25910696SDavid.Hollister@Sun.COM 		wwn = pmcs_barray2wwn(phyp->sas_address);
26010696SDavid.Hollister@Sun.COM 		(void) scsi_wwn_to_wwnstr(wwn, ua_form, sas_addr);
26110696SDavid.Hollister@Sun.COM 		if (strcmp(etype, SAS_PHY_ONLINE) == 0) {
26210696SDavid.Hollister@Sun.COM 			lrate = phyp->link_rate;
26310696SDavid.Hollister@Sun.COM 		}
26410696SDavid.Hollister@Sun.COM 	}
26510696SDavid.Hollister@Sun.COM 	if (strcmp(subclass, ESC_SAS_HBA_PORT_BROADCAST) == 0) {
26610696SDavid.Hollister@Sun.COM 		(void) ddi_pathname(pwp->dip, pname);
26710696SDavid.Hollister@Sun.COM 	}
26810696SDavid.Hollister@Sun.COM 
26910696SDavid.Hollister@Sun.COM 	if (nvlist_alloc(&attr_list, NV_UNIQUE_NAME_TYPE, 0) != 0) {
27011048SDavid.Hollister@Sun.COM 		pmcs_prt(pwp, PMCS_PRT_DEBUG, NULL, NULL,
27111048SDavid.Hollister@Sun.COM 		    "%s: Failed to post sysevent", __func__);
27210696SDavid.Hollister@Sun.COM 		kmem_free(pname, MAXPATHLEN);
27310696SDavid.Hollister@Sun.COM 		return;
27410696SDavid.Hollister@Sun.COM 	}
27510696SDavid.Hollister@Sun.COM 
27610696SDavid.Hollister@Sun.COM 	if (nvlist_add_int32(attr_list, SAS_DRV_INST,
27710696SDavid.Hollister@Sun.COM 	    ddi_get_instance(pwp->dip)) != 0)
27810696SDavid.Hollister@Sun.COM 		goto fail;
27910696SDavid.Hollister@Sun.COM 
28010696SDavid.Hollister@Sun.COM 	if (nvlist_add_string(attr_list, SAS_PORT_ADDR, sas_addr) != 0)
28110696SDavid.Hollister@Sun.COM 		goto fail;
28210696SDavid.Hollister@Sun.COM 
28310696SDavid.Hollister@Sun.COM 	if (nvlist_add_string(attr_list, SAS_DEVFS_PATH, pname) != 0)
28410696SDavid.Hollister@Sun.COM 		goto fail;
28510696SDavid.Hollister@Sun.COM 
28610696SDavid.Hollister@Sun.COM 	if (nvlist_add_uint8(attr_list, SAS_PHY_ID, phynum) != 0)
28710696SDavid.Hollister@Sun.COM 		goto fail;
28810696SDavid.Hollister@Sun.COM 
28910696SDavid.Hollister@Sun.COM 	if (strcmp(etype, SAS_PHY_ONLINE) == 0) {
29010696SDavid.Hollister@Sun.COM 		if (nvlist_add_uint8(attr_list, SAS_LINK_RATE, lrate) != 0)
29110696SDavid.Hollister@Sun.COM 			goto fail;
29210696SDavid.Hollister@Sun.COM 	}
29310696SDavid.Hollister@Sun.COM 
29410696SDavid.Hollister@Sun.COM 	if (nvlist_add_string(attr_list, SAS_EVENT_TYPE, etype) != 0)
29510696SDavid.Hollister@Sun.COM 		goto fail;
29610696SDavid.Hollister@Sun.COM 
29710696SDavid.Hollister@Sun.COM 	(void) ddi_log_sysevent(pwp->dip, DDI_VENDOR_SUNW, EC_HBA, subclass,
29810696SDavid.Hollister@Sun.COM 	    attr_list, NULL, DDI_NOSLEEP);
29910696SDavid.Hollister@Sun.COM 
30010696SDavid.Hollister@Sun.COM fail:
30110696SDavid.Hollister@Sun.COM 	kmem_free(pname, MAXPATHLEN);
30210696SDavid.Hollister@Sun.COM 	nvlist_free(attr_list);
30310696SDavid.Hollister@Sun.COM }
304