changeset 12996:be896e318721

6897810 panic - Page fault in module "scsi_vhci" due to a NULL pointer dereference
author Raghuram Prahlada <Raghuram.Prahlada@Sun.COM>
date Mon, 02 Aug 2010 16:27:00 +0530
parents 03e7109ccca0
children 82a41a56372e
files usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci.c
diffstat 1 files changed, 9 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci.c	Mon Aug 02 11:12:35 2010 +0200
+++ b/usr/src/uts/common/io/scsi/adapters/scsi_vhci/scsi_vhci.c	Mon Aug 02 16:27:00 2010 +0530
@@ -206,7 +206,7 @@
 static struct vhci_pkt *vhci_sync_retry_pkt(struct vhci_pkt *);
 static struct scsi_vhci_lun *vhci_lun_lookup(dev_info_t *);
 static struct scsi_vhci_lun *vhci_lun_lookup_alloc(dev_info_t *, char *, int *);
-static void vhci_lun_free(dev_info_t *);
+static void vhci_lun_free(struct scsi_vhci_lun *dvlp, struct scsi_device *sd);
 static int vhci_recovery_reset(scsi_vhci_lun_t *, struct scsi_address *,
     uint8_t, uint8_t);
 void vhci_update_pathstates(void *);
@@ -1059,6 +1059,12 @@
 vhci_scsi_tgt_free(dev_info_t *hba_dip, dev_info_t *tgt_dip,
 	scsi_hba_tran_t *hba_tran, struct scsi_device *sd)
 {
+	struct scsi_vhci_lun *dvlp;
+	ASSERT(mdi_client_get_path_count(tgt_dip) <= 0);
+	dvlp = (struct scsi_vhci_lun *)scsi_device_hba_private_get(sd);
+	ASSERT(dvlp != NULL);
+
+	vhci_lun_free(dvlp, sd);
 }
 
 /*
@@ -4197,7 +4203,7 @@
 		kmem_free(hba, sizeof (scsi_hba_tran_t));
 
 	if (vlun_alloced)
-		vhci_lun_free(tgt_dip);
+		vhci_lun_free(vlun, NULL);
 
 	return (rval);
 }
@@ -4268,14 +4274,6 @@
 	cv_destroy(&svp->svp_cv);
 	kmem_free((caddr_t)svp, sizeof (*svp));
 
-	/*
-	 * If this is the last path to the client,
-	 * then free up the vlun as well.
-	 */
-	if (mdi_client_get_path_count(cdip) == 1) {
-		vhci_lun_free(cdip);
-	}
-
 	VHCI_DEBUG(4, (CE_NOTE, NULL, "!vhci_pathinfo_uninit: path=0x%p\n",
 	    (void *)pip));
 	return (MDI_SUCCESS);
@@ -7316,23 +7314,9 @@
 }
 
 static void
-vhci_lun_free(dev_info_t *tgt_dip)
+vhci_lun_free(struct scsi_vhci_lun *dvlp, struct scsi_device *sd)
 {
-	struct scsi_vhci_lun *dvlp;
 	char *guid;
-	struct scsi_device *sd;
-
-	/*
-	 * The scsi_device was set to driver private during child node
-	 * initialization in the scsi_hba_bus_ctl().
-	 */
-	sd = (struct scsi_device *)ddi_get_driver_private(tgt_dip);
-
-	dvlp = (struct scsi_vhci_lun *)
-	    mdi_client_get_vhci_private(tgt_dip);
-	ASSERT(dvlp != NULL);
-
-	mdi_client_set_vhci_private(tgt_dip, NULL);
 
 	guid = dvlp->svl_lun_wwn;
 	ASSERT(guid != NULL);