[SCSI] mptfusion: sanity check for vdevice pointer is added
Kashyap, Desai [Thu, 18 Mar 2010 13:52:45 +0000 (18:52 +0530)]
Added sanity checks before accessing vdevice and added vdevice->deleted
setting for mptfc.

Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@suse.de>

drivers/message/fusion/mptctl.c
drivers/message/fusion/mptfc.c
drivers/message/fusion/mptscsih.c

index e7fab5d..f06b291 100644 (file)
@@ -1329,6 +1329,8 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
        if (ioc->sh) {
                shost_for_each_device(sdev, ioc->sh) {
                        vdevice = sdev->hostdata;
+                       if (vdevice == NULL || vdevice->vtarget == NULL)
+                               continue;
                        if (vdevice->vtarget->tflags &
                            MPT_TARGET_FLAGS_RAID_COMPONENT)
                                continue;
@@ -1450,6 +1452,8 @@ mptctl_gettargetinfo (unsigned long arg)
                        if (!maxWordsLeft)
                                continue;
                        vdevice = sdev->hostdata;
+                       if (vdevice == NULL || vdevice->vtarget == NULL)
+                               continue;
                        if (vdevice->vtarget->tflags &
                            MPT_TARGET_FLAGS_RAID_COMPONENT)
                                continue;
@@ -1978,6 +1982,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
                                struct scsi_target *starget = scsi_target(sdev);
                                VirtTarget *vtarget = starget->hostdata;
 
+                               if (vtarget == NULL)
+                                       continue;
+
                                if ((pScsiReq->TargetID == vtarget->id) &&
                                    (pScsiReq->Bus == vtarget->channel) &&
                                    (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
index 8b3ff2d..b5f03ad 100644 (file)
@@ -482,6 +482,7 @@ mptfc_register_dev(MPT_ADAPTER *ioc, int channel, FCDevicePage0_t *pg0)
                                if (vtarget) {
                                        vtarget->id = pg0->CurrentTargetID;
                                        vtarget->channel = pg0->CurrentBus;
+                                       vtarget->deleted = 0;
                                }
                        }
                        *((struct mptfc_rport_info **)rport->dd_data) = ri;
@@ -1092,6 +1093,8 @@ mptfc_setup_reset(struct work_struct *work)
                container_of(work, MPT_ADAPTER, fc_setup_reset_work);
        u64                     pn;
        struct mptfc_rport_info *ri;
+       struct scsi_target      *starget;
+       VirtTarget              *vtarget;
 
        /* reset about to happen, delete (block) all rports */
        list_for_each_entry(ri, &ioc->fc_rports, list) {
@@ -1099,6 +1102,12 @@ mptfc_setup_reset(struct work_struct *work)
                        ri->flags &= ~MPT_RPORT_INFO_FLAGS_REGISTERED;
                        fc_remote_port_delete(ri->rport);       /* won't sleep */
                        ri->rport = NULL;
+                       starget = ri->starget;
+                       if (starget) {
+                               vtarget = starget->hostdata;
+                               if (vtarget)
+                                       vtarget->deleted = 1;
+                       }
 
                        pn = (u64)ri->pg0.WWPN.High << 32 |
                             (u64)ri->pg0.WWPN.Low;
@@ -1119,6 +1128,8 @@ mptfc_rescan_devices(struct work_struct *work)
        int                     ii;
        u64                     pn;
        struct mptfc_rport_info *ri;
+       struct scsi_target      *starget;
+       VirtTarget              *vtarget;
 
        /* start by tagging all ports as missing */
        list_for_each_entry(ri, &ioc->fc_rports, list) {
@@ -1146,6 +1157,12 @@ mptfc_rescan_devices(struct work_struct *work)
                                       MPT_RPORT_INFO_FLAGS_MISSING);
                        fc_remote_port_delete(ri->rport);       /* won't sleep */
                        ri->rport = NULL;
+                       starget = ri->starget;
+                       if (starget) {
+                               vtarget = starget->hostdata;
+                               if (vtarget)
+                                       vtarget->deleted = 1;
+                       }
 
                        pn = (u64)ri->pg0.WWPN.High << 32 |
                             (u64)ri->pg0.WWPN.Low;
index b966678..90a1dff 100644 (file)
@@ -2339,6 +2339,8 @@ mptscsih_slave_destroy(struct scsi_device *sdev)
        starget = scsi_target(sdev);
        vtarget = starget->hostdata;
        vdevice = sdev->hostdata;
+       if (!vdevice)
+               return;
 
        mptscsih_search_running_cmds(hd, vdevice);
        vtarget->num_luns--;