aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/cciss.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/cciss.c')
-rw-r--r--drivers/block/cciss.c27
1 files changed, 19 insertions, 8 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 41f9acb8ecd7..f09e6df15aa7 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -26,7 +26,6 @@
26#include <linux/pci.h> 26#include <linux/pci.h>
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/smp_lock.h>
30#include <linux/delay.h> 29#include <linux/delay.h>
31#include <linux/major.h> 30#include <linux/major.h>
32#include <linux/fs.h> 31#include <linux/fs.h>
@@ -66,6 +65,7 @@ MODULE_SUPPORTED_DEVICE("HP Smart Array Controllers");
66MODULE_VERSION("3.6.26"); 65MODULE_VERSION("3.6.26");
67MODULE_LICENSE("GPL"); 66MODULE_LICENSE("GPL");
68 67
68static DEFINE_MUTEX(cciss_mutex);
69static int cciss_allow_hpsa; 69static int cciss_allow_hpsa;
70module_param(cciss_allow_hpsa, int, S_IRUGO|S_IWUSR); 70module_param(cciss_allow_hpsa, int, S_IRUGO|S_IWUSR);
71MODULE_PARM_DESC(cciss_allow_hpsa, 71MODULE_PARM_DESC(cciss_allow_hpsa,
@@ -299,6 +299,8 @@ static void enqueue_cmd_and_start_io(ctlr_info_t *h,
299 spin_lock_irqsave(&h->lock, flags); 299 spin_lock_irqsave(&h->lock, flags);
300 addQ(&h->reqQ, c); 300 addQ(&h->reqQ, c);
301 h->Qdepth++; 301 h->Qdepth++;
302 if (h->Qdepth > h->maxQsinceinit)
303 h->maxQsinceinit = h->Qdepth;
302 start_io(h); 304 start_io(h);
303 spin_unlock_irqrestore(&h->lock, flags); 305 spin_unlock_irqrestore(&h->lock, flags);
304} 306}
@@ -1059,9 +1061,9 @@ static int cciss_unlocked_open(struct block_device *bdev, fmode_t mode)
1059{ 1061{
1060 int ret; 1062 int ret;
1061 1063
1062 lock_kernel(); 1064 mutex_lock(&cciss_mutex);
1063 ret = cciss_open(bdev, mode); 1065 ret = cciss_open(bdev, mode);
1064 unlock_kernel(); 1066 mutex_unlock(&cciss_mutex);
1065 1067
1066 return ret; 1068 return ret;
1067} 1069}
@@ -1074,13 +1076,13 @@ static int cciss_release(struct gendisk *disk, fmode_t mode)
1074 ctlr_info_t *h; 1076 ctlr_info_t *h;
1075 drive_info_struct *drv; 1077 drive_info_struct *drv;
1076 1078
1077 lock_kernel(); 1079 mutex_lock(&cciss_mutex);
1078 h = get_host(disk); 1080 h = get_host(disk);
1079 drv = get_drv(disk); 1081 drv = get_drv(disk);
1080 dev_dbg(&h->pdev->dev, "cciss_release %s\n", disk->disk_name); 1082 dev_dbg(&h->pdev->dev, "cciss_release %s\n", disk->disk_name);
1081 drv->usage_count--; 1083 drv->usage_count--;
1082 h->usage_count--; 1084 h->usage_count--;
1083 unlock_kernel(); 1085 mutex_unlock(&cciss_mutex);
1084 return 0; 1086 return 0;
1085} 1087}
1086 1088
@@ -1088,9 +1090,9 @@ static int do_ioctl(struct block_device *bdev, fmode_t mode,
1088 unsigned cmd, unsigned long arg) 1090 unsigned cmd, unsigned long arg)
1089{ 1091{
1090 int ret; 1092 int ret;
1091 lock_kernel(); 1093 mutex_lock(&cciss_mutex);
1092 ret = cciss_ioctl(bdev, mode, cmd, arg); 1094 ret = cciss_ioctl(bdev, mode, cmd, arg);
1093 unlock_kernel(); 1095 mutex_unlock(&cciss_mutex);
1094 return ret; 1096 return ret;
1095} 1097}
1096 1098
@@ -4503,6 +4505,12 @@ static __devinit int cciss_kdump_hard_reset_controller(struct pci_dev *pdev)
4503 misc_fw_support = readl(&cfgtable->misc_fw_support); 4505 misc_fw_support = readl(&cfgtable->misc_fw_support);
4504 use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET; 4506 use_doorbell = misc_fw_support & MISC_FW_DOORBELL_RESET;
4505 4507
4508 /* The doorbell reset seems to cause lockups on some Smart
4509 * Arrays (e.g. P410, P410i, maybe others). Until this is
4510 * fixed or at least isolated, avoid the doorbell reset.
4511 */
4512 use_doorbell = 0;
4513
4506 rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell); 4514 rc = cciss_controller_hard_reset(pdev, vaddr, use_doorbell);
4507 if (rc) 4515 if (rc)
4508 goto unmap_cfgtable; 4516 goto unmap_cfgtable;
@@ -4696,6 +4704,9 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
4696 h->scatter_list = kmalloc(h->max_commands * 4704 h->scatter_list = kmalloc(h->max_commands *
4697 sizeof(struct scatterlist *), 4705 sizeof(struct scatterlist *),
4698 GFP_KERNEL); 4706 GFP_KERNEL);
4707 if (!h->scatter_list)
4708 goto clean4;
4709
4699 for (k = 0; k < h->nr_cmds; k++) { 4710 for (k = 0; k < h->nr_cmds; k++) {
4700 h->scatter_list[k] = kmalloc(sizeof(struct scatterlist) * 4711 h->scatter_list[k] = kmalloc(sizeof(struct scatterlist) *
4701 h->maxsgentries, 4712 h->maxsgentries,
@@ -4765,7 +4776,7 @@ static int __devinit cciss_init_one(struct pci_dev *pdev,
4765clean4: 4776clean4:
4766 kfree(h->cmd_pool_bits); 4777 kfree(h->cmd_pool_bits);
4767 /* Free up sg elements */ 4778 /* Free up sg elements */
4768 for (k = 0; k < h->nr_cmds; k++) 4779 for (k-- ; k >= 0; k--)
4769 kfree(h->scatter_list[k]); 4780 kfree(h->scatter_list[k]);
4770 kfree(h->scatter_list); 4781 kfree(h->scatter_list);
4771 cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds); 4782 cciss_free_sg_chain_blocks(h->cmd_sg_list, h->nr_cmds);