]> err.no Git - linux-2.6/blobdiff - drivers/scsi/aacraid/commsup.c
[SCSI] aacraid: adjustable timeouts
[linux-2.6] / drivers / scsi / aacraid / commsup.c
index 723c0cea7c04a4ade79767a22eadc27ed2747c67..1c83af3d0f3d499084c5385a5a7c08e70148e3f1 100644 (file)
 #include <linux/slab.h>
 #include <linux/completion.h>
 #include <linux/blkdev.h>
+#include <linux/delay.h>
+#include <linux/kthread.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_device.h>
 #include <asm/semaphore.h>
-#include <asm/delay.h>
 
 #include "aacraid.h"
 
@@ -67,27 +68,27 @@ static int fib_map_alloc(struct aac_dev *dev)
 }
 
 /**
- *     fib_map_free            -       free the fib objects
+ *     aac_fib_map_free                -       free the fib objects
  *     @dev: Adapter to free
  *
  *     Free the PCI mappings and the memory allocated for FIB blocks
  *     on this adapter.
  */
 
-void fib_map_free(struct aac_dev *dev)
+void aac_fib_map_free(struct aac_dev *dev)
 {
        pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa);
 }
 
 /**
- *     fib_setup       -       setup the fibs
+ *     aac_fib_setup   -       setup the fibs
  *     @dev: Adapter to set up
  *
  *     Allocate the PCI space for the fibs, map it and then intialise the
  *     fib area, the unmapped fib data and also the free list
  */
 
-int fib_setup(struct aac_dev * dev)
+int aac_fib_setup(struct aac_dev * dev)
 {
        struct fib *fibptr;
        struct hw_fib *hw_fib_va;
@@ -134,14 +135,14 @@ int fib_setup(struct aac_dev * dev)
 }
 
 /**
- *     fib_alloc       -       allocate a fib
+ *     aac_fib_alloc   -       allocate a fib
  *     @dev: Adapter to allocate the fib for
  *
  *     Allocate a fib from the adapter fib pool. If the pool is empty we
  *     return NULL.
  */
  
-struct fib * fib_alloc(struct aac_dev *dev)
+struct fib *aac_fib_alloc(struct aac_dev *dev)
 {
        struct fib * fibptr;
        unsigned long flags;
@@ -170,14 +171,14 @@ struct fib * fib_alloc(struct aac_dev *dev)
 }
 
 /**
- *     fib_free        -       free a fib
+ *     aac_fib_free    -       free a fib
  *     @fibptr: fib to free up
  *
  *     Frees up a fib and places it on the appropriate queue
  *     (either free or timed out)
  */
  
-void fib_free(struct fib * fibptr)
+void aac_fib_free(struct fib *fibptr)
 {
        unsigned long flags;
 
@@ -188,7 +189,7 @@ void fib_free(struct fib * fibptr)
                fibptr->dev->timeout_fib = fibptr;
        } else {
                if (fibptr->hw_fib->header.XferState != 0) {
-                       printk(KERN_WARNING "fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n", 
+                       printk(KERN_WARNING "aac_fib_free, XferState != 0, fibptr = 0x%p, XferState = 0x%x\n",
                                 (void*)fibptr, 
                                 le32_to_cpu(fibptr->hw_fib->header.XferState));
                }
@@ -199,13 +200,13 @@ void fib_free(struct fib * fibptr)
 }
 
 /**
- *     fib_init        -       initialise a fib
+ *     aac_fib_init    -       initialise a fib
  *     @fibptr: The fib to initialize
  *     
  *     Set up the generic fib fields ready for use
  */
  
-void fib_init(struct fib *fibptr)
+void aac_fib_init(struct fib *fibptr)
 {
        struct hw_fib *hw_fib = fibptr->hw_fib;
 
@@ -362,7 +363,7 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
  */
 
 /**
- *     fib_send        -       send a fib to the adapter
+ *     aac_fib_send    -       send a fib to the adapter
  *     @command: Command to send
  *     @fibptr: The fib
  *     @size: Size of fib data area
@@ -378,7 +379,9 @@ static int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_f
  *     response FIB is received from the adapter.
  */
  
-int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority, int wait, int reply, fib_callback callback, void * callback_data)
+int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
+               int priority, int wait, int reply, fib_callback callback,
+               void *callback_data)
 {
        struct aac_dev * dev = fibptr->dev;
        struct hw_fib * hw_fib = fibptr->hw_fib;
@@ -493,7 +496,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority
                q->numpending++;
                *(q->headers.producer) = cpu_to_le32(index + 1);
                spin_unlock_irqrestore(q->lock, qflags);
-               dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));
+               dprintk((KERN_DEBUG "aac_fib_send: inserting a queue entry at index %d.\n",index));
                if (!(nointr & aac_config.irq_mod))
                        aac_adapter_notify(dev, AdapNormCmdQueue);
        }
