aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/block
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block')
-rw-r--r--drivers/block/mtip32xx/mtip32xx.c148
-rw-r--r--drivers/block/mtip32xx/mtip32xx.h18
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. */
82static int instance; 82static int instance;
83 83
84struct list_head online_list;
85struct list_head removing_list;
86spinlock_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 */
88static int mtip_major; 92static int mtip_major;
89static struct dentry *dfs_parent; 93static struct dentry *dfs_parent;
94static struct dentry *dfs_device_status;
90 95
91static u32 cpu_use[NR_CPUS]; 96static u32 cpu_use[NR_CPUS];
92 97
@@ -2707,6 +2712,100 @@ static ssize_t mtip_hw_show_status(struct device *dev,
2707 2712
2708static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL); 2713static DEVICE_ATTR(status, S_IRUGO, mtip_hw_show_status, NULL);
2709 2714
2715/* debugsfs entries */
2716
2717static 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
2790static 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
2710static ssize_t mtip_hw_read_registers(struct file *f, char __user *ubuf, 2809static 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
2903static 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
2804static const struct file_operations mtip_regs_fops = { 2910static 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
4309block_initialize_err: 4425block_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
185struct mtip_trim_entry { 185struct 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