赞
踩
接着分析pm8001_pci_probe中调用到的scsi_scan_host函数下面是scsi_scan_host的代码
- /**
- * scsi_scan_host - scan the given adapter
- * @shost: adapter to scan
- **/
- void scsi_scan_host(struct Scsi_Host *shost)
- {
- struct task_struct *p;
- struct async_scan_data *data;
-
- if (strncmp(scsi_scan_type, "none", 4) == 0)
- return;
-
- data = scsi_prep_async_scan(shost);
- if (!data) {
- do_scsi_scan_host(shost);
- return;
- }
-
- p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no);
- if (IS_ERR(p))
- do_scan_async(data);
- }

下面看一下scsi_scan_type是什么,显然它的值是字符串 "async"或者"sync
- #ifdef CONFIG_SCSI_SCAN_ASYNC
- #define SCSI_SCAN_TYPE_DEFAULT "async"
- #else
- #define SCSI_SCAN_TYPE_DEFAULT "sync"
- #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函数:
- static int do_scan_async(void *_data)
- {
- struct async_scan_data *data = _data;
- do_scsi_scan_host(data->shost);
- scsi_finish_async_scan(data);
- return 0;
- }
下面是do_scsi_scan_host函数:
- static void do_scsi_scan_host(struct Scsi_Host *shost)
- {
- if (shost->hostt->scan_finished) {
- unsigned long start = jiffies;
- if (shost->hostt->scan_start)
- shost->hostt->scan_start(shost);
-
- while (!shost->hostt->scan_finished(shost, jiffies - start))
- msleep(10);
- } else {
- scsi_scan_host_selected(shost, SCAN_WILD_CARD, SCAN_WILD_CARD,
- SCAN_WILD_CARD, 0);
- }
- }
- /**
- * scsi_host_alloc - register a scsi host adapter instance.
- * @sht: pointer to scsi host template
- * @privsize: extra bytes to allocate for driver
- *
- * Note:
- * Allocate a new Scsi_Host and perform basic initialization.
- * The host is not published to the scsi midlayer until scsi_add_host
- * is called.
- *
- * Return value:
- * Pointer to a new Scsi_Host
- **/
- struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
- {
- struct Scsi_Host *shost;
- gfp_t gfp_mask = GFP_KERNEL;
- int rval;
-
- if (sht->unchecked_isa_dma && privsize)
- gfp_mask |= __GFP_DMA;
-
- shost = kzalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask);
- if (!shost)
- return NULL;
-
- shost->host_lock = &shost->default_lock;
- spin_lock_init(shost->host_lock);
- shost->shost_state = SHOST_CREATED;
- INIT_LIST_HEAD(&shost->__devices);
- INIT_LIST_HEAD(&shost->__targets);
- INIT_LIST_HEAD(&shost->eh_cmd_q);
- INIT_LIST_HEAD(&shost->starved_list);
- init_waitqueue_head(&shost->host_wait);
-
- mutex_init(&shost->scan_mutex);
-
- /*
- * subtract one because we increment first then return, but we need to
- * know what the next host number was before increment
- */
- shost->host_no = atomic_inc_return(&scsi_host_next_hn) - 1;
- shost->dma_channel = 0xff;
-
- /* These three are default values which can be overridden */
- shost->max_channel = 0;
- shost->max_id = 8;
- shost->max_lun = 8;
-
- /* Give each shost a default transportt */
- shost->transportt = &blank_transport_template;
-
- /*
- * All drivers right now should be able to handle 12 byte
- * commands. Every so often there are requests for 16 byte
- * commands, but individual low-level drivers need to certify that
- * they actually do something sensible with such commands.
- */
- shost->max_cmd_len = 12;
- shost->hostt = sht;
- shost->this_id = sht->this_id;
- shost->can_queue = sht->can_queue;
- shost->sg_tablesize = sht->sg_tablesize;
- shost->cmd_per_lun = sht->cmd_per_lun;
- shost->unchecked_isa_dma = sht->unchecked_isa_dma;
- shost->use_clustering = sht->use_clustering;
- shost->ordered_tag = sht->ordered_tag;
-
- if (sht-&g

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。