diff options
Diffstat (limited to 'drivers/block/cciss.c')
-rw-r--r-- | drivers/block/cciss.c | 27 |
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"); | |||
66 | MODULE_VERSION("3.6.26"); | 65 | MODULE_VERSION("3.6.26"); |
67 | MODULE_LICENSE("GPL"); | 66 | MODULE_LICENSE("GPL"); |
68 | 67 | ||
68 | static DEFINE_MUTEX(cciss_mutex); | ||
69 | static int cciss_allow_hpsa; | 69 | static int cciss_allow_hpsa; |
70 | module_param(cciss_allow_hpsa, int, S_IRUGO|S_IWUSR); | 70 | module_param(cciss_allow_hpsa, int, S_IRUGO|S_IWUSR); |
71 | MODULE_PARM_DESC(cciss_allow_hpsa, | 71 | MODULE_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, | |||
4765 | clean4: | 4776 | clean4: |
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); |