aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2015-10-03 03:49:23 -0400
committerJens Axboe <axboe@fb.com>2015-10-09 12:40:36 -0400
commit3cf519b5a8d4d067e3de19736283c9414402d3a2 (patch)
treed4f3b2784f94befaa19552413e44cbb61b319535
parent90667892c5a78b47080359883a569a260e9e87ed (diff)
nvme: merge nvme_dev_start, nvme_dev_resume and nvme_async_probe
And give the resulting function a sensible name. This keeps all the error handling in a single place and will allow for further improvements to it. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Keith Busch <keith.busch@intel.com> Signed-off-by: Jens Axboe <axboe@fb.com>
-rw-r--r--drivers/block/nvme-core.c53
1 files changed, 20 insertions, 33 deletions
diff --git a/drivers/block/nvme-core.c b/drivers/block/nvme-core.c
index e03a95bd4ee4..61cfff34c3b8 100644
--- a/drivers/block/nvme-core.c
+++ b/drivers/block/nvme-core.c
@@ -87,6 +87,7 @@ static struct class *nvme_class;
87static int __nvme_reset(struct nvme_dev *dev); 87static int __nvme_reset(struct nvme_dev *dev);
88static int nvme_reset(struct nvme_dev *dev); 88static int nvme_reset(struct nvme_dev *dev);
89static int nvme_process_cq(struct nvme_queue *nvmeq); 89static int nvme_process_cq(struct nvme_queue *nvmeq);
90static void nvme_dead_ctrl(struct nvme_dev *dev);
90 91
91struct async_cmd_info { 92struct async_cmd_info {
92 struct kthread_work work; 93 struct kthread_work work;
@@ -2949,14 +2950,15 @@ static const struct file_operations nvme_dev_fops = {
2949 .compat_ioctl = nvme_dev_ioctl, 2950 .compat_ioctl = nvme_dev_ioctl,
2950}; 2951};
2951 2952
2952static int nvme_dev_start(struct nvme_dev *dev) 2953static void nvme_probe_work(struct work_struct *work)
2953{ 2954{
2954 int result; 2955 struct nvme_dev *dev = container_of(work, struct nvme_dev, probe_work);
2955 bool start_thread = false; 2956 bool start_thread = false;
2957 int result;
2956 2958
2957 result = nvme_dev_map(dev); 2959 result = nvme_dev_map(dev);
2958 if (result) 2960 if (result)
2959 return result; 2961 goto out;
2960 2962
2961 result = nvme_configure_admin_queue(dev); 2963 result = nvme_configure_admin_queue(dev);
2962 if (result) 2964 if (result)
@@ -2991,7 +2993,17 @@ static int nvme_dev_start(struct nvme_dev *dev)
2991 goto free_tags; 2993 goto free_tags;
2992 2994
2993 dev->event_limit = 1; 2995 dev->event_limit = 1;
2994 return result; 2996
2997 if (dev->online_queues < 2) {
2998 dev_warn(dev->dev, "IO queues not created\n");
2999 nvme_free_queues(dev, 1);
3000 nvme_dev_remove(dev);
3001 } else {
3002 nvme_unfreeze_queues(dev);
3003 nvme_dev_add(dev);
3004 }
3005
3006 return;
2995 3007
2996 free_tags: 3008 free_tags:
2997 nvme_dev_remove_admin(dev); 3009 nvme_dev_remove_admin(dev);
@@ -3003,7 +3015,9 @@ static int nvme_dev_start(struct nvme_dev *dev)
3003 nvme_dev_list_remove(dev); 3015 nvme_dev_list_remove(dev);
3004 unmap: 3016 unmap:
3005 nvme_dev_unmap(dev); 3017 nvme_dev_unmap(dev);
3006 return result; 3018 out:
3019 if (!work_busy(&dev->reset_work))
3020 nvme_dead_ctrl(dev);
3007} 3021}
3008 3022
3009static int nvme_remove_dead_ctrl(void *arg) 3023static int nvme_remove_dead_ctrl(void *arg)
@@ -3017,24 +3031,6 @@ static int nvme_remove_dead_ctrl(void *arg)
3017 return 0; 3031 return 0;
3018} 3032}
3019 3033
3020static int nvme_dev_resume(struct nvme_dev *dev)
3021{
3022 int ret;
3023
3024 ret = nvme_dev_start(dev);
3025 if (ret)
3026 return ret;
3027 if (dev->online_queues < 2) {
3028 dev_warn(dev->dev, "IO queues not created\n");
3029 nvme_free_queues(dev, 1);
3030 nvme_dev_remove(dev);
3031 } else {
3032 nvme_unfreeze_queues(dev);
3033 nvme_dev_add(dev);
3034 }
3035 return 0;
3036}
3037
3038static void nvme_dead_ctrl(struct nvme_dev *dev) 3034static void nvme_dead_ctrl(struct nvme_dev *dev)
3039{ 3035{
3040 dev_warn(dev->dev, "Device failed to resume\n"); 3036 dev_warn(dev->dev, "Device failed to resume\n");
@@ -3113,7 +3109,6 @@ static ssize_t nvme_sysfs_reset(struct device *dev,
3113} 3109}
3114static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset); 3110static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset);
3115 3111
3116static void nvme_async_probe(struct work_struct *work);
3117static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) 3112static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3118{ 3113{
3119 int node, result = -ENOMEM; 3114 int node, result = -ENOMEM;
@@ -3164,7 +3159,7 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3164 3159
3165 INIT_LIST_HEAD(&dev->node); 3160 INIT_LIST_HEAD(&dev->node);
3166 INIT_WORK(&dev->scan_work, nvme_dev_scan); 3161 INIT_WORK(&dev->scan_work, nvme_dev_scan);
3167 INIT_WORK(&dev->probe_work, nvme_async_probe); 3162 INIT_WORK(&dev->probe_work, nvme_probe_work);
3168 schedule_work(&dev->probe_work); 3163 schedule_work(&dev->probe_work);
3169 return 0; 3164 return 0;
3170 3165
@@ -3184,14 +3179,6 @@ static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id)
3184 return result; 3179 return result;
3185} 3180}
3186 3181
3187static void nvme_async_probe(struct work_struct *work)
3188{
3189 struct nvme_dev *dev = container_of(work, struct nvme_dev, probe_work);
3190
3191 if (nvme_dev_resume(dev) && !work_busy(&dev->reset_work))
3192 nvme_dead_ctrl(dev);
3193}
3194
3195static void nvme_reset_notify(struct pci_dev *pdev, bool prepare) 3182static void nvme_reset_notify(struct pci_dev *pdev, bool prepare)
3196{ 3183{
3197 struct nvme_dev *dev = pci_get_drvdata(pdev); 3184 struct nvme_dev *dev = pci_get_drvdata(pdev);