diff options
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.c | 453 | ||||
-rw-r--r-- | drivers/block/mtip32xx/mtip32xx.h | 18 |
2 files changed, 289 insertions, 182 deletions
diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index 952dbfe22126..76f3bc4f0c21 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c | |||
@@ -126,64 +126,30 @@ struct mtip_compat_ide_task_request_s { | |||
126 | static bool mtip_check_surprise_removal(struct pci_dev *pdev) | 126 | static bool mtip_check_surprise_removal(struct pci_dev *pdev) |
127 | { | 127 | { |
128 | u16 vendor_id = 0; | 128 | u16 vendor_id = 0; |
129 | struct driver_data *dd = pci_get_drvdata(pdev); | ||
130 | |||
131 | if (dd->sr) | ||
132 | return true; | ||
129 | 133 | ||
130 | /* Read the vendorID from the configuration space */ | 134 | /* Read the vendorID from the configuration space */ |
131 | pci_read_config_word(pdev, 0x00, &vendor_id); | 135 | pci_read_config_word(pdev, 0x00, &vendor_id); |
132 | if (vendor_id == 0xFFFF) | 136 | if (vendor_id == 0xFFFF) { |
137 | dd->sr = true; | ||
138 | if (dd->queue) | ||
139 | set_bit(QUEUE_FLAG_DEAD, &dd->queue->queue_flags); | ||
140 | else | ||
141 | dev_warn(&dd->pdev->dev, | ||
142 | "%s: dd->queue is NULL\n", __func__); | ||
143 | if (dd->port) { | ||
144 | set_bit(MTIP_PF_SR_CLEANUP_BIT, &dd->port->flags); | ||
145 | wake_up_interruptible(&dd->port->svc_wait); | ||
146 | } else | ||
147 | dev_warn(&dd->pdev->dev, | ||
148 | "%s: dd->port is NULL\n", __func__); | ||
133 | return true; /* device removed */ | 149 | return true; /* device removed */ |
134 | |||
135 | return false; /* device present */ | ||
136 | } | ||
137 | |||
138 | /* | ||
139 | * This function is called for clean the pending command in the | ||
140 | * command slot during the surprise removal of device and return | ||
141 | * error to the upper layer. | ||
142 | * | ||
143 | * @dd Pointer to the DRIVER_DATA structure. | ||
144 | * | ||
145 | * return value | ||
146 | * None | ||
147 | */ | ||
148 | static void mtip_command_cleanup(struct driver_data *dd) | ||
149 | { | ||
150 | int group = 0, commandslot = 0, commandindex = 0; | ||
151 | struct mtip_cmd *command; | ||
152 | struct mtip_port *port = dd->port; | ||
153 | static int in_progress; | ||
154 | |||
155 | if (in_progress) | ||
156 | return; | ||
157 | |||
158 | in_progress = 1; | ||
159 | |||
160 | for (group = 0; group < 4; group++) { | ||
161 | for (commandslot = 0; commandslot < 32; commandslot++) { | ||
162 | if (!(port->allocated[group] & (1 << commandslot))) | ||
163 | continue; | ||
164 | |||
165 | commandindex = group << 5 | commandslot; | ||
166 | command = &port->commands[commandindex]; | ||
167 | |||
168 | if (atomic_read(&command->active) | ||
169 | && (command->async_callback)) { | ||
170 | command->async_callback(command->async_data, | ||
171 | -ENODEV); | ||
172 | command->async_callback = NULL; | ||
173 | command->async_data = NULL; | ||
174 | } | ||
175 | |||
176 | dma_unmap_sg(&port->dd->pdev->dev, | ||
177 | command->sg, | ||
178 | command->scatter_ents, | ||
179 | command->direction); | ||
180 | } | ||
181 | } | 150 | } |
182 | 151 | ||
183 | up(&port->cmd_slot); | 152 | return false; /* device present */ |
184 | |||
185 | set_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag); | ||
186 | in_progress = 0; | ||
187 | } | 153 | } |
188 | 154 | ||
189 | /* | 155 | /* |
@@ -222,10 +188,7 @@ static int get_slot(struct mtip_port *port) | |||
222 | } | 188 | } |
223 | dev_warn(&port->dd->pdev->dev, "Failed to get a tag.\n"); | 189 | dev_warn(&port->dd->pdev->dev, "Failed to get a tag.\n"); |
224 | 190 | ||
225 | if (mtip_check_surprise_removal(port->dd->pdev)) { | 191 | mtip_check_surprise_removal(port->dd->pdev); |
226 | /* Device not present, clean outstanding commands */ | ||
227 | mtip_command_cleanup(port->dd); | ||
228 | } | ||
229 | return -1; | 192 | return -1; |
230 | } | 193 | } |
231 | 194 | ||
@@ -246,6 +209,107 @@ static inline void release_slot(struct mtip_port *port, int tag) | |||
246 | } | 209 | } |
247 | 210 | ||
248 | /* | 211 | /* |
212 | * IO completion function. | ||
213 | * | ||
214 | * This completion function is called by the driver ISR when a | ||
215 | * command that was issued by the kernel completes. It first calls the | ||
216 | * asynchronous completion function which normally calls back into the block | ||
217 | * layer passing the asynchronous callback data, then unmaps the | ||
218 | * scatter list associated with the completed command, and finally | ||
219 | * clears the allocated bit associated with the completed command. | ||
220 | * | ||
221 | * @port Pointer to the port data structure. | ||
222 | * @tag Tag of the command. | ||
223 | * @data Pointer to driver_data. | ||
224 | * @status Completion status. | ||
225 | * | ||
226 | * return value | ||
227 | * None | ||
228 | */ | ||
229 | static void mtip_async_complete(struct mtip_port *port, | ||
230 | int tag, | ||
231 | void *data, | ||
232 | int status) | ||
233 | { | ||
234 | struct mtip_cmd *command; | ||
235 | struct driver_data *dd = data; | ||
236 | int cb_status = status ? -EIO : 0; | ||
237 | |||
238 | if (unlikely(!dd) || unlikely(!port)) | ||
239 | return; | ||
240 | |||
241 | command = &port->commands[tag]; | ||
242 | |||
243 | if (unlikely(status == PORT_IRQ_TF_ERR)) { | ||
244 | dev_warn(&port->dd->pdev->dev, | ||
245 | "Command tag %d failed due to TFE\n", tag); | ||
246 | } | ||
247 | |||
248 | /* Upper layer callback */ | ||
249 | if (likely(command->async_callback)) | ||
250 | command->async_callback(command->async_data, cb_status); | ||
251 | |||
252 | command->async_callback = NULL; | ||
253 | command->comp_func = NULL; | ||
254 | |||
255 | /* Unmap the DMA scatter list entries */ | ||
256 | dma_unmap_sg(&dd->pdev->dev, | ||
257 | command->sg, | ||
258 | command->scatter_ents, | ||
259 | command->direction); | ||
260 | |||
261 | /* Clear the allocated and active bits for the command */ | ||
262 | atomic_set(&port->commands[tag].active, 0); | ||
263 | release_slot(port, tag); | ||
264 | |||
265 | up(&port->cmd_slot); | ||
266 | } | ||
267 | |||
268 | /* | ||
269 | * This function is called for clean the pending command in the | ||
270 | * command slot during the surprise removal of device and return | ||
271 | * error to the upper layer. | ||
272 | * | ||
273 | * @dd Pointer to the DRIVER_DATA structure. | ||
274 | * | ||
275 | * return value | ||
276 | * None | ||
277 | */ | ||
278 | static void mtip_command_cleanup(struct driver_data *dd) | ||
279 | { | ||
280 | int tag = 0; | ||
281 | struct mtip_cmd *cmd; | ||
282 | struct mtip_port *port = dd->port; | ||
283 | unsigned int num_cmd_slots = dd->slot_groups * 32; | ||
284 | |||
285 | if (!test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) | ||
286 | return; | ||
287 | |||
288 | if (!port) | ||
289 | return; | ||
290 | |||
291 | cmd = &port->commands[MTIP_TAG_INTERNAL]; | ||
292 | if (atomic_read(&cmd->active)) | ||
293 | if (readl(port->cmd_issue[MTIP_TAG_INTERNAL]) & | ||
294 | (1 << MTIP_TAG_INTERNAL)) | ||
295 | if (cmd->comp_func) | ||
296 | cmd->comp_func(port, MTIP_TAG_INTERNAL, | ||
297 | cmd->comp_data, -ENODEV); | ||
298 | |||
299 | while (1) { | ||
300 | tag = find_next_bit(port->allocated, num_cmd_slots, tag); | ||
301 | if (tag >= num_cmd_slots) | ||
302 | break; | ||
303 | |||
304 | cmd = &port->commands[tag]; | ||
305 | if (atomic_read(&cmd->active)) | ||
306 | mtip_async_complete(port, tag, dd, -ENODEV); | ||
307 | } | ||
308 | |||
309 | set_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag); | ||
310 | } | ||
311 | |||
312 | /* | ||
249 | * Reset the HBA (without sleeping) | 313 | * Reset the HBA (without sleeping) |
250 | * | 314 | * |
251 | * @dd Pointer to the driver data structure. | 315 | * @dd Pointer to the driver data structure. |
@@ -584,6 +648,9 @@ static void mtip_timeout_function(unsigned long int data) | |||
584 | if (unlikely(!port)) | 648 | if (unlikely(!port)) |
585 | return; | 649 | return; |
586 | 650 | ||
651 | if (unlikely(port->dd->sr)) | ||
652 | return; | ||
653 | |||
587 | if (test_bit(MTIP_DDF_RESUME_BIT, &port->dd->dd_flag)) { | 654 | if (test_bit(MTIP_DDF_RESUME_BIT, &port->dd->dd_flag)) { |
588 | mod_timer(&port->cmd_timer, | 655 | mod_timer(&port->cmd_timer, |
589 | jiffies + msecs_to_jiffies(30000)); | 656 | jiffies + msecs_to_jiffies(30000)); |
@@ -675,66 +742,6 @@ static void mtip_timeout_function(unsigned long int data) | |||
675 | } | 742 | } |
676 | 743 | ||
677 | /* | 744 | /* |
678 | * IO completion function. | ||
679 | * | ||
680 | * This completion function is called by the driver ISR when a | ||
681 | * command that was issued by the kernel completes. It first calls the | ||
682 | * asynchronous completion function which normally calls back into the block | ||
683 | * layer passing the asynchronous callback data, then unmaps the | ||
684 | * scatter list associated with the completed command, and finally | ||
685 | * clears the allocated bit associated with the completed command. | ||
686 | * | ||
687 | * @port Pointer to the port data structure. | ||
688 | * @tag Tag of the command. | ||
689 | * @data Pointer to driver_data. | ||
690 | * @status Completion status. | ||
691 | * | ||
692 | * return value | ||
693 | * None | ||
694 | */ | ||
695 | static void mtip_async_complete(struct mtip_port *port, | ||
696 | int tag, | ||
697 | void *data, | ||
698 | int status) | ||
699 | { | ||
700 | struct mtip_cmd *command; | ||
701 | struct driver_data *dd = data; | ||
702 | int cb_status = status ? -EIO : 0; | ||
703 | |||
704 | if (unlikely(!dd) || unlikely(!port)) | ||
705 | return; | ||
706 | |||
707 | command = &port->commands[tag]; | ||
708 | |||
709 | if (unlikely(status == PORT_IRQ_TF_ERR)) { | ||
710 | dev_warn(&port->dd->pdev->dev, | ||
711 | "Command tag %d failed due to TFE\n", tag); | ||
712 | } | ||
713 | |||
714 | /* Upper layer callback */ | ||
715 | if (likely(command->async_callback)) | ||
716 | command->async_callback(command->async_data, cb_status); | ||
717 | |||
718 | command->async_callback = NULL; | ||
719 | command->comp_func = NULL; | ||
720 | |||
721 | /* Unmap the DMA scatter list entries */ | ||
722 | dma_unmap_sg(&dd->pdev->dev, | ||
723 | command->sg, | ||
724 | command->scatter_ents, | ||
725 | command->direction); | ||
726 | |||
727 | /* Clear the allocated and active bits for the command */ | ||
728 | atomic_set(&port->commands[tag].active, 0); | ||
729 | release_slot(port, tag); | ||
730 | |||
731 | if (unlikely(command->unaligned)) | ||
732 | up(&port->cmd_slot_unal); | ||
733 | else | ||
734 | up(&port->cmd_slot); | ||
735 | } | ||
736 | |||
737 | /* | ||
738 | * Internal command completion callback function. | 745 | * Internal command completion callback function. |
739 | * | 746 | * |
740 | * This function is normally called by the driver ISR when an internal | 747 | * This function is normally called by the driver ISR when an internal |
@@ -854,7 +861,6 @@ static void mtip_handle_tfe(struct driver_data *dd) | |||
854 | "Missing completion func for tag %d", | 861 | "Missing completion func for tag %d", |
855 | tag); | 862 | tag); |
856 | if (mtip_check_surprise_removal(dd->pdev)) { | 863 | if (mtip_check_surprise_removal(dd->pdev)) { |
857 | mtip_command_cleanup(dd); | ||
858 | /* don't proceed further */ | 864 | /* don't proceed further */ |
859 | return; | 865 | return; |
860 | } | 866 | } |
@@ -1018,14 +1024,12 @@ static inline void mtip_workq_sdbfx(struct mtip_port *port, int group, | |||
1018 | command->comp_data, | 1024 | command->comp_data, |
1019 | 0); | 1025 | 0); |
1020 | } else { | 1026 | } else { |
1021 | dev_warn(&dd->pdev->dev, | 1027 | dev_dbg(&dd->pdev->dev, |
1022 | "Null completion " | 1028 | "Null completion for tag %d", |
1023 | "for tag %d", | ||
1024 | tag); | 1029 | tag); |
1025 | 1030 | ||
1026 | if (mtip_check_surprise_removal( | 1031 | if (mtip_check_surprise_removal( |
1027 | dd->pdev)) { | 1032 | dd->pdev)) { |
1028 | mtip_command_cleanup(dd); | ||
1029 | return; | 1033 | return; |
1030 | } | 1034 | } |
1031 | } | 1035 | } |
@@ -1145,7 +1149,6 @@ static inline irqreturn_t mtip_handle_irq(struct driver_data *data) | |||
1145 | 1149 | ||
1146 | if (unlikely(port_stat & PORT_IRQ_ERR)) { | 1150 | if (unlikely(port_stat & PORT_IRQ_ERR)) { |
1147 | if (unlikely(mtip_check_surprise_removal(dd->pdev))) { | 1151 | if (unlikely(mtip_check_surprise_removal(dd->pdev))) { |
1148 | mtip_command_cleanup(dd); | ||
1149 | /* don't proceed further */ | 1152 | /* don't proceed further */ |
1150 | return IRQ_HANDLED; | 1153 | return IRQ_HANDLED; |
1151 | } | 1154 | } |
@@ -3006,6 +3009,46 @@ static void mtip_hw_debugfs_exit(struct driver_data *dd) | |||
3006 | debugfs_remove_recursive(dd->dfs_node); | 3009 | debugfs_remove_recursive(dd->dfs_node); |
3007 | } | 3010 | } |
3008 | 3011 | ||
3012 | static int mtip_free_orphan(struct driver_data *dd) | ||
3013 | { | ||
3014 | struct kobject *kobj; | ||
3015 | |||
3016 | if (dd->bdev) { | ||
3017 | if (dd->bdev->bd_holders >= 1) | ||
3018 | return -2; | ||
3019 | |||
3020 | bdput(dd->bdev); | ||
3021 | dd->bdev = NULL; | ||
3022 | } | ||
3023 | |||
3024 | mtip_hw_debugfs_exit(dd); | ||
3025 | |||
3026 | spin_lock(&rssd_index_lock); | ||
3027 | ida_remove(&rssd_index_ida, dd->index); | ||
3028 | spin_unlock(&rssd_index_lock); | ||
3029 | |||
3030 | if (!test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag) && | ||
3031 | test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag)) { | ||
3032 | put_disk(dd->disk); | ||
3033 | } else { | ||
3034 | if (dd->disk) { | ||
3035 | kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); | ||
3036 | if (kobj) { | ||
3037 | mtip_hw_sysfs_exit(dd, kobj); | ||
3038 | kobject_put(kobj); | ||
3039 | } | ||
3040 | del_gendisk(dd->disk); | ||
3041 | dd->disk = NULL; | ||
3042 | } | ||
3043 | if (dd->queue) { | ||
3044 | dd->queue->queuedata = NULL; | ||
3045 | blk_cleanup_queue(dd->queue); | ||
3046 | dd->queue = NULL; | ||
3047 | } | ||
3048 | } | ||
3049 | kfree(dd); | ||
3050 | return 0; | ||
3051 | } | ||
3009 | 3052 | ||
3010 | /* | 3053 | /* |
3011 | * Perform any init/resume time hardware setup | 3054 | * Perform any init/resume time hardware setup |
@@ -3154,6 +3197,7 @@ static int mtip_service_thread(void *data) | |||
3154 | unsigned long slot, slot_start, slot_wrap; | 3197 | unsigned long slot, slot_start, slot_wrap; |
3155 | unsigned int num_cmd_slots = dd->slot_groups * 32; | 3198 | unsigned int num_cmd_slots = dd->slot_groups * 32; |
3156 | struct mtip_port *port = dd->port; | 3199 | struct mtip_port *port = dd->port; |
3200 | int ret; | ||
3157 | 3201 | ||
3158 | while (1) { | 3202 | while (1) { |
3159 | /* | 3203 | /* |
@@ -3164,13 +3208,18 @@ static int mtip_service_thread(void *data) | |||
3164 | !(port->flags & MTIP_PF_PAUSE_IO)); | 3208 | !(port->flags & MTIP_PF_PAUSE_IO)); |
3165 | 3209 | ||
3166 | if (kthread_should_stop()) | 3210 | if (kthread_should_stop()) |
3211 | goto st_out; | ||
3212 | |||
3213 | set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); | ||
3214 | |||
3215 | /* If I am an orphan, start self cleanup */ | ||
3216 | if (test_bit(MTIP_PF_SR_CLEANUP_BIT, &port->flags)) | ||
3167 | break; | 3217 | break; |
3168 | 3218 | ||
3169 | if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, | 3219 | if (unlikely(test_bit(MTIP_DDF_REMOVE_PENDING_BIT, |
3170 | &dd->dd_flag))) | 3220 | &dd->dd_flag))) |
3171 | break; | 3221 | goto st_out; |
3172 | 3222 | ||
3173 | set_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); | ||
3174 | if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { | 3223 | if (test_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags)) { |
3175 | slot = 1; | 3224 | slot = 1; |
3176 | /* used to restrict the loop to one iteration */ | 3225 | /* used to restrict the loop to one iteration */ |
@@ -3201,7 +3250,7 @@ static int mtip_service_thread(void *data) | |||
3201 | 3250 | ||
3202 | clear_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); | 3251 | clear_bit(MTIP_PF_ISSUE_CMDS_BIT, &port->flags); |
3203 | } else if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) { | 3252 | } else if (test_bit(MTIP_PF_REBUILD_BIT, &port->flags)) { |
3204 | if (!mtip_ftl_rebuild_poll(dd)) | 3253 | if (mtip_ftl_rebuild_poll(dd) < 0) |
3205 | set_bit(MTIP_DDF_REBUILD_FAILED_BIT, | 3254 | set_bit(MTIP_DDF_REBUILD_FAILED_BIT, |
3206 | &dd->dd_flag); | 3255 | &dd->dd_flag); |
3207 | clear_bit(MTIP_PF_REBUILD_BIT, &port->flags); | 3256 | clear_bit(MTIP_PF_REBUILD_BIT, &port->flags); |
@@ -3209,8 +3258,30 @@ static int mtip_service_thread(void *data) | |||
3209 | clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); | 3258 | clear_bit(MTIP_PF_SVC_THD_ACTIVE_BIT, &port->flags); |
3210 | 3259 | ||
3211 | if (test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags)) | 3260 | if (test_bit(MTIP_PF_SVC_THD_STOP_BIT, &port->flags)) |
3261 | goto st_out; | ||
3262 | } | ||
3263 | |||
3264 | /* wait for pci remove to exit */ | ||
3265 | while (1) { | ||
3266 | if (test_bit(MTIP_DDF_REMOVE_DONE_BIT, &dd->dd_flag)) | ||
3212 | break; | 3267 | break; |
3268 | msleep_interruptible(1000); | ||
3269 | if (kthread_should_stop()) | ||
3270 | goto st_out; | ||
3213 | } | 3271 | } |
3272 | |||
3273 | while (1) { | ||
3274 | ret = mtip_free_orphan(dd); | ||
3275 | if (!ret) { | ||
3276 | /* NOTE: All data structures are invalid, do not | ||
3277 | * access any here */ | ||
3278 | return 0; | ||
3279 | } | ||
3280 | msleep_interruptible(1000); | ||
3281 | if (kthread_should_stop()) | ||
3282 | goto st_out; | ||
3283 | } | ||
3284 | st_out: | ||
3214 | return 0; | 3285 | return 0; |
3215 | } | 3286 | } |
3216 | 3287 | ||
@@ -3437,13 +3508,13 @@ static int mtip_hw_init(struct driver_data *dd) | |||
3437 | rv = -EFAULT; | 3508 | rv = -EFAULT; |
3438 | goto out3; | 3509 | goto out3; |
3439 | } | 3510 | } |
3511 | mtip_dump_identify(dd->port); | ||
3440 | 3512 | ||
3441 | if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == | 3513 | if (*(dd->port->identify + MTIP_FTL_REBUILD_OFFSET) == |
3442 | MTIP_FTL_REBUILD_MAGIC) { | 3514 | MTIP_FTL_REBUILD_MAGIC) { |
3443 | set_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags); | 3515 | set_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags); |
3444 | return MTIP_FTL_REBUILD_MAGIC; | 3516 | return MTIP_FTL_REBUILD_MAGIC; |
3445 | } | 3517 | } |
3446 | mtip_dump_identify(dd->port); | ||
3447 | 3518 | ||
3448 | /* check write protect, over temp and rebuild statuses */ | 3519 | /* check write protect, over temp and rebuild statuses */ |
3449 | rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ, | 3520 | rv = mtip_read_log_page(dd->port, ATA_LOG_SATA_NCQ, |
@@ -3467,8 +3538,8 @@ static int mtip_hw_init(struct driver_data *dd) | |||
3467 | } | 3538 | } |
3468 | if (buf[288] == 0xBF) { | 3539 | if (buf[288] == 0xBF) { |
3469 | dev_info(&dd->pdev->dev, | 3540 | dev_info(&dd->pdev->dev, |
3470 | "Drive indicates rebuild has failed.\n"); | 3541 | "Drive is in security locked state.\n"); |
3471 | /* TODO */ | 3542 | set_bit(MTIP_DDF_SEC_LOCK_BIT, &dd->dd_flag); |
3472 | } | 3543 | } |
3473 | } | 3544 | } |
3474 | 3545 | ||
@@ -3523,9 +3594,8 @@ static int mtip_hw_exit(struct driver_data *dd) | |||
3523 | * Send standby immediate (E0h) to the drive so that it | 3594 | * Send standby immediate (E0h) to the drive so that it |
3524 | * saves its state. | 3595 | * saves its state. |
3525 | */ | 3596 | */ |
3526 | if (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { | 3597 | if (!dd->sr) { |
3527 | 3598 | if (!test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag)) | |
3528 | if (!test_bit(MTIP_PF_REBUILD_BIT, &dd->port->flags)) | ||
3529 | if (mtip_standby_immediate(dd->port)) | 3599 | if (mtip_standby_immediate(dd->port)) |
3530 | dev_warn(&dd->pdev->dev, | 3600 | dev_warn(&dd->pdev->dev, |
3531 | "STANDBY IMMEDIATE failed\n"); | 3601 | "STANDBY IMMEDIATE failed\n"); |
@@ -3551,6 +3621,7 @@ static int mtip_hw_exit(struct driver_data *dd) | |||
3551 | dd->port->command_list_dma); | 3621 | dd->port->command_list_dma); |
3552 | /* Free the memory allocated for the for structure. */ | 3622 | /* Free the memory allocated for the for structure. */ |
3553 | kfree(dd->port); | 3623 | kfree(dd->port); |
3624 | dd->port = NULL; | ||
3554 | 3625 | ||
3555 | return 0; | 3626 | return 0; |
3556 | } | 3627 | } |
@@ -3572,7 +3643,8 @@ static int mtip_hw_shutdown(struct driver_data *dd) | |||
3572 | * Send standby immediate (E0h) to the drive so that it | 3643 | * Send standby immediate (E0h) to the drive so that it |
3573 | * saves its state. | 3644 | * saves its state. |
3574 | */ | 3645 | */ |
3575 | mtip_standby_immediate(dd->port); | 3646 | if (!dd->sr && dd->port) |
3647 | mtip_standby_immediate(dd->port); | ||
3576 | 3648 | ||
3577 | return 0; | 3649 | return 0; |
3578 | } | 3650 | } |
@@ -3887,6 +3959,10 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) | |||
3887 | bio_endio(bio, -ENODATA); | 3959 | bio_endio(bio, -ENODATA); |
3888 | return; | 3960 | return; |
3889 | } | 3961 | } |
3962 | if (test_bit(MTIP_DDF_REBUILD_FAILED_BIT, &dd->dd_flag)) { | ||
3963 | bio_endio(bio, -ENXIO); | ||
3964 | return; | ||
3965 | } | ||
3890 | } | 3966 | } |
3891 | 3967 | ||
3892 | if (unlikely(bio->bi_rw & REQ_DISCARD)) { | 3968 | if (unlikely(bio->bi_rw & REQ_DISCARD)) { |
@@ -4010,6 +4086,8 @@ static int mtip_block_initialize(struct driver_data *dd) | |||
4010 | dd->disk->private_data = dd; | 4086 | dd->disk->private_data = dd; |
4011 | dd->index = index; | 4087 | dd->index = index; |
4012 | 4088 | ||
4089 | mtip_hw_debugfs_init(dd); | ||
4090 | |||
4013 | /* | 4091 | /* |
4014 | * if rebuild pending, start the service thread, and delay the block | 4092 | * if rebuild pending, start the service thread, and delay the block |
4015 | * queue creation and add_disk() | 4093 | * queue creation and add_disk() |
@@ -4068,6 +4146,7 @@ skip_create_disk: | |||
4068 | /* Enable the block device and add it to /dev */ | 4146 | /* Enable the block device and add it to /dev */ |
4069 | add_disk(dd->disk); | 4147 | add_disk(dd->disk); |
4070 | 4148 | ||
4149 | dd->bdev = bdget_disk(dd->disk, 0); | ||
4071 | /* | 4150 | /* |
4072 | * Now that the disk is active, initialize any sysfs attributes | 4151 | * Now that the disk is active, initialize any sysfs attributes |
4073 | * managed by the protocol layer. | 4152 | * managed by the protocol layer. |
@@ -4077,7 +4156,6 @@ skip_create_disk: | |||
4077 | mtip_hw_sysfs_init(dd, kobj); | 4156 | mtip_hw_sysfs_init(dd, kobj); |
4078 | kobject_put(kobj); | 4157 | kobject_put(kobj); |
4079 | } | 4158 | } |
4080 | mtip_hw_debugfs_init(dd); | ||
4081 | 4159 | ||
4082 | if (dd->mtip_svc_handler) { | 4160 | if (dd->mtip_svc_handler) { |
4083 | set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); | 4161 | set_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag); |
@@ -4103,7 +4181,8 @@ start_service_thread: | |||
4103 | return rv; | 4181 | return rv; |
4104 | 4182 | ||
4105 | kthread_run_error: | 4183 | kthread_run_error: |
4106 | mtip_hw_debugfs_exit(dd); | 4184 | bdput(dd->bdev); |
4185 | dd->bdev = NULL; | ||
4107 | 4186 | ||
4108 | /* Delete our gendisk. This also removes the device from /dev */ | 4187 | /* Delete our gendisk. This also removes the device from /dev */ |
4109 | del_gendisk(dd->disk); | 4188 | del_gendisk(dd->disk); |
@@ -4112,6 +4191,7 @@ read_capacity_error: | |||
4112 | blk_cleanup_queue(dd->queue); | 4191 | blk_cleanup_queue(dd->queue); |
4113 | 4192 | ||
4114 | block_queue_alloc_init_error: | 4193 | block_queue_alloc_init_error: |
4194 | mtip_hw_debugfs_exit(dd); | ||
4115 | disk_index_error: | 4195 | disk_index_error: |
4116 | spin_lock(&rssd_index_lock); | 4196 | spin_lock(&rssd_index_lock); |
4117 | ida_remove(&rssd_index_ida, index); | 4197 | ida_remove(&rssd_index_ida, index); |
@@ -4141,40 +4221,48 @@ static int mtip_block_remove(struct driver_data *dd) | |||
4141 | { | 4221 | { |
4142 | struct kobject *kobj; | 4222 | struct kobject *kobj; |
4143 | 4223 | ||
4144 | if (dd->mtip_svc_handler) { | 4224 | if (!dd->sr) { |
4145 | set_bit(MTIP_PF_SVC_THD_STOP_BIT, &dd->port->flags); | 4225 | mtip_hw_debugfs_exit(dd); |
4146 | wake_up_interruptible(&dd->port->svc_wait); | ||
4147 | kthread_stop(dd->mtip_svc_handler); | ||
4148 | } | ||
4149 | 4226 | ||
4150 | /* Clean up the sysfs attributes, if created */ | 4227 | if (dd->mtip_svc_handler) { |
4151 | if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) { | 4228 | set_bit(MTIP_PF_SVC_THD_STOP_BIT, &dd->port->flags); |
4152 | kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); | 4229 | wake_up_interruptible(&dd->port->svc_wait); |
4153 | if (kobj) { | 4230 | kthread_stop(dd->mtip_svc_handler); |
4154 | mtip_hw_sysfs_exit(dd, kobj); | ||
4155 | kobject_put(kobj); | ||
4156 | } | 4231 | } |
4157 | } | ||
4158 | mtip_hw_debugfs_exit(dd); | ||
4159 | 4232 | ||
4160 | /* | 4233 | /* Clean up the sysfs attributes, if created */ |
4161 | * Delete our gendisk structure. This also removes the device | 4234 | if (test_bit(MTIP_DDF_INIT_DONE_BIT, &dd->dd_flag)) { |
4162 | * from /dev | 4235 | kobj = kobject_get(&disk_to_dev(dd->disk)->kobj); |
4163 | */ | 4236 | if (kobj) { |
4164 | if (dd->disk) { | 4237 | mtip_hw_sysfs_exit(dd, kobj); |
4165 | if (dd->disk->queue) | 4238 | kobject_put(kobj); |
4166 | del_gendisk(dd->disk); | 4239 | } |
4167 | else | 4240 | } |
4168 | put_disk(dd->disk); | 4241 | /* |
4169 | } | 4242 | * Delete our gendisk structure. This also removes the device |
4170 | 4243 | * from /dev | |
4171 | spin_lock(&rssd_index_lock); | 4244 | */ |
4172 | ida_remove(&rssd_index_ida, dd->index); | 4245 | if (dd->bdev) { |
4173 | spin_unlock(&rssd_index_lock); | 4246 | bdput(dd->bdev); |
4247 | dd->bdev = NULL; | ||
4248 | } | ||
4249 | if (dd->disk) { | ||
4250 | if (dd->disk->queue) { | ||
4251 | del_gendisk(dd->disk); | ||
4252 | blk_cleanup_queue(dd->queue); | ||
4253 | dd->queue = NULL; | ||
4254 | } else | ||
4255 | put_disk(dd->disk); | ||
4256 | } | ||
4257 | dd->disk = NULL; | ||
4174 | 4258 | ||
4175 | blk_cleanup_queue(dd->queue); | 4259 | spin_lock(&rssd_index_lock); |
4176 | dd->disk = NULL; | 4260 | ida_remove(&rssd_index_ida, dd->index); |
4177 | dd->queue = NULL; | 4261 | spin_unlock(&rssd_index_lock); |
4262 | } else { | ||
4263 | dev_info(&dd->pdev->dev, "device %s surprise removal\n", | ||
4264 | dd->disk->disk_name); | ||
4265 | } | ||
4178 | 4266 | ||
4179 | /* De-initialize the protocol layer. */ | 4267 | /* De-initialize the protocol layer. */ |
4180 | mtip_hw_exit(dd); | 4268 | mtip_hw_exit(dd); |
@@ -4490,8 +4578,7 @@ done: | |||
4490 | static void mtip_pci_remove(struct pci_dev *pdev) | 4578 | static void mtip_pci_remove(struct pci_dev *pdev) |
4491 | { | 4579 | { |
4492 | struct driver_data *dd = pci_get_drvdata(pdev); | 4580 | struct driver_data *dd = pci_get_drvdata(pdev); |
4493 | int counter = 0; | 4581 | unsigned long flags, to; |
4494 | unsigned long flags; | ||
4495 | 4582 | ||
4496 | set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); | 4583 | set_bit(MTIP_DDF_REMOVE_PENDING_BIT, &dd->dd_flag); |
4497 | 4584 | ||
@@ -4500,17 +4587,22 @@ static void mtip_pci_remove(struct pci_dev *pdev) | |||
4500 | list_add(&dd->remove_list, &removing_list); | 4587 | list_add(&dd->remove_list, &removing_list); |
4501 | spin_unlock_irqrestore(&dev_lock, flags); | 4588 | spin_unlock_irqrestore(&dev_lock, flags); |
4502 | 4589 | ||
4503 | if (mtip_check_surprise_removal(pdev)) { | 4590 | mtip_check_surprise_removal(pdev); |
4504 | while (!test_bit(MTIP_DDF_CLEANUP_BIT, &dd->dd_flag)) { | 4591 | synchronize_irq(dd->pdev->irq); |
4505 | counter++; | 4592 | |
4506 | msleep(20); | 4593 | /* Spin until workers are done */ |
4507 | if (counter == 10) { | 4594 | to = jiffies + msecs_to_jiffies(4000); |
4508 | /* Cleanup the outstanding commands */ | 4595 | do { |
4509 | mtip_command_cleanup(dd); | 4596 | msleep(20); |
4510 | break; | 4597 | } while (atomic_read(&dd->irq_workers_active) != 0 && |
4511 | } | 4598 | time_before(jiffies, to)); |
4512 | } | 4599 | |
4600 | if (atomic_read(&dd->irq_workers_active) != 0) { | ||
4601 | dev_warn(&dd->pdev->dev, | ||
4602 | "Completion workers still active!\n"); | ||
4513 | } | 4603 | } |
4604 | /* Cleanup the outstanding commands */ | ||
4605 | mtip_command_cleanup(dd); | ||
4514 | 4606 | ||
4515 | /* Clean up the block layer. */ | 4607 | /* Clean up the block layer. */ |
4516 | mtip_block_remove(dd); | 4608 | mtip_block_remove(dd); |
@@ -4529,8 +4621,15 @@ static void mtip_pci_remove(struct pci_dev *pdev) | |||
4529 | list_del_init(&dd->remove_list); | 4621 | list_del_init(&dd->remove_list); |
4530 | spin_unlock_irqrestore(&dev_lock, flags); | 4622 | spin_unlock_irqrestore(&dev_lock, flags); |
4531 | 4623 | ||
4532 | kfree(dd); | 4624 | if (!dd->sr) |
4625 | kfree(dd); | ||
4626 | else | ||
4627 | set_bit(MTIP_DDF_REMOVE_DONE_BIT, &dd->dd_flag); | ||
4628 | |||
4533 | pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); | 4629 | pcim_iounmap_regions(pdev, 1 << MTIP_ABAR); |
4630 | pci_set_drvdata(pdev, NULL); | ||
4631 | pci_dev_put(pdev); | ||
4632 | |||
4534 | } | 4633 | } |
4535 | 4634 | ||
4536 | /* | 4635 | /* |
diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 3bb8a295fbe4..9be7a1582ad3 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h | |||
@@ -140,6 +140,7 @@ enum { | |||
140 | MTIP_PF_SVC_THD_ACTIVE_BIT = 4, | 140 | MTIP_PF_SVC_THD_ACTIVE_BIT = 4, |
141 | MTIP_PF_ISSUE_CMDS_BIT = 5, | 141 | MTIP_PF_ISSUE_CMDS_BIT = 5, |
142 | MTIP_PF_REBUILD_BIT = 6, | 142 | MTIP_PF_REBUILD_BIT = 6, |
143 | MTIP_PF_SR_CLEANUP_BIT = 7, | ||
143 | MTIP_PF_SVC_THD_STOP_BIT = 8, | 144 | MTIP_PF_SVC_THD_STOP_BIT = 8, |
144 | 145 | ||
145 | /* below are bit numbers in 'dd_flag' defined in driver_data */ | 146 | /* below are bit numbers in 'dd_flag' defined in driver_data */ |
@@ -147,15 +148,18 @@ enum { | |||
147 | MTIP_DDF_REMOVE_PENDING_BIT = 1, | 148 | MTIP_DDF_REMOVE_PENDING_BIT = 1, |
148 | MTIP_DDF_OVER_TEMP_BIT = 2, | 149 | MTIP_DDF_OVER_TEMP_BIT = 2, |
149 | MTIP_DDF_WRITE_PROTECT_BIT = 3, | 150 | MTIP_DDF_WRITE_PROTECT_BIT = 3, |
150 | MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | | 151 | MTIP_DDF_REMOVE_DONE_BIT = 4, |
151 | (1 << MTIP_DDF_SEC_LOCK_BIT) | | ||
152 | (1 << MTIP_DDF_OVER_TEMP_BIT) | | ||
153 | (1 << MTIP_DDF_WRITE_PROTECT_BIT)), | ||
154 | |||
155 | MTIP_DDF_CLEANUP_BIT = 5, | 152 | MTIP_DDF_CLEANUP_BIT = 5, |
156 | MTIP_DDF_RESUME_BIT = 6, | 153 | MTIP_DDF_RESUME_BIT = 6, |
157 | MTIP_DDF_INIT_DONE_BIT = 7, | 154 | MTIP_DDF_INIT_DONE_BIT = 7, |
158 | MTIP_DDF_REBUILD_FAILED_BIT = 8, | 155 | MTIP_DDF_REBUILD_FAILED_BIT = 8, |
156 | |||
157 | MTIP_DDF_STOP_IO = ((1 << MTIP_DDF_REMOVE_PENDING_BIT) | | ||
158 | (1 << MTIP_DDF_SEC_LOCK_BIT) | | ||
159 | (1 << MTIP_DDF_OVER_TEMP_BIT) | | ||
160 | (1 << MTIP_DDF_WRITE_PROTECT_BIT) | | ||
161 | (1 << MTIP_DDF_REBUILD_FAILED_BIT)), | ||
162 | |||
159 | }; | 163 | }; |
160 | 164 | ||
161 | struct smart_attr { | 165 | struct smart_attr { |
@@ -499,6 +503,8 @@ struct driver_data { | |||
499 | 503 | ||
500 | bool trim_supp; /* flag indicating trim support */ | 504 | bool trim_supp; /* flag indicating trim support */ |
501 | 505 | ||
506 | bool sr; | ||
507 | |||
502 | int numa_node; /* NUMA support */ | 508 | int numa_node; /* NUMA support */ |
503 | 509 | ||
504 | char workq_name[32]; | 510 | char workq_name[32]; |
@@ -511,6 +517,8 @@ struct driver_data { | |||
511 | 517 | ||
512 | int isr_binding; | 518 | int isr_binding; |
513 | 519 | ||
520 | struct block_device *bdev; | ||
521 | |||
514 | int unal_qdepth; /* qdepth of unaligned IO queue */ | 522 | int unal_qdepth; /* qdepth of unaligned IO queue */ |
515 | 523 | ||
516 | struct list_head online_list; /* linkage for online list */ | 524 | struct list_head online_list; /* linkage for online list */ |