aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/cciss.c153
-rw-r--r--drivers/block/cciss_scsi.c10
2 files changed, 89 insertions, 74 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);
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
index 9133ad4c7b1b..9fe0d8ffc90d 100644
--- a/drivers/block/cciss_scsi.c
+++ b/drivers/block/cciss_scsi.c
@@ -49,8 +49,10 @@ static int fill_cmd(ctlr_info_t *h, CommandList_struct *c, __u8 cmd, void *buff,
49 __u8 page_code, unsigned char *scsi3addr, 49 __u8 page_code, unsigned char *scsi3addr,
50 int cmd_type); 50 int cmd_type);
51 51
52static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool); 52static CommandList_struct *cmd_alloc(ctlr_info_t *h);
53static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool); 53static CommandList_struct *cmd_special_alloc(ctlr_info_t *h);
54static void cmd_free(ctlr_info_t *h, CommandList_struct *c);
55static void cmd_special_free(ctlr_info_t *h, CommandList_struct *c);
54 56
55static int cciss_scsi_proc_info( 57static int cciss_scsi_proc_info(
56 struct Scsi_Host *sh, 58 struct Scsi_Host *sh,
@@ -1582,7 +1584,7 @@ static int wait_for_device_to_become_ready(ctlr_info_t *h,
1582 int waittime = HZ; 1584 int waittime = HZ;
1583 CommandList_struct *c; 1585 CommandList_struct *c;
1584 1586
1585 c = cmd_alloc(h, 1); 1587 c = cmd_alloc(h);
1586 if (!c) { 1588 if (!c) {
1587 printk(KERN_WARNING "cciss%d: out of memory in " 1589 printk(KERN_WARNING "cciss%d: out of memory in "
1588 "wait_for_device_to_become_ready.\n", h->ctlr); 1590 "wait_for_device_to_become_ready.\n", h->ctlr);
@@ -1640,7 +1642,7 @@ retry_tur:
1640 else 1642 else
1641 printk(KERN_WARNING "cciss%d: device is ready.\n", h->ctlr); 1643 printk(KERN_WARNING "cciss%d: device is ready.\n", h->ctlr);
1642 1644
1643 cmd_free(h, c, 1); 1645 cmd_free(h, c);
1644 return rc; 1646 return rc;
1645} 1647}
1646 1648