]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - drivers/message/fusion/mptscsih.c
[SCSI] fusion: FC rport code fixes
[linux-2.6-omap-h63xx.git] / drivers / message / fusion / mptscsih.c
index 93a16fa3c4baeab822056108f9e622e906b10d5c..56c3d1f78f0500f8ec250d4fc2551500d6110f82 100644 (file)
@@ -162,8 +162,6 @@ static void mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice);
 static void    mptscsih_negotiate_to_asyn_narrow(MPT_SCSI_HOST *hd, VirtTarget *vtarget);
 static int     mptscsih_is_phys_disk(MPT_ADAPTER *ioc, int id);
 
-static struct work_struct   mptscsih_persistTask;
-
 #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
 static int     mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
 static void    mptscsih_domainValidation(void *hd);
@@ -893,6 +891,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
  *             when a lun is disable by mid-layer.
  *             Do NOT access the referenced scsi_cmnd structure or
  *             members. Will cause either a paging or NULL ptr error.
+ *             (BUT, BUT, BUT, the code does reference it! - mdr)
  *      @hd: Pointer to a SCSI HOST structure
  *     @vdevice: per device private data
  *
@@ -2162,10 +2161,9 @@ mptscsih_target_alloc(struct scsi_target *starget)
 {
        VirtTarget              *vtarget;
 
-       vtarget = kmalloc(sizeof(VirtTarget), GFP_KERNEL);
+       vtarget = kzalloc(sizeof(VirtTarget), GFP_KERNEL);
        if (!vtarget)
                return -ENOMEM;
-       memset(vtarget, 0, sizeof(VirtTarget));
        starget->hostdata = vtarget;
        return 0;
 }
@@ -2185,14 +2183,13 @@ mptscsih_slave_alloc(struct scsi_device *sdev)
        VirtDevice              *vdev;
        struct scsi_target      *starget;
 
-       vdev = kmalloc(sizeof(VirtDevice), GFP_KERNEL);
+       vdev = kzalloc(sizeof(VirtDevice), GFP_KERNEL);
        if (!vdev) {
                printk(MYIOC_s_ERR_FMT "slave_alloc kmalloc(%zd) FAILED!\n",
                                hd->ioc->name, sizeof(VirtDevice));
                return -ENOMEM;
        }
 
-       memset(vdev, 0, sizeof(VirtDevice));
        vdev->ioc_id = hd->ioc->id;
        vdev->target_id = sdev->id;
        vdev->bus_id = sdev->channel;
@@ -2559,13 +2556,25 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
                        hd->cmdPtr = NULL;
                }
 
-               /* 7. Set flag to force DV and re-read IOC Page 3
+               /* 7. SPI: Set flag to force DV and re-read IOC Page 3
                 */
                if (ioc->bus_type == SPI) {
                        ioc->spi_data.forceDv = MPT_SCSICFG_NEED_DV | MPT_SCSICFG_RELOAD_IOC_PG3;
                        ddvtprintk(("Set reload IOC Pg3 Flag\n"));
                }
 
+               /* 7. FC: Rescan for blocked rports which might have returned.
+                */
+               else if (ioc->bus_type == FC) {
+                       int work_count;
+                       unsigned long flags;
+
+                       spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
+                       work_count = ++ioc->fc_rescan_work_count;
+                       spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
+                       if (work_count == 1)
+                               schedule_work(&ioc->fc_rescan_work);
+               }
                dtmprintk((MYIOC_s_WARN_FMT "Post-Reset complete.\n", ioc->name));
 
        }
@@ -2573,22 +2582,14 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
        return 1;               /* currently means nothing really */
 }
 
-/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
-/* work queue thread to clear the persitency table */
-static void
-mptscsih_sas_persist_clear_table(void * arg)
-{
-       MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
-
-       mptbase_sas_persist_operation(ioc, MPI_SAS_OP_CLEAR_NOT_PRESENT);
-}
-
 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
 int
 mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
 {
        MPT_SCSI_HOST *hd;
        u8 event = le32_to_cpu(pEvReply->Event) & 0xFF;
+       int work_count;
+       unsigned long flags;
 
        devtprintk((MYIOC_s_INFO_FMT "MPT event (=%02Xh) routed to SCSI host driver!\n",
                        ioc->name, event));
@@ -2610,11 +2611,18 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
                /* FIXME! */
                break;
 
+       case MPI_EVENT_RESCAN:                          /* 06 */
+               spin_lock_irqsave(&ioc->fc_rescan_work_lock, flags);
+               work_count = ++ioc->fc_rescan_work_count;
+               spin_unlock_irqrestore(&ioc->fc_rescan_work_lock, flags);
+               if (work_count == 1)
+                       schedule_work(&ioc->fc_rescan_work);
+               break;
+
                /*
                 *  CHECKME! Don't think we need to do
                 *  anything for these, but...
                 */
-       case MPI_EVENT_RESCAN:                          /* 06 */
        case MPI_EVENT_LINK_STATUS_CHANGE:              /* 07 */
        case MPI_EVENT_LOOP_STATE_CHANGE:               /* 08 */
                /*
@@ -2636,13 +2644,6 @@ mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply)
                break;
        }
 
-       /* Persistent table is full. */
-       case MPI_EVENT_PERSISTENT_TABLE_FULL:
-               INIT_WORK(&mptscsih_persistTask,
-                   mptscsih_sas_persist_clear_table,(void *)ioc);
-               schedule_work(&mptscsih_persistTask);
-               break;
-
        case MPI_EVENT_NONE:                            /* 00 */
        case MPI_EVENT_LOG_DATA:                        /* 01 */
        case MPI_EVENT_STATE_CHANGE:                    /* 02 */
@@ -3952,8 +3953,6 @@ mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, VirtDevice *vdevice)
                mptscsih_do_cmd(hd, &iocmd);
 }
 
-/* Search IOC page 3 to determine if this is hidden physical disk
- */
 /* Search IOC page 3 to determine if this is hidden physical disk
  */
 static int