- patches.apparmor/remove_suid_new_case_in_2.6.22.diff: Merge fix.
[linux-flexiantxendom0-3.2.10.git] / drivers / message / fusion / mptspi.c
index 85f21b5..d75f7ff 100644 (file)
@@ -96,14 +96,13 @@ static int  mptspiTaskCtx = -1;
 static int     mptspiInternalCtx = -1; /* Used only for internal commands */
 
 /**
- *     mptspi_setTargetNegoParms  - Update the target negotiation
- *     parameters based on the the Inquiry data, adapter capabilities,
- *     and NVRAM settings
- *
+ *     mptspi_setTargetNegoParms  - Update the target negotiation parameters
  *     @hd: Pointer to a SCSI Host Structure
- *     @vtarget: per target private data
+ *     @target: per target private data
  *     @sdev: SCSI device
  *
+ *     Update the target negotiation parameters based on the the Inquiry
+ *     data, adapter capabilities, and NVRAM settings.
  **/
 static void
 mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
@@ -234,7 +233,7 @@ mptspi_setTargetNegoParms(MPT_SCSI_HOST *hd, VirtTarget *target,
 /**
  *     mptspi_writeIOCPage4  - write IOC Page 4
  *     @hd: Pointer to a SCSI Host Structure
- *     @channel:
+ *     @channel: channel number
  *     @id: write IOC Page4 for this ID & Bus
  *
  *     Return: -EAGAIN if unable to obtain a Message Frame
@@ -446,7 +445,7 @@ static int mptspi_target_alloc(struct scsi_target *starget)
        return 0;
 }
 
-void
+static void
 mptspi_target_destroy(struct scsi_target *starget)
 {
        if (starget->hostdata)
@@ -677,7 +676,9 @@ static void mptspi_dv_device(struct _MPT_SCSI_HOST *hd,
                return;
        }
 
+       hd->spi_pending |= (1 << sdev->id);
        spi_dv_device(sdev);
+       hd->spi_pending &= ~(1 << sdev->id);
 
        if (sdev->channel == 1 &&
            mptscsih_quiesce_raid(hd, 0, vtarget->channel, vtarget->id) < 0)
@@ -1203,11 +1204,27 @@ mptspi_dv_renegotiate_work(struct work_struct *work)
                container_of(work, struct work_queue_wrapper, work);
        struct _MPT_SCSI_HOST *hd = wqw->hd;
        struct scsi_device *sdev;
+       struct scsi_target *starget;
+       struct _CONFIG_PAGE_SCSI_DEVICE_1 pg1;
+       u32 nego;
 
        kfree(wqw);
 
-       shost_for_each_device(sdev, hd->ioc->sh)
-               mptspi_dv_device(hd, sdev);
+       if (hd->spi_pending) {
+               shost_for_each_device(sdev, hd->ioc->sh) {
+                       if  (hd->spi_pending & (1 << sdev->id))
+                               continue;
+                       starget = scsi_target(sdev);
+                       nego = mptspi_getRP(starget);
+                       pg1.RequestedParameters = cpu_to_le32(nego);
+                       pg1.Reserved = 0;
+                       pg1.Configuration = 0;
+                       mptspi_write_spi_device_pg1(starget, &pg1);
+               }
+       } else {
+               shost_for_each_device(sdev, hd->ioc->sh)
+                       mptspi_dv_device(hd, sdev);
+       }
 }
 
 static void
@@ -1453,6 +1470,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
        init_waitqueue_head(&hd->scandv_waitq);
        hd->scandv_wait_done = 0;
        hd->last_queue_full = 0;
+       hd->spi_pending = 0;
 
        /* Some versions of the firmware don't support page 0; without
         * that we can't get the parameters */