@@ -520,7 +523,7 @@ int fib_send(u16 command, struct fib * fibptr, unsigned long size,  int priority
                                        list_del(&fibptr->queue);
                                        spin_unlock_irqrestore(q->lock, qflags);
                                        if (wait == -1) {
-                                               printk(KERN_ERR "aacraid: fib_send: first asynchronous command timed out.\n"
+                                               printk(KERN_ERR "aacraid: aac_fib_send: first asynchronous command timed out.\n"
                                                  "Usually a result of a PCI interrupt routing problem;\n"
                                                  "update mother board BIOS or consider utilizing one of\n"
                                                  "the SAFE mode kernel options (acpi, apic etc)\n");
@@ -624,7 +627,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid)
 }        
 
 /**
- *     fib_adapter_complete    -       complete adapter issued fib
+ *     aac_fib_adapter_complete        -       complete adapter issued fib
  *     @fibptr: fib to complete
  *     @size: size of fib
  *
@@ -632,7 +635,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid)
  *     the adapter.
  */
 
-int fib_adapter_complete(struct fib * fibptr, unsigned short size)
+int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size)
 {
        struct hw_fib * hw_fib = fibptr->hw_fib;
        struct aac_dev * dev = fibptr->dev;
@@ -683,20 +686,20 @@ int fib_adapter_complete(struct fib * fibptr, unsigned short size)
        }
        else 
        {
-               printk(KERN_WARNING "fib_adapter_complete: Unknown xferstate detected.\n");
+               printk(KERN_WARNING "aac_fib_adapter_complete: Unknown xferstate detected.\n");
                BUG();
        }   
        return 0;
 }
 
 /**
- *     fib_complete    -       fib completion handler
+ *     aac_fib_complete        -       fib completion handler
  *     @fib: FIB to complete
  *
  *     Will do all necessary work to complete a FIB.
  */
  
-int fib_complete(struct fib * fibptr)
+int aac_fib_complete(struct fib *fibptr)
 {
        struct hw_fib * hw_fib = fibptr->hw_fib;
 
@@ -764,9 +767,9 @@ void aac_printf(struct aac_dev *dev, u32 val)
                if (cp[length] != 0)
                        cp[length] = 0;
                if (level == LOG_AAC_HIGH_ERROR)
-                       printk(KERN_WARNING "aacraid:%s", cp);
+                       printk(KERN_WARNING "%s:%s", dev->name, cp);
                else
-                       printk(KERN_INFO "aacraid:%s", cp);
+                       printk(KERN_INFO "%s:%s", dev->name, cp);
        }
        memset(cp, 0,  256);
 }
@@ -781,6 +784,7 @@ void aac_printf(struct aac_dev *dev, u32 val)
  *     dispatches it to the appropriate routine for handling.
  */
 
