diff options
author | Christoph Hellwig <hch@lst.de> | 2015-10-03 03:49:23 -0400 |
---|---|---|
committer | Jens Axboe <axboe@fb.com> | 2015-10-09 12:40:36 -0400 |
commit | 3cf519b5a8d4d067e3de19736283c9414402d3a2 (patch) | |
tree | d4f3b2784f94befaa19552413e44cbb61b319535 | |
parent | 90667892c5a78b47080359883a569a260e9e87ed (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.c | 53 |
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; | |||
87 | static int __nvme_reset(struct nvme_dev *dev); | 87 | static int __nvme_reset(struct nvme_dev *dev); |
88 | static int nvme_reset(struct nvme_dev *dev); | 88 | static int nvme_reset(struct nvme_dev *dev); |
89 | static int nvme_process_cq(struct nvme_queue *nvmeq); | 89 | static int nvme_process_cq(struct nvme_queue *nvmeq); |
90 | static void nvme_dead_ctrl(struct nvme_dev *dev); | ||
90 | 91 | ||
91 | struct async_cmd_info { | 92 | struct 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 | ||
2952 | static int nvme_dev_start(struct nvme_dev *dev) | 2953 | static 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 | ||
3009 | static int nvme_remove_dead_ctrl(void *arg) | 3023 | static 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 | ||
3020 | static 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 | |||
3038 | static void nvme_dead_ctrl(struct nvme_dev *dev) | 3034 | static 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 | } |
3114 | static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset); | 3110 | static DEVICE_ATTR(reset_controller, S_IWUSR, NULL, nvme_sysfs_reset); |
3115 | 3111 | ||
3116 | static void nvme_async_probe(struct work_struct *work); | ||
3117 | static int nvme_probe(struct pci_dev *pdev, const struct pci_device_id *id) | 3112 | static 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 | ||
3187 | static 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 | |||
3195 | static void nvme_reset_notify(struct pci_dev *pdev, bool prepare) | 3182 | static 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); |