diff options
Diffstat (limited to 'drivers/block')
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 148 | ||||
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.h | 18 |
2 files changed, 154 insertions, 12 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index ce4e47dcc153..8517af8c0fcb 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -81,12 +81,17 @@ | |||
81 | /* Device instance number, incremented each time a device is probed. */ | 81 | /* Device instance number, incremented each time a device is probed. */ |
82 | static int instance; | 82 | static int instance; |
83 | 83 | ||
84 | struct list_head online_list; | ||
85 | struct list_head removing_list; | ||
86 | spinlock_t dev_lock; | ||
87 | |||
84 | /* | 88 | /* |
85 | * Global variable used to hold the major block device number | 89 | * Global variable used to hold the major block device number |
86 | * allocated in mtip_init(). | 90 | * allocated in mtip_init(). |
87 | */ | 91 | */ |
88 | static int mtip_major; | 92 | static int mtip_major; |
89 | static struct dentry *dfs_parent; | 93 | static struct dentry *dfs_parent; |
94 | static struct dentry *dfs_device_status; | ||
90 | 95 | ||
91 | static u32 cpu_use[NR_CPUS]; | 96 | static u32 cpu_use[NR_CPUS]; |
92 | 97 | ||
@@ -2707,6 +2712,100 @@ static ssize_t mtip_hw_show_status(struct device *dev, | |||
2707 | 2712 | ||
2708 | static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); | 2713 | static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); |
2709 | 2714 | ||
2715 | /* debugsfs entries */ | ||
2716 | |||
2717 | static ssize_t show_device_status(struct device_driver *drv, char *buf) | ||
2718 | { | ||
2719 | int size = 0; | ||
2720 | struct driver_data *dd, *tmp; | ||
2721 | unsigned long flags; | ||
2722 | char id_buf[42]; | ||
2723 | u16 status = 0; | ||
2724 | |||
2725 | spin_lock_irqsave(&dev_lock, flags); | ||
2726 | size += sprintf(&buf[size], "Devices Present:\n"); | ||
2727 | list_for_each_entry_safe(dd, tmp, &online_list, online_list) { | ||
2728 | if (dd && dd->pdev) { | ||
2729 | if (dd->port && | ||
2730 | dd->port->identify && | ||
2731 | dd->port->identify_valid) { | ||
2732 | strlcpy(id_buf, | ||
2733 | (char *) (dd->port->identify + 10), 21); | ||
2734 | status = *(dd->port->identify + 141); | ||
2735 | } else { | ||
2736 | memset(id_buf, 0, 42); | ||
2737 | status = 0; | ||
2738 | } | ||
2739 | |||
2740 | if (dd->port && | ||
2741 | test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) { | ||
2742 | size += sprintf(&buf[size], | ||
2743 | " device %s %s (ftl rebuild %d %%)\n", | ||
2744 | dev_name(&dd->pdev->dev), | ||
2745 | id_buf, | ||
2746 | status); | ||
2747 | } else { | ||
2748 | size += sprintf(&buf[size], | ||
2749 | " device %s %s\n", | ||
2750 | dev_name(&dd->pdev->dev), | ||
2751 | id_buf); | ||
2752 | } | ||
2753 | } | ||
2754 | } | ||
2755 | |||
2756 | size += sprintf(&buf[size], "Devices Being Removed:\n"); | ||
2757 | list_for_each_entry_safe(dd, tmp, &removing_list, remove_list) { | ||
2758 | if (dd && dd->pdev) { | ||
2759 | if (dd->port && | ||
2760 | dd->port->identify && | ||
2761 | dd->port->identify_valid) { | ||
2762 | strlcpy(id_buf, | ||
2763 | (char *) (dd->port->identify+10), 21); | ||
2764 | status = *(dd->port->identify + 141); | ||
2765 | } else { | ||
2766 | memset(id_buf, 0, 42); | ||
2767 | status = 0; | ||
2768 | } | ||
2769 | |||
2770 | if (dd->port && | ||
2771 | test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) { | ||
2772 | size += sprintf(&buf[size], | ||
2773 | " device %s %s (ftl rebuild %d %%)\n", | ||
2774 | dev_name(&dd->pdev->dev), | ||
2775 | id_buf, | ||
2776 | status); | ||
2777 | } else { | ||
2778 | size += sprintf(&buf[size], | ||
2779 | " device %s %s\n", | ||
2780 | dev_name(&dd->pdev->dev), | ||
2781 | id_buf); | ||
2782 | } | ||
2783 | } | ||
2784 | } | ||
2785 | spin_unlock_irqrestore(&dev_lock, flags); | ||
2786 | |||
2787 | return size; | ||
2788 | } | ||
2789 | |||
2790 | static ssize_t mtip_hw_read_device_status(struct file *f, char __user *ubuf, | ||
2791 | size_t len, loff_t *offset) | ||
2792 | { | ||
2793 | int size = *offset; | ||
2794 | char buf[MTIP_DFS_MAX_BUF_SIZE]; | ||
2795 | |||
2796 | if (!len || *offset) | ||
2797 | return 0; | ||
2798 | |||
2799 | size += show_device_status(NULL, buf); | ||
2800 | |||
2801 | *offset = size <= len ? size : len; | ||
2802 | size = copy_to_user(ubuf, buf, *offset); | ||
2803 | if (size) | ||
2804 | return -EFAULT; | ||
2805 | |||
2806 | return *offset; | ||
2807 | } | ||
2808 | |||
2710 | static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, | 2809 | static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, |
2711 | size_t len, loff_t *offset) | 2810 | size_t len, loff_t *offset) |
2712 | { | 2811 | { |
@@ -2801,6 +2900,13 @@ static ssize_t mtip_hw_read_flags(struct file *f, char __user *ubuf, | |||
2801 | return *offset; | 2900 | return *offset; |
2802 | } | 2901 | } |
2803 | 2902 | ||
2903 | static const struct file_operations mtip_device_status_fops = { | ||
2904 | .owner = THIS_MODULE, | ||
2905 | .open = simple_open, | ||
2906 | .read = mtip_hw_read_device_status, | ||
2907 | .llseek = no_llseek, | ||
2908 | }; | ||
2909 | |||
2804 | static const struct file_operations mtip_regs_fops = { | 2910 | static const struct file_operations mtip_regs_fops = { |
2805 | .owner = THIS_MODULE, | 2911 | .owner = THIS_MODULE, |
2806 | .open = simple_open, | 2912 | .open = simple_open, |
@@ -4158,6 +4264,7 @@ static int mtip_pci_probe(struct pci_dev *pdev, | |||
4158 | const struct cpumask *node_mask; | 4264 | const struct cpumask *node_mask; |
4159 | int cpu, i = 0, j = 0; | 4265 | int cpu, i = 0, j = 0; |
4160 | int my_node = NUMA_NO_NODE; | 4266 | int my_node = NUMA_NO_NODE; |
4267 | unsigned long flags; | ||
4161 | 4268 | ||
4162 | /* Allocate memory for this devices private data. */ | 4269 | /* Allocate memory for this devices private data. */ |
4163 | my_node = pcibus_to_node(pdev->bus); | 4270 | my_node = pcibus_to_node(pdev->bus); |
@@ -4215,6 +4322,9 @@ static int mtip_pci_probe(struct pci_dev *pdev, | |||
4215 | dd->pdev = pdev; | 4322 | dd->pdev = pdev; |
4216 | dd->numa_node = my_node; | 4323 | dd->numa_node = my_node; |
4217 | 4324 | ||
4325 | INIT_LIST_HEAD(&dd->online_list); | ||
4326 | INIT_LIST_HEAD(&dd->remove_list); | ||
4327 | |||
4218 | memset(dd->workq_name, 0, 32); | 4328 | memset(dd->workq_name, 0, 32); |
4219 | snprintf(dd->workq_name, 31, "mtipq%d", dd->instance); | 4329 | snprintf(dd->workq_name, 31, "mtipq%d", dd->instance); |
4220 | 4330 | ||
@@ -4304,6 +4414,12 @@ static int mtip_pci_probe(struct pci_dev *pdev, | |||
4304 | set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); | 4414 | set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); |
4305 | else | 4415 | else |
4306 | rv = 0; /* device in rebuild state, return 0 from probe */ | 4416 | rv = 0; /* device in rebuild state, return 0 from probe */ |
4417 | |||
4418 | /* Add to online list even if in ftl rebuild */ | ||
4419 | spin_lock_irqsave(&dev_lock, flags); | ||
4420 | list_add(&dd->online_list, &online_list); | ||
4421 | spin_unlock_irqrestore(&dev_lock, flags); | ||
4422 | |||
4307 | goto done; | 4423 | goto done; |
4308 | 4424 | ||
4309 | block_initialize_err: | 4425 | block_initialize_err: |
@@ -4337,9 +4453,15 @@ static void mtip_pci_remove(struct pci_dev *pdev) | |||
4337 | { | 4453 | { |
4338 | struct driver_data *dd = pci_get_drvdata(pdev); | 4454 | struct driver_data *dd = pci_get_drvdata(pdev); |
4339 | int counter = 0; | 4455 | int counter = 0; |
4456 | unsigned long flags; | ||
4340 | 4457 | ||
4341 | set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); | 4458 | set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); |
4342 | 4459 | ||
4460 | spin_lock_irqsave(&dev_lock, flags); | ||
4461 | list_del_init(&dd->online_list); | ||
4462 | list_add(&dd->remove_list, &removing_list); | ||
4463 | spin_unlock_irqrestore(&dev_lock, flags); | ||
4464 | |||
4343 | if (mtip_check_surprise_removal(pdev)) { | 4465 | if (mtip_check_surprise_removal(pdev)) { |
4344 | while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { | 4466 | while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { |
4345 | counter++; | 4467 | counter++; |
@@ -4365,6 +4487,10 @@ static void mtip_pci_remove(struct pci_dev *pdev) | |||
4365 | 4487 | ||
4366 | pci_disable_msi(pdev); | 4488 | pci_disable_msi(pdev); |
4367 | 4489 | ||
4490 | spin_lock_irqsave(&dev_lock, flags); | ||
4491 | list_del_init(&dd->remove_list); | ||
4492 | spin_unlock_irqrestore(&dev_lock, flags); | ||
4493 | |||
4368 | kfree(dd); | 4494 | kfree(dd); |
4369 | pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); | 4495 | pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); |
4370 | } | 4496 | } |
@@ -4512,6 +4638,11 @@ static int __init mtip_init(void) | |||
4512 | 4638 | ||
4513 | pr_info(MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n"); | 4639 | pr_info(MTIP_DRV_NAME " Version " MTIP_DRV_VERSION "\n"); |
4514 | 4640 | ||
4641 | spin_lock_init(&dev_lock); | ||
4642 | |||
4643 | INIT_LIST_HEAD(&online_list); | ||
4644 | INIT_LIST_HEAD(&removing_list); | ||
4645 | |||
4515 | /* Allocate a major block device number to use with this driver. */ | 4646 | /* Allocate a major block device number to use with this driver. */ |
4516 | error = register_blkdev(0, MTIP_DRV_NAME); | 4647 | error = register_blkdev(0, MTIP_DRV_NAME); |
4517 | if (error <= 0) { | 4648 | if (error <= 0) { |
@@ -4521,11 +4652,18 @@ static int __init mtip_init(void) | |||
4521 | } | 4652 | } |
4522 | mtip_major = error; | 4653 | mtip_major = error; |
4523 | 4654 | ||
4524 | if (!dfs_parent) { | 4655 | dfs_parent = debugfs_create_dir("rssd", NULL); |
4525 | dfs_parent = debugfs_create_dir("rssd", NULL); | 4656 | if (IS_ERR_OR_NULL(dfs_parent)) { |
4526 | if (IS_ERR_OR_NULL(dfs_parent)) { | 4657 | pr_warn("Error creating debugfs parent\n"); |
4527 | pr_warn("Error creating debugfs parent\n"); | 4658 | dfs_parent = NULL; |
4528 | dfs_parent = NULL; | 4659 | } |
4660 | if (dfs_parent) { | ||
4661 | dfs_device_status = debugfs_create_file("device_status", | ||
4662 | S_IRUGO, dfs_parent, NULL, | ||
4663 | &mtip_device_status_fops); | ||
4664 | if (IS_ERR_OR_NULL(dfs_device_status)) { | ||
4665 | pr_err("Error creating device_status node\n"); | ||
4666 | dfs_device_status = NULL; | ||
4529 | } | 4667 | } |
4530 | } | 4668 | } |
4531 | 4669 | ||
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 3bffff5f670c..8e8334c9dd0f 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
@@ -129,9 +129,9 @@ enum { | |||
129 | MTIP_PF_EH_ACTIVE_BIT = 1, /* error handling */ | 129 | MTIP_PF_EH_ACTIVE_BIT = 1, /* error handling */ |
130 | MTIP_PF_SE_ACTIVE_BIT = 2, /* secure erase */ | 130 | MTIP_PF_SE_ACTIVE_BIT = 2, /* secure erase */ |
131 | MTIP_PF_DM_ACTIVE_BIT = 3, /* download microcde */ | 131 | MTIP_PF_DM_ACTIVE_BIT = 3, /* download microcde */ |
132 | MTIP_PF_PAUSE_IO = ((1 << MTIP_PF_IC_ACTIVE_BIT) | \ | 132 | MTIP_PF_PAUSE_IO = ((1 << MTIP_PF_IC_ACTIVE_BIT) | |
133 | (1 << MTIP_PF_EH_ACTIVE_BIT) | \ | 133 | (1 << MTIP_PF_EH_ACTIVE_BIT) | |
134 | (1 << MTIP_PF_SE_ACTIVE_BIT) | \ | 134 | (1 << MTIP_PF_SE_ACTIVE_BIT) | |
135 | (1 << MTIP_PF_DM_ACTIVE_BIT)), | 135 | (1 << MTIP_PF_DM_ACTIVE_BIT)), |
136 | 136 | ||
137 | MTIP_PF_SVC_THD_ACTIVE_BIT = 4, | 137 | MTIP_PF_SVC_THD_ACTIVE_BIT = 4, |
@@ -144,9 +144,9 @@ enum { | |||
144 | MTIP_DDF_REMOVE_PENDING_BIT = 1, | 144 | MTIP_DDF_REMOVE_PENDING_BIT = 1, |
145 | MTIP_DDF_OVER_TEMP_BIT = 2, | 145 | MTIP_DDF_OVER_TEMP_BIT = 2, |
146 | MTIP_DDF_WRITE_PROTECT_BIT = 3, | 146 | MTIP_DDF_WRITE_PROTECT_BIT = 3, |
147 | MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | \ | 147 | MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | |
148 | (1 << MTIP_DDF_SEC_LOCK_BIT) | \ | 148 | (1 << MTIP_DDF_SEC_LOCK_BIT) | |
149 | (1 << MTIP_DDF_OVER_TEMP_BIT) | \ | 149 | (1 << MTIP_DDF_OVER_TEMP_BIT) | |
150 | (1 << MTIP_DDF_WRITE_PROTECT_BIT)), | 150 | (1 << MTIP_DDF_WRITE_PROTECT_BIT)), |
151 | 151 | ||
152 | MTIP_DDF_CLEANUP_BIT = 5, | 152 | MTIP_DDF_CLEANUP_BIT = 5, |
@@ -180,7 +180,7 @@ struct mtip_work { | |||
180 | 180 | ||
181 | #define MTIP_TRIM_TIMEOUT_MS 240000 | 181 | #define MTIP_TRIM_TIMEOUT_MS 240000 |
182 | #define MTIP_MAX_TRIM_ENTRIES 8 | 182 | #define MTIP_MAX_TRIM_ENTRIES 8 |
183 | #define MTIP_MAX_TRIM_ENTRY_LEN 0xfff8 | 183 | #define MTIP_MAX_TRIM_ENTRY_LEN 0xfff8 |
184 | 184 | ||
185 | struct mtip_trim_entry { | 185 | struct mtip_trim_entry { |
186 | u32 lba; /* starting lba of region */ | 186 | u32 lba; /* starting lba of region */ |
@@ -501,6 +501,10 @@ struct driver_data { | |||
501 | atomic_t irq_workers_active; | 501 | atomic_t irq_workers_active; |
502 | 502 | ||
503 | int isr_binding; | 503 | int isr_binding; |
504 | |||
505 | struct list_head online_list; /* linkage for online list */ | ||
506 | |||
507 | struct list_head remove_list; /* linkage for removing list */ | ||
504 | }; | 508 | }; |
505 | 509 | ||
506 | #endif | 510 | #endif |