+#define AIF_SNIFF_TIMEOUT      (30*HZ)
 static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
 {
        struct hw_fib * hw_fib = fibptr->hw_fib;
@@ -820,7 +824,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                                break;
 
                        /*
-                        *      Find the Scsi_Device associated with the SCSI
+                        *      Find the scsi_device associated with the SCSI
                         * address. Make sure we have the right array, and if
                         * so set the flag to initiate a new re-config once we
                         * see an AifEnConfigChange AIF come through.
@@ -834,6 +838,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                                if (device) {
                                        dev->fsa_dev[container].config_needed = CHANGE;
                                        dev->fsa_dev[container].config_waiting_on = AifEnConfigChange;
+                                       dev->fsa_dev[container].config_waiting_stamp = jiffies;
                                        scsi_device_put(device);
                                }
                        }
@@ -846,13 +851,15 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                if (container != (u32)-1) {
                        if (container >= dev->maximum_num_containers)
                                break;
-                       if (dev->fsa_dev[container].config_waiting_on ==
-                           le32_to_cpu(*(u32 *)aifcmd->data))
+                       if ((dev->fsa_dev[container].config_waiting_on ==
+                           le32_to_cpu(*(u32 *)aifcmd->data)) &&
+                        time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT))
                                dev->fsa_dev[container].config_waiting_on = 0;
                } else for (container = 0;
                    container < dev->maximum_num_containers; ++container) {
-                       if (dev->fsa_dev[container].config_waiting_on ==
-                           le32_to_cpu(*(u32 *)aifcmd->data))
+                       if ((dev->fsa_dev[container].config_waiting_on ==
+                           le32_to_cpu(*(u32 *)aifcmd->data)) &&
+                        time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT))
                                dev->fsa_dev[container].config_waiting_on = 0;
                }
                break;
@@ -869,6 +876,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                        dev->fsa_dev[container].config_needed = ADD;
                        dev->fsa_dev[container].config_waiting_on =
                                AifEnConfigChange;
+                       dev->fsa_dev[container].config_waiting_stamp = jiffies;
                        break;
 
                /*
@@ -881,6 +889,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                        dev->fsa_dev[container].config_needed = DELETE;
                        dev->fsa_dev[container].config_waiting_on =
                                AifEnConfigChange;
+                       dev->fsa_dev[container].config_waiting_stamp = jiffies;
                        break;
 
                /*
@@ -891,11 +900,13 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                        container = le32_to_cpu(((u32 *)aifcmd->data)[1]);
                        if (container >= dev->maximum_num_containers)
                                break;
-                       if (dev->fsa_dev[container].config_waiting_on)
+                       if (dev->fsa_dev[container].config_waiting_on &&
+                        time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT))
                                break;
                        dev->fsa_dev[container].config_needed = CHANGE;
                        dev->fsa_dev[container].config_waiting_on =
                                AifEnConfigChange;
+                       dev->fsa_dev[container].config_waiting_stamp = jiffies;
                        break;
 
                case AifEnConfigChange:
@@ -910,13 +921,15 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                if (container != (u32)-1) {
                        if (container >= dev->maximum_num_containers)
                                break;
-                       if (dev->fsa_dev[container].config_waiting_on ==
-                           le32_to_cpu(*(u32 *)aifcmd->data))
+                       if ((dev->fsa_dev[container].config_waiting_on ==
+                           le32_to_cpu(*(u32 *)aifcmd->data)) &&
+                        time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT))
                                dev->fsa_dev[container].config_waiting_on = 0;
                } else for (container = 0;
                    container < dev->maximum_num_containers; ++container) {
-                       if (dev->fsa_dev[container].config_waiting_on ==
-                           le32_to_cpu(*(u32 *)aifcmd->data))
+                       if ((dev->fsa_dev[container].config_waiting_on ==
+                           le32_to_cpu(*(u32 *)aifcmd->data)) &&
+                        time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT))
                                dev->fsa_dev[container].config_waiting_on = 0;
                }
                break;
@@ -943,6 +956,8 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                                dev->fsa_dev[container].config_waiting_on =
                                        AifEnContainerChange;
                                dev->fsa_dev[container].config_needed = ADD;
+                               dev->fsa_dev[container].config_waiting_stamp =
+                                       jiffies;
                        }
                }
                if ((((u32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero))
@@ -958,6 +973,8 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
                                dev->fsa_dev[container].config_waiting_on =
                                        AifEnContainerChange;
                                dev->fsa_dev[container].config_needed = DELETE;
+                               dev->fsa_dev[container].config_waiting_stamp =
+                                       jiffies;
                        }
                }
                break;
@@ -966,8 +983,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
        device_config_needed = NOTHING;
        for (container = 0; container < dev->maximum_num_containers;
            ++container) {
-               if ((dev->fsa_dev[container].config_waiting_on == 0)
-                && (dev->fsa_dev[container].config_needed != NOTHING)) {
+               if ((dev->fsa_dev[container].config_waiting_on == 0) &&
+                       (dev->fsa_dev[container].config_needed != NOTHING) &&
+                       time_before(jiffies, dev->fsa_dev[container].config_waiting_stamp + AIF_SNIFF_TIMEOUT)) {
                        device_config_needed =
                                dev->fsa_dev[container].config_needed;
                        dev->fsa_dev[container].config_needed = NOTHING;
@@ -987,7 +1005,7 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
 
 
        /*
-        *      Find the Scsi_Device associated with the SCSI address,
+        *      Find the scsi_device associated with the SCSI address,
         * and mark it as changed, invalidating the cache. This deals
         * with changes to existing device IDs.
         */
@@ -995,14 +1013,14 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
        if (!dev || !dev->scsi_host_ptr)
                return;
        /*
-        * force reload of disk info via probe_container
+        * force reload of disk info via aac_probe_container
         */
        if ((device_config_needed == CHANGE)
         && (dev->fsa_dev[container].valid == 1))
                dev->fsa_dev[container].valid = 2;
        if ((device_config_needed == CHANGE) ||
                        (device_config_needed == ADD))
-               probe_container(dev, container);
+               aac_probe_container(dev, container);
        device = scsi_device_lookup(dev->scsi_host_ptr, 
                CONTAINER_TO_CHANNEL(container), 
                CONTAINER_TO_ID(container), 
@@ -1043,8 +1061,9 @@ static void aac_handle_aif(struct aac_dev * dev, struct fib * fibptr)
  *     more FIBs.
  */
  
-int aac_command_thread(struct aac_dev * dev)
+int aac_command_thread(void *data)
 {
+       struct aac_dev *dev = data;
        struct hw_fib *hw_fib, *hw_newfib;
        struct fib *fib, *newfib;
        struct aac_fib_context *fibctx;
@@ -1056,12 +1075,7 @@ int aac_command_thread(struct aac_dev * dev)
         */
        if (dev->aif_thread)
                return -EINVAL;
-       /*
-        *      Set up the name that will appear in 'ps'
-        *      stored in  task_struct.comm[16].
-        */
-       daemonize("aacraid");
-       allow_signal(SIGKILL);
+
        /*
         *      Let the DPC know it has a place to send the AIF's to.
         */
@@ -1104,7 +1118,7 @@ int aac_command_thread(struct aac_dev * dev)
                                /* Handle Driver Notify Events */
                                aac_handle_aif(dev, fib);
                                *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
-                               fib_adapter_complete(fib, (u16)sizeof(u32));
+                               aac_fib_adapter_complete(fib, (u16)sizeof(u32));
                        } else {
                                struct list_head *entry;
                                /* The u32 here is important and intended. We are using
@@ -1200,7 +1214,7 @@ int aac_command_thread(struct aac_dev * dev)
                                                 * since the last read off
                                                 * the queue?
                                                 */
-                                               if ((time_now - time_last) > 120) {
+                                               if ((time_now - time_last) > aif_timeout) {
                                                        entry = entry->next;
                                                        aac_close_fib_context(dev, fibctx);
                                                        continue;
@@ -1241,7 +1255,7 @@ int aac_command_thread(struct aac_dev * dev)
                                 *      Set the status of this FIB
                                 */
                                *(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);
-                               fib_adapter_complete(fib, sizeof(u32));
+                               aac_fib_adapter_complete(fib, sizeof(u32));
                                spin_unlock_irqrestore(&dev->fib_lock, flagv);
                                /* Free up the remaining resources */
                                hw_fib_p = hw_fib_pool;
@@ -1264,13 +1278,12 @@ int aac_command_thread(struct aac_dev * dev)
                spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags);
                schedule();
 
-               if(signal_pending(current))
+               if (kthread_should_stop())
                        break;
                set_current_state(TASK_INTERRUPTIBLE);
        }
        if (dev->queues)
                remove_wait_queue(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait);
        dev->aif_thread = 0;
-       complete_and_exit(&dev->aif_completion, 0);
        return 0;
 }