当前位置:   article > 正文

pm8001_pci_probe函数分析之scsi_scan_host(一)_scsi scan host

scsi scan host

接着分析pm8001_pci_probe中调用到的scsi_scan_host函数下面是scsi_scan_host的代码

  1. /**
  2. * scsi_scan_host - scan the given adapter
  3. * @shost: adapter to scan
  4. **/
  5. void scsi_scan_host(struct Scsi_Host *shost)
  6. {
  7. struct task_struct *p;
  8. struct async_scan_data *data;
  9. if (strncmp(scsi_scan_type, "none", 4) == 0)
  10. return;
  11. data = scsi_prep_async_scan(shost);
  12. if (!data) {
  13. do_scsi_scan_host(shost);
  14. return;
  15. }
  16. p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
  17. if (IS_ERR(p))
  18. do_scan_async(data);
  19. }
下面看一下scsi_scan_type是什么,显然它的值是字符串 "async"或者"sync

  1. #ifdef CONFIG_SCSI_SCAN_ASYNC
  2. #define SCSI_SCAN_TYPE_DEFAULT "async"
  3. #else
  4. #define SCSI_SCAN_TYPE_DEFAULT "sync"
  5. #endif
scsi_scan_type[6]=SCSI_SCAN_TYPE_DEFAULT;
如果是异步扫描,那么scsi_prep_async_scan的返回值为TRUE,!data为FALSE,接着用kthread_run执行一个线程。如果是同步扫描,!data为TRUE,直接调用do_scsi_scan_host。结合pm8001的代码我们分别来看一下。首先,我们看一下异步扫描:

p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
在线程环境中调用do_scan_async函数:

  1. static int do_scan_async(void *_data)
  2. {
  3. struct async_scan_data *data = _data;
  4. do_scsi_scan_host(data->shost);
  5. scsi_finish_async_scan(data);
  6. return 0;
  7. }
下面是do_scsi_scan_host函数:

  1. static void do_scsi_scan_host(struct Scsi_Host *shost)
  2. {
  3. if (shost->hostt->scan_finished) {
  4. unsigned long start = jiffies;
  5. if (shost->hostt->scan_start)
  6. shost->hostt->scan_start(shost);
  7. while (!shost->hostt->scan_finished(shost, jiffies - start))
  8. msleep(10);
  9. } else {
  10. scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
  11. SCAN_WILD_CARD, 0);
  12. }
  13. }

在pm8001_pci_probe中已经调用过shost = scsi_host_alloc(&pm8001_sht, sizeof(void *));它完成的功能是分配scsi_host的内存并以pm8001_sht为模板初始化

  1. /**
  2. * scsi_host_alloc - register a scsi host adapter instance.
  3. * @sht: pointer to scsi host template
  4. * @privsize: extra bytes to allocate for driver
  5. *
  6. * Note:
  7. * Allocate a new Scsi_Host and perform basic initialization.
  8. * The host is not published to the scsi midlayer until scsi_add_host
  9. * is called.
  10. *
  11. * Return value:
  12. * Pointer to a new Scsi_Host
  13. **/
  14. struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
  15. {
  16. struct Scsi_Host *shost;
  17. gfp_t gfp_mask = GFP_KERNEL;
  18. int rval;
  19. if (sht->unchecked_isa_dma && privsize)
  20. gfp_mask |= __GFP_DMA;
  21. shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask);
  22. if (!shost)
  23. return NULL;
  24. shost->host_lock = &shost->default_lock;
  25. spin_lock_init(shost->host_lock);
  26. shost->shost_state = SHOST_CREATED;
  27. INIT_LIST_HEAD(&shost->__devices);
  28. INIT_LIST_HEAD(&shost->__targets);
  29. INIT_LIST_HEAD(&shost->eh_cmd_q);
  30. INIT_LIST_HEAD(&shost->starved_list);
  31. init_waitqueue_head(&shost->host_wait);
  32. mutex_init(&shost->scan_mutex);
  33. /*
  34. * subtract one because we increment first then return, but we need to
  35. * know what the next host number was before increment
  36. */
  37. shost->host_no = atomic_inc_return(&scsi_host_next_hn) - 1;
  38. shost->dma_channel = 0xff;
  39. /* These three are default values which can be overridden */
  40. shost->max_channel = 0;
  41. shost->max_id = 8;
  42. shost->max_lun = 8;
  43. /* Give each shost a default transportt */
  44. shost->transportt = &blank_transport_template;
  45. /*
  46. * All drivers right now should be able to handle 12 byte
  47. * commands. Every so often there are requests for 16 byte
  48. * commands, but individual low-level drivers need to certify that
  49. * they actually do something sensible with such commands.
  50. */
  51. shost->max_cmd_len = 12;
  52. shost->hostt = sht;
  53. shost->this_id = sht->this_id;
  54. shost->can_queue = sht->can_queue;
  55. shost->sg_tablesize = sht->sg_tablesize;
  56. shost->cmd_per_lun = sht->cmd_per_lun;
  57. shost->unchecked_isa_dma = sht->unchecked_isa_dma;
  58. shost->use_clustering = sht->use_clustering;
  59. shost->ordered_tag = sht->ordered_tag;
  60. if (sht-&g
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/1003473
推荐阅读
相关标签
  

闽ICP备14008679号