diff options
author | Stephen M. Cameron <scameron@beardog.cce.hp.com> | 2010-07-19 14:46:43 -0400 |
---|---|---|
committer | Jens Axboe <jaxboe@fusionio.com> | 2010-08-07 12:52:30 -0400 |
commit | 6b4d96b878d67c6768766e682c188a2a8bdc804a (patch) | |
tree | c879de9d10eb2b28e0d3f7382057206035a51734 /drivers/block/cciss.c | |
parent | f70dba83669bf718c2f1731f0f58b8149e883593 (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.c | 153 |
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 | */ |
914 | static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool) | 912 | static 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 | 953 | static 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 | /* | 989 | static void cmd_free(ctlr_info_t *h, CommandList_struct *c) |
977 | * Frees a command block that was previously allocated with cmd_alloc(). | ||
978 | */ | ||
979 | static 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 | |||
999 | static 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 | ||
999 | static inline ctlr_info_t *get_host(struct gendisk *disk) | 1011 | static 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); |