diff options
Diffstat (limited to 'drivers/scsi/hosts.c')
-rw-r--r-- | drivers/scsi/hosts.c | 50 |
1 files changed, 38 insertions, 12 deletions
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 3cbb57a8b846..6de80e352871 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -204,18 +204,33 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, | |||
204 | struct scsi_host_template *sht = shost->hostt; | 204 | struct scsi_host_template *sht = shost->hostt; |
205 | int error = -EINVAL; | 205 | int error = -EINVAL; |
206 | 206 | ||
207 | printk(KERN_INFO "scsi%d : %s\n", shost->host_no, | 207 | shost_printk(KERN_INFO, shost, "%s\n", |
208 | sht->info ? sht->info(shost) : sht->name); | 208 | sht->info ? sht->info(shost) : sht->name); |
209 | 209 | ||
210 | if (!shost->can_queue) { | 210 | if (!shost->can_queue) { |
211 | printk(KERN_ERR "%s: can_queue = 0 no longer supported\n", | 211 | shost_printk(KERN_ERR, shost, |
212 | sht->name); | 212 | "can_queue = 0 no longer supported\n"); |
213 | goto fail; | 213 | goto fail; |
214 | } | 214 | } |
215 | 215 | ||
216 | if (shost_use_blk_mq(shost)) { | ||
217 | error = scsi_mq_setup_tags(shost); | ||
218 | if (error) | ||
219 | goto fail; | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * Note that we allocate the freelist even for the MQ case for now, | ||
224 | * as we need a command set aside for scsi_reset_provider. Having | ||
225 | * the full host freelist and one command available for that is a | ||
226 | * little heavy-handed, but avoids introducing a special allocator | ||
227 | * just for this. Eventually the structure of scsi_reset_provider | ||
228 | * will need a major overhaul. | ||
229 | */ | ||
216 | error = scsi_setup_command_freelist(shost); | 230 | error = scsi_setup_command_freelist(shost); |
217 | if (error) | 231 | if (error) |
218 | goto fail; | 232 | goto out_destroy_tags; |
233 | |||
219 | 234 | ||
220 | if (!shost->shost_gendev.parent) | 235 | if (!shost->shost_gendev.parent) |
221 | shost->shost_gendev.parent = dev ? dev : &platform_bus; | 236 | shost->shost_gendev.parent = dev ? dev : &platform_bus; |
@@ -226,7 +241,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, | |||
226 | 241 | ||
227 | error = device_add(&shost->shost_gendev); | 242 | error = device_add(&shost->shost_gendev); |
228 | if (error) | 243 | if (error) |
229 | goto out; | 244 | goto out_destroy_freelist; |
230 | 245 | ||
231 | pm_runtime_set_active(&shost->shost_gendev); | 246 | pm_runtime_set_active(&shost->shost_gendev); |
232 | pm_runtime_enable(&shost->shost_gendev); | 247 | pm_runtime_enable(&shost->shost_gendev); |
@@ -279,8 +294,11 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, | |||
279 | device_del(&shost->shost_dev); | 294 | device_del(&shost->shost_dev); |
280 | out_del_gendev: | 295 | out_del_gendev: |
281 | device_del(&shost->shost_gendev); | 296 | device_del(&shost->shost_gendev); |
282 | out: | 297 | out_destroy_freelist: |
283 | scsi_destroy_command_freelist(shost); | 298 | scsi_destroy_command_freelist(shost); |
299 | out_destroy_tags: | ||
300 | if (shost_use_blk_mq(shost)) | ||
301 | scsi_mq_destroy_tags(shost); | ||
284 | fail: | 302 | fail: |
285 | return error; | 303 | return error; |
286 | } | 304 | } |
@@ -309,8 +327,13 @@ static void scsi_host_dev_release(struct device *dev) | |||
309 | } | 327 | } |
310 | 328 | ||
311 | scsi_destroy_command_freelist(shost); | 329 | scsi_destroy_command_freelist(shost); |
312 | if (shost->bqt) | 330 | if (shost_use_blk_mq(shost)) { |
313 | blk_free_tags(shost->bqt); | 331 | if (shost->tag_set.tags) |
332 | scsi_mq_destroy_tags(shost); | ||
333 | } else { | ||
334 | if (shost->bqt) | ||
335 | blk_free_tags(shost->bqt); | ||
336 | } | ||
314 | 337 | ||
315 | kfree(shost->shost_data); | 338 | kfree(shost->shost_data); |
316 | 339 | ||
@@ -436,6 +459,8 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
436 | else | 459 | else |
437 | shost->dma_boundary = 0xffffffff; | 460 | shost->dma_boundary = 0xffffffff; |
438 | 461 | ||
462 | shost->use_blk_mq = scsi_use_blk_mq && !shost->hostt->disable_blk_mq; | ||
463 | |||
439 | device_initialize(&shost->shost_gendev); | 464 | device_initialize(&shost->shost_gendev); |
440 | dev_set_name(&shost->shost_gendev, "host%d", shost->host_no); | 465 | dev_set_name(&shost->shost_gendev, "host%d", shost->host_no); |
441 | shost->shost_gendev.bus = &scsi_bus_type; | 466 | shost->shost_gendev.bus = &scsi_bus_type; |
@@ -450,8 +475,9 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
450 | shost->ehandler = kthread_run(scsi_error_handler, shost, | 475 | shost->ehandler = kthread_run(scsi_error_handler, shost, |
451 | "scsi_eh_%d", shost->host_no); | 476 | "scsi_eh_%d", shost->host_no); |
452 | if (IS_ERR(shost->ehandler)) { | 477 | if (IS_ERR(shost->ehandler)) { |
453 | printk(KERN_WARNING "scsi%d: error handler thread failed to spawn, error = %ld\n", | 478 | shost_printk(KERN_WARNING, shost, |
454 | shost->host_no, PTR_ERR(shost->ehandler)); | 479 | "error handler thread failed to spawn, error = %ld\n", |
480 | PTR_ERR(shost->ehandler)); | ||
455 | goto fail_kfree; | 481 | goto fail_kfree; |
456 | } | 482 | } |
457 | 483 | ||
@@ -584,7 +610,7 @@ EXPORT_SYMBOL(scsi_is_host_device); | |||
584 | int scsi_queue_work(struct Scsi_Host *shost, struct work_struct *work) | 610 | int scsi_queue_work(struct Scsi_Host *shost, struct work_struct *work) |
585 | { | 611 | { |
586 | if (unlikely(!shost->work_q)) { | 612 | if (unlikely(!shost->work_q)) { |
587 | printk(KERN_ERR | 613 | shost_printk(KERN_ERR, shost, |
588 | "ERROR: Scsi host '%s' attempted to queue scsi-work, " | 614 | "ERROR: Scsi host '%s' attempted to queue scsi-work, " |
589 | "when no workqueue created.\n", shost->hostt->name); | 615 | "when no workqueue created.\n", shost->hostt->name); |
590 | dump_stack(); | 616 | dump_stack(); |
@@ -603,7 +629,7 @@ EXPORT_SYMBOL_GPL(scsi_queue_work); | |||
603 | void scsi_flush_work(struct Scsi_Host *shost) | 629 | void scsi_flush_work(struct Scsi_Host *shost) |
604 | { | 630 | { |
605 | if (!shost->work_q) { | 631 | if (!shost->work_q) { |
606 | printk(KERN_ERR | 632 | shost_printk(KERN_ERR, shost, |
607 | "ERROR: Scsi host '%s' attempted to flush scsi-work, " | 633 | "ERROR: Scsi host '%s' attempted to flush scsi-work, " |
608 | "when no workqueue created.\n", shost->hostt->name); | 634 | "when no workqueue created.\n", shost->hostt->name); |
609 | dump_stack(); | 635 | dump_stack(); |