aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block/cciss.c
diff options
context:
space:
mode:
authorStephen M. Cameron <scameron@beardog.cce.hp.com>2010-07-19 14:46:43 -0400
committerJens Axboe <jaxboe@fusionio.com>2010-08-07 12:52:30 -0400
commit6b4d96b878d67c6768766e682c188a2a8bdc804a (patch)
treec879de9d10eb2b28e0d3f7382057206035a51734 /drivers/block/cciss.c
parentf70dba83669bf718c2f1731f0f58b8149e883593 (diff)
cciss: separate cmd_alloc() and cmd_special_alloc()
cciss: separate cmd_alloc() and cmd_special_alloc() cmd_alloc() took a parameter which caused it to either allocate from a pre-allocated pool, or allocate using pci_alloc_consistent. This parameter is always known at compile time, so this would be better handled by breaking the function into two functions and differentiating the cases by function names. Same goes for cmd_free(). Signed-off-by: Stephen M. Cameron <scameron@beardog.cce.hp.com> Signed-off-by: Jens Axboe <jaxboe@fusionio.com>
Diffstat (limited to 'drivers/block/cciss.c')
-rw-r--r--drivers/block/cciss.c153
1 files changed, 83 insertions, 70 deletions
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 70ad24f3604f..1dc95740b3bb 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -907,60 +907,73 @@ static void cciss_destroy_ld_sysfs_entry(struct ctlr_info *h, int drv_index,
907/* 907/*
908 * For operations that cannot sleep, a command block is allocated at init, 908 * For operations that cannot sleep, a command block is allocated at init,
909 * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track 909 * and managed by cmd_alloc() and cmd_free() using a simple bitmap to track
910 * which ones are free or in use. For operations that can wait for kmalloc 910 * which ones are free or in use.
911 * to possible sleep, this routine can be called with get_from_pool set to 0.
912 * cmd_free() MUST be called with a got_from_pool set to 0 if cmd_alloc was.
913 */ 911 */
914static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool) 912static CommandList_struct *cmd_alloc(ctlr_info_t *h)
915{ 913{
916 CommandList_struct *c; 914 CommandList_struct *c;
917 int i; 915 int i;
918 u64bit temp64; 916 u64bit temp64;
919 dma_addr_t cmd_dma_handle, err_dma_handle; 917 dma_addr_t cmd_dma_handle, err_dma_handle;
920 918
921 if (!get_from_pool) { 919 do {
922 c = (CommandList_struct *) pci_alloc_consistent(h->pdev, 920 i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds);
923 sizeof(CommandList_struct), &cmd_dma_handle); 921 if (i == h->nr_cmds)
924 if (c == NULL)
925 return NULL; 922 return NULL;
926 memset(c, 0, sizeof(CommandList_struct)); 923 } while (test_and_set_bit(i & (BITS_PER_LONG - 1),
924 h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0);
925#ifdef CCISS_DEBUG
926 printk(KERN_DEBUG "cciss: using command buffer %d\n", i);
927#endif
928 c = h->cmd_pool + i;
929 memset(c, 0, sizeof(CommandList_struct));
930 cmd_dma_handle = h->cmd_pool_dhandle + i * sizeof(CommandList_struct);
931 c->err_info = h->errinfo_pool + i;
932 memset(c->err_info, 0, sizeof(ErrorInfo_struct));
933 err_dma_handle = h->errinfo_pool_dhandle
934 + i * sizeof(ErrorInfo_struct);
935 h->nr_allocs++;
927 936
928 c->cmdindex = -1; 937 c->cmdindex = i;
929 938
930 c->err_info = (ErrorInfo_struct *) 939 INIT_HLIST_NODE(&c->list);
931 pci_alloc_consistent(h->pdev, sizeof(ErrorInfo_struct), 940 c->busaddr = (__u32) cmd_dma_handle;
932 &err_dma_handle); 941 temp64.val = (__u64) err_dma_handle;
942 c->ErrDesc.Addr.lower = temp64.val32.lower;
943 c->ErrDesc.Addr.upper = temp64.val32.upper;
944 c->ErrDesc.Len = sizeof(ErrorInfo_struct);
933 945
934 if (c->err_info == NULL) { 946 c->ctlr = h->ctlr;
935 pci_free_consistent(h->pdev, 947 return c;
936 sizeof(CommandList_struct), c, cmd_dma_handle); 948}
937 return NULL; 949
938 } 950/* allocate a command using pci_alloc_consistent, used for ioctls,
939 memset(c->err_info, 0, sizeof(ErrorInfo_struct)); 951 * etc., not for the main i/o path.
940 } else { /* get it out of the controllers pool */ 952 */
941 953static CommandList_struct *cmd_special_alloc(ctlr_info_t *h)
942 do { 954{
943 i = find_first_zero_bit(h->cmd_pool_bits, h->nr_cmds); 955 CommandList_struct *c;
944 if (i == h->nr_cmds) 956 u64bit temp64;
945 return NULL; 957 dma_addr_t cmd_dma_handle, err_dma_handle;
946 } while (test_and_set_bit 958
947 (i & (BITS_PER_LONG - 1), 959 c = (CommandList_struct *) pci_alloc_consistent(h->pdev,
948 h->cmd_pool_bits + (i / BITS_PER_LONG)) != 0); 960 sizeof(CommandList_struct), &cmd_dma_handle);
949#ifdef CCISS_DEBUG 961 if (c == NULL)
950 printk(KERN_DEBUG "cciss: using command buffer %d\n", i); 962 return NULL;
951#endif 963 memset(c, 0, sizeof(CommandList_struct));
952 c = h->cmd_pool + i; 964
953 memset(c, 0, sizeof(CommandList_struct)); 965 c->cmdindex = -1;
954 cmd_dma_handle = h->cmd_pool_dhandle 966
955 + i * sizeof(CommandList_struct); 967 c->err_info = (ErrorInfo_struct *)
956 c->err_info = h->errinfo_pool + i; 968 pci_alloc_consistent(h->pdev, sizeof(ErrorInfo_struct),
957 memset(c->err_info, 0, sizeof(ErrorInfo_struct)); 969 &err_dma_handle);
958 err_dma_handle = h->errinfo_pool_dhandle
959 + i * sizeof(ErrorInfo_struct);
960 h->nr_allocs++;
961 970
962 c->cmdindex = i; 971 if (c->err_info == NULL) {
972 pci_free_consistent(h->pdev,
973 sizeof(CommandList_struct), c, cmd_dma_handle);
974 return NULL;
963 } 975 }
976 memset(c->err_info, 0, sizeof(ErrorInfo_struct));
964 977
965 INIT_HLIST_NODE(&c->list); 978 INIT_HLIST_NODE(&c->list);
966 c->busaddr = (__u32) cmd_dma_handle; 979 c->busaddr = (__u32) cmd_dma_handle;
@@ -973,27 +986,26 @@ static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool)
973 return c; 986 return c;
974} 987}
975 988
976/* 989static void cmd_free(ctlr_info_t *h, CommandList_struct *c)
977 * Frees a command block that was previously allocated with cmd_alloc().
978 */
979static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool)
980{ 990{
981 int i; 991 int i;
992
993 i = c - h->cmd_pool;
994 clear_bit(i & (BITS_PER_LONG - 1),
995 h->cmd_pool_bits + (i / BITS_PER_LONG));
996 h->nr_frees++;
997}
998
999static void cmd_special_free(ctlr_info_t *h, CommandList_struct *c)
1000{
982 u64bit temp64; 1001 u64bit temp64;
983 1002
984 if (!got_from_pool) { 1003 temp64.val32.lower = c->ErrDesc.Addr.lower;
985 temp64.val32.lower = c->ErrDesc.Addr.lower; 1004 temp64.val32.upper = c->ErrDesc.Addr.upper;
986 temp64.val32.upper = c->ErrDesc.Addr.upper; 1005 pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct),
987 pci_free_consistent(h->pdev, sizeof(ErrorInfo_struct), 1006 c->err_info, (dma_addr_t) temp64.val);
988 c->err_info, (dma_addr_t) temp64.val); 1007 pci_free_consistent(h->pdev, sizeof(CommandList_struct),
989 pci_free_consistent(h->pdev, sizeof(CommandList_struct), 1008 c, (dma_addr_t) c->busaddr);
990 c, (dma_addr_t) c->busaddr);
991 } else {
992 i = c - h->cmd_pool;
993 clear_bit(i & (BITS_PER_LONG - 1),
994 h->cmd_pool_bits + (i / BITS_PER_LONG));
995 h->nr_frees++;
996 }
997} 1009}
998 1010
999static inline ctlr_info_t *get_host(struct gendisk *disk) 1011static inline ctlr_info_t *get_host(struct gendisk *disk)
@@ -1470,7 +1482,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
1470 } else { 1482 } else {
1471 memset(buff, 0, iocommand.buf_size); 1483 memset(buff, 0, iocommand.buf_size);
1472 } 1484 }
1473 c = cmd_alloc(h, 0); 1485 c = cmd_special_alloc(h);
1474 if (!c) { 1486 if (!c) {
1475 kfree(buff); 1487 kfree(buff);
1476 return -ENOMEM; 1488 return -ENOMEM;
@@ -1524,7 +1536,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
1524 if (copy_to_user 1536 if (copy_to_user
1525 (argp, &iocommand, sizeof(IOCTL_Command_struct))) { 1537 (argp, &iocommand, sizeof(IOCTL_Command_struct))) {
1526 kfree(buff); 1538 kfree(buff);
1527 cmd_free(h, c, 0); 1539 cmd_special_free(h, c);
1528 return -EFAULT; 1540 return -EFAULT;
1529 } 1541 }
1530 1542
@@ -1533,12 +1545,12 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
1533 if (copy_to_user 1545 if (copy_to_user
1534 (iocommand.buf, buff, iocommand.buf_size)) { 1546 (iocommand.buf, buff, iocommand.buf_size)) {
1535 kfree(buff); 1547 kfree(buff);
1536 cmd_free(h, c, 0); 1548 cmd_special_free(h, c);
1537 return -EFAULT; 1549 return -EFAULT;
1538 } 1550 }
1539 } 1551 }
1540 kfree(buff); 1552 kfree(buff);
1541 cmd_free(h, c, 0); 1553 cmd_special_free(h, c);
1542 return 0; 1554 return 0;
1543 } 1555 }
1544 case CCISS_BIG_PASSTHRU:{ 1556 case CCISS_BIG_PASSTHRU:{
@@ -1620,7 +1632,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
1620 data_ptr += sz; 1632 data_ptr += sz;
1621 sg_used++; 1633 sg_used++;
1622 } 1634 }
1623 c = cmd_alloc(h, 0); 1635 c = cmd_special_alloc(h);
1624 if (!c) { 1636 if (!c) {
1625 status = -ENOMEM; 1637 status = -ENOMEM;
1626 goto cleanup1; 1638 goto cleanup1;
@@ -1668,7 +1680,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
1668 /* Copy the error information out */ 1680 /* Copy the error information out */
1669 ioc->error_info = *(c->err_info); 1681 ioc->error_info = *(c->err_info);
1670 if (copy_to_user(argp, ioc, sizeof(*ioc))) { 1682 if (copy_to_user(argp, ioc, sizeof(*ioc))) {
1671 cmd_free(h, c, 0); 1683 cmd_special_free(h, c);
1672 status = -EFAULT; 1684 status = -EFAULT;
1673 goto cleanup1; 1685 goto cleanup1;
1674 } 1686 }
@@ -1678,14 +1690,14 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
1678 for (i = 0; i < sg_used; i++) { 1690 for (i = 0; i < sg_used; i++) {
1679 if (copy_to_user 1691 if (copy_to_user
1680 (ptr, buff[i], buff_size[i])) { 1692 (ptr, buff[i], buff_size[i])) {
1681 cmd_free(h, c, 0); 1693 cmd_special_free(h, c);
1682 status = -EFAULT; 1694 status = -EFAULT;
1683 goto cleanup1; 1695 goto cleanup1;
1684 } 1696 }
1685 ptr += buff_size[i]; 1697 ptr += buff_size[i];
1686 } 1698 }
1687 } 1699 }
1688 cmd_free(h, c, 0); 1700 cmd_special_free(h, c);
1689 status = 0; 1701 status = 0;
1690 cleanup1: 1702 cleanup1:
1691 if (buff) { 1703 if (buff) {
@@ -1813,7 +1825,7 @@ static void cciss_softirq_done(struct request *rq)
1813 blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO); 1825 blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO);
1814 1826
1815 spin_lock_irqsave(&h->lock, flags); 1827 spin_lock_irqsave(&h->lock, flags);
1816 cmd_free(h, c, 1); 1828 cmd_free(h, c);
1817 cciss_check_queues(h); 1829 cciss_check_queues(h);
1818 spin_unlock_irqrestore(&h->lock, flags); 1830 spin_unlock_irqrestore(&h->lock, flags);
1819} 1831}
@@ -2765,7 +2777,7 @@ static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size,
2765 CommandList_struct *c; 2777 CommandList_struct *c;
2766 int return_status; 2778 int return_status;
2767 2779
2768 c = cmd_alloc(h, 0); 2780 c = cmd_special_alloc(h);
2769 if (!c) 2781 if (!c)
2770 return -ENOMEM; 2782 return -ENOMEM;
2771 return_status = fill_cmd(h, c, cmd, buff, size, page_code, 2783 return_status = fill_cmd(h, c, cmd, buff, size, page_code,
@@ -2773,7 +2785,7 @@ static int sendcmd_withirq(ctlr_info_t *h, __u8 cmd, void *buff, size_t size,
2773 if (return_status == IO_OK) 2785 if (return_status == IO_OK)
2774 return_status = sendcmd_withirq_core(h, c, 1); 2786 return_status = sendcmd_withirq_core(h, c, 1);
2775 2787
2776 cmd_free(h, c, 0); 2788 cmd_special_free(h, c);
2777 return return_status; 2789 return return_status;
2778} 2790}
2779 2791
@@ -3240,7 +3252,8 @@ static void do_cciss_request(struct request_queue *q)
3240 3252
3241 BUG_ON(creq->nr_phys_segments > h->maxsgentries); 3253 BUG_ON(creq->nr_phys_segments > h->maxsgentries);
3242 3254
3243 if ((c = cmd_alloc(h, 1)) == NULL) 3255 c = cmd_alloc(h);
3256 if (!c)
3244 goto full; 3257 goto full;
3245 3258
3246 blk_start_request(creq); 3259 blk_start_request(creq);