]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/block/cciss.c
Merge branch 'for-2.6.37/drivers' of git://git.kernel.dk/linux-2.6-block
[net-next-2.6.git] / drivers / block / cciss.c
index 41f9acb8ecd78515f39b686cf11f2f6f8b515148..f09e6df15aa7f8e9c6f5842920e43eee3819f21b 100644 (file)
@@ -26,7 +26,6 @@
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/slab.h>
-#include <linux/smp_lock.h>
 #include <linux/delay.h>
 #include <linux/major.h>
 #include <linux/fs.h>
@@ -66,6 +65,7 @@ MODULE_SUPPORTED_DEVICE("HP Smart Array Controllers");
 MODULE_VERSION("3.6.26");
 MODULE_LICENSE("GPL");
 
+static DEFINE_MUTEX(cciss_mutex);
 static int cciss_allow_hpsa;
 module_param(cciss_allow_hpsa, int, S_IRUGO|S_IWUSR);
 MODULE_PARM_DESC(cciss_allow_hpsa,
@@ -299,6 +299,8 @@ static void enqueue_cmd_and_start_io(ctlr_info_t *h,
        spin_lock_irqsave(&h->lock, flags);
        addQ(&h->reqQ, c);
        h->Qdepth++;
+       if (h->Qdepth > h->maxQsinceinit)
+               h->maxQsinceinit = h->Qdepth;
        start_io(h);
        spin_unlock_irqrestore(&h->lock, flags);
 }
@@ -1059,9 +1061,9 @@ static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode)
 {
        int ret;
 
-       lock_kernel();
+       mutex_lock(&cciss_mutex);
        ret = cciss_open(bdev, mode);
-       unlock_kernel();
+       mutex_unlock(&cciss_mutex);
 
        return ret;
 }
@@ -1074,13 +1076,13 @@ static int cciss_release(struct gendisk *disk, fmode_t mode)
        ctlr_info_t *h;
        drive_info_struct *drv;
 
-       lock_kernel();
+       mutex_lock(&cciss_mutex);
        h = get_host(disk);
        drv = get_drv(disk);
        dev_dbg(&h->pdev->dev, "cciss_release %s\n", disk->disk_name);
        drv->usage_count--;
        h->usage_count--;
-       unlock_kernel();
+       mutex_unlock(&cciss_mutex);
        return 0;
 }
 
@@ -1088,9 +1090,9 @@ static int do_ioctl(struct block_device *bdev, fmode_t mode,
                    unsigned cmd, unsigned long arg)
 {
        int ret;
-       lock_kernel();
+       mutex_lock(&cciss_mutex);
        ret = cciss_ioctl(bdev, mode, cmd, arg);
-       unlock_kernel();
+       mutex_unlock(&cciss_mutex);
        return ret;
 }
 
@@ -4503,6 +4505,12 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
        misc_fw_support = readl(&cfgtable->misc_fw_support);
        use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
 
+       /* The doorbell reset seems to cause lockups on some Smart
+        * Arrays (e.g. P410, P410i, maybe others).  Until this is
+        * fixed or at least isolated, avoid the doorbell reset.
+        */
+       use_doorbell = 0;
+
        rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell);
        if (rc)
                goto unmap_cfgtable;
@@ -4696,6 +4704,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
        h->scatter_list = kmalloc(h->max_commands *
                                                sizeof(struct scatterlist *),
                                                GFP_KERNEL);
+       if (!h->scatter_list)
+               goto clean4;
+
        for (k = 0; k < h->nr_cmds; k++) {
                h->scatter_list[k] = kmalloc(sizeof(struct scatterlist) *
                                                        h->maxsgentries,
@@ -4765,7 +4776,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
 clean4:
        kfree(h->cmd_pool_bits);
        /* Free up sg elements */
-       for (k = 0; k < h->nr_cmds; k++)
+       for (k-- ; k >= 0; k--)
                kfree(h->scatter_list[k]);
        kfree(h->scatter_list);
        cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds);