Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6
[sfrench/cifs-2.6.git] / drivers / scsi / aacraid / commsup.c
index 1dd2e57c3345dfc499b9f90caf8b2d1efae2e0be..ef67816a6fe5940211247e96e1299343e3f4a298 100644 (file)
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/interrupt.h>
+#include <linux/semaphore.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_cmnd.h>
-#include <asm/semaphore.h>
 
 #include "aacraid.h"
 
@@ -515,10 +515,12 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
                                }
                                udelay(5);
                        }
-               } else
-                       (void)down_interruptible(&fibptr->event_wait);
+               } else if (down_interruptible(&fibptr->event_wait) == 0) {
+                       fibptr->done = 2;
+                       up(&fibptr->event_wait);
+               }
                spin_lock_irqsave(&fibptr->event_lock, flags);
-               if (fibptr->done == 0) {
+               if ((fibptr->done == 0) || (fibptr->done == 2)) {
                        fibptr->done = 2; /* Tell interrupt we aborted */
                        spin_unlock_irqrestore(&fibptr->event_lock, flags);
                        return -EINTR;
@@ -594,7 +596,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid)
        if (le32_to_cpu(*q->headers.consumer) >= q->entries)
                *q->headers.consumer = cpu_to_le32(1);
        else
-               *q->headers.consumer = cpu_to_le32(le32_to_cpu(*q->headers.consumer)+1);
+               le32_add_cpu(q->headers.consumer, 1);
 
        if (wasfull) {
                switch (qid) {
@@ -901,7 +903,31 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                case AifEnConfigChange:
                        break;
 
+               case AifEnAddJBOD:
+               case AifEnDeleteJBOD:
+                       container = le32_to_cpu(((__le32 *)aifcmd->data)[1]);
+                       if ((container >> 28))
+                               break;
+                       channel = (container >> 24) & 0xF;
+                       if (channel >= dev->maximum_num_channels)
+                               break;
+                       id = container & 0xFFFF;
+                       if (id >= dev->maximum_num_physicals)
+                               break;
+                       lun = (container >> 16) & 0xFF;
+                       channel = aac_phys_to_logical(channel);
+                       device_config_needed =
+                         (((__le32 *)aifcmd->data)[0] ==
+                           cpu_to_le32(AifEnAddJBOD)) ? ADD : DELETE;
+                       break;
+
                case AifEnEnclosureManagement:
+                       /*
+                        * If in JBOD mode, automatic exposure of new
+                        * physical target to be suppressed until configured.
+                        */
+                       if (dev->jbod)
+                               break;
                        switch (le32_to_cpu(((__le32 *)aifcmd->data)[3])) {
                        case EM_DRIVE_INSERTION:
                        case EM_DRIVE_REMOVAL:
@@ -1434,7 +1460,7 @@ int aac_check_health(struct aac_dev * aac)
 
        printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED);
 
-       if (!aac_check_reset || ((aac_check_reset != 1) &&
+       if (!aac_check_reset || ((aac_check_reset == 1) &&
                (aac->supplement_adapter_info.SupportedOptions2 &
                        AAC_OPTION_IGNORE_RESET)))
                goto out;