推荐下载Linux内核SCSI子系统驱动架构.docx

上传人:b****8 文档编号:9931579 上传时间:2023-05-22 格式:DOCX 页数:27 大小:36.73KB
下载 相关 举报
推荐下载Linux内核SCSI子系统驱动架构.docx_第1页
第1页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第2页
第2页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第3页
第3页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第4页
第4页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第5页
第5页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第6页
第6页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第7页
第7页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第8页
第8页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第9页
第9页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第10页
第10页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第11页
第11页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第12页
第12页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第13页
第13页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第14页
第14页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第15页
第15页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第16页
第16页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第17页
第17页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第18页
第18页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第19页
第19页 / 共27页
推荐下载Linux内核SCSI子系统驱动架构.docx_第20页
第20页 / 共27页
亲,该文档总共27页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

推荐下载Linux内核SCSI子系统驱动架构.docx

《推荐下载Linux内核SCSI子系统驱动架构.docx》由会员分享,可在线阅读,更多相关《推荐下载Linux内核SCSI子系统驱动架构.docx(27页珍藏版)》请在冰点文库上搜索。

推荐下载Linux内核SCSI子系统驱动架构.docx

推荐下载Linux内核SCSI子系统驱动架构

(完整word版)Linux内核SCSI子系统驱动架构

编辑整理:

 

尊敬的读者朋友们:

这里是精品文档编辑中心,本文档内容是由我和我的同事精心编辑整理后发布的,发布之前我们对文中内容进行仔细校对,但是难免会有疏漏的地方,但是任然希望((完整word版)Linux内核SCSI子系统驱动架构)的内容能够给您的工作和学习带来便利。

同时也真诚的希望收到您的建议和反馈,这将是我们进步的源泉,前进的动力。

本文可编辑可修改,如果觉得对您有帮助请收藏以便随时查阅,最后祝您生活愉快业绩进步,以下为(完整word版)Linux内核SCSI子系统驱动架构的全部内容。

SCSI子系统驱动架构

2013—2—2

代码布局:

一、读写数据流:

drivers/scsi/scsi_lib.c

scsi_execute_req===>scsi_execute===〉blk_execute_rq===〉blk_execute_rq_nowait

错误恢复:

drivers/scsi/scsi_error。

c

内核线程scsi_error_handler===>

 

二、初始化:

(本文!

-—--—-——---————------—----——--——---—---————-——--—-——--——-—-—-——---———--—-———————-———--———------—-——--—-——-----——--——

scsi高层(scsi磁盘)驱动:

1代码分布

2核心调用:

drivers/scsi/sd。

c(这里以scsidisk设备为例)

同步执行部分:

sd_probe

异步执行部分:

sd_probe_async===>sd_revalidate_disk===〉sd_spinup_disk

----—--——-——-————-——-———-—--—-——-——---—--—-——-——--—---———---——-----———--——-——----—--———-—--------—--———---—-——-—-——-

scsi子系统核心初始化:

1代码分布

2核心调用:

scsi_init_queue();

scsi_init_procfs();

scsi_init_devinfo();

scsi_init_hosts();

scsi_init_sysctl();

scsi_sysfs_register();

scsi_netlink_init();

——-—-——--———-—---—-——-------—-—-----—————-——---—-—---———-—-----—----——----——-—--——--—-——-————---——-——-—---———--———-—

scsi适配器驱动:

1代码分布

2核心调用:

drivers/scsi/hosts。

c

1)、structScsi_Host*scsi_host_alloc(structscsi_host_template*sht,intprivsize)

2)、scsi_add_host(structScsi_Host*host,structdevice*dev)

===>scsi_add_host_with_dma(host,dev,dev)

intscsi_add_host_with_dma(structScsi_Host*shost,structdevice*dev,structdevice*dma_dev)

3)、scsi_scan_host===〉do_scsi_scan_host===〉scsi_scan_host_selected===>scsi_scan_channel

===〉__scsi_scan_target===〉scsi_probe_and_add_lun===〉scsi_probe_lun

scsi_add_lun

 

代码骨架:

-—-—-—-——--——-------——--—-—-——————--—---———---—-——--———-——-———--——-—--——-—————--—————-————----————---——----—-——-——-—-—

scsi子系统核心初始化:

drivers/scsi/scsi。

c:

staticstructclassshost_class={

.name=”scsi_host”,

.dev_release=scsi_host_cls_release,

};

staticstructclasssdev_class={

.name="scsi_device",

.dev_release=scsi_device_cls_release,

};

structbus_typescsi_bus_type={

name=”scsi",

match=scsi_bus_match,

uevent=scsi_bus_uevent,

};

subsys_initcall(init_scsi)===>

staticint__initinit_scsi(void)

{

scsi_init_queue();

scsi_init_procfs();

scsi_init_devinfo();//

scsi_init_hosts();//

scsi_init_sysctl();

scsi_sysfs_register();//

scsi_netlink_init();

intscsi_init_hosts(void)

{

returnclass_register(&shost_class);

}

intscsi_sysfs_register(void)

interror;

error=bus_register(&scsi_bus_type);

if(!

error){

class_register(&sdev_class);

}

 

--—------——----—-—--——-——--——-—-———--—--——----—-—-——--——-—-——-———-—-------——--—--——----—--—-—------——--——--—-——--—-——-

scsiHBA驱动:

(前端以dmx3191d为例)

staticstructscsi_host_templatedmx3191d_driver_template={

.name="DomexDMX3191D”,

.queuecommand=NCR5380_queue_command,

.。

.。

};

staticstructpci_device_iddmx3191d_pci_tbl[]={

{PCI_VENDOR_ID_DOMEX,PCI_DEVICE_ID_DOMEX_DMX3191D,

PCI_ANY_ID,PCI_ANY_ID,0,0,4},

{}

};

staticstructpci_driverdmx3191d_pci_driver={

name=DMX3191D_DRIVER_NAME,

.id_table=dmx3191d_pci_tbl,

probe=dmx3191d_probe_one,

.remove=__devexit_p(dmx3191d_remove_one),

};

module_init(dmx3191d_init);

staticint__initdmx3191d_init(void)

{

returnpci_register_driver(&dmx3191d_pci_driver);//调dmx3191d_probe_one

}

staticint__devinitdmx3191d_probe_one(structpci_dev*pdev,conststructpci_device_id*id)

structScsi_Host*shost;

..。

.;

scsi_host_alloc(&dmx3191d_driver_template,sizeof(structNCR5380_hostdata));//-—-———

shost—>irq=pdev-〉irq;

request_irq(pdev->irq,NCR5380_intr,IRQF_SHARED,NAME,shost);

.。

....;

scsi_add_host(shost,&pdev->dev);

scsi_scan_host(shost);

}

 

————-—-——-———-———--—-—---—--—-———------—-——-—-—-—-———---———--—-——---———-——————-—-----——---—-------——----—-

drivers/scsi/hosts。

c

staticatomic_tscsi_host_next_hn;

structScsi_Host*scsi_host_alloc(structscsi_host_template*sht,intprivsize)

structScsi_Host*shost;

gfp_tgfp_mask=GFP_KERNEL;

shost=kzalloc(sizeof(structScsi_Host)+privsize,gfp_mask);

shost—>host_no=atomic_inc_return(&scsi_host_next_hn)-1;

device_initialize(&shost-〉shost_gendev);

shost—〉shost_gendev.bus=&scsi_bus_type;

shost—〉shost_gendev。

type=&scsi_host_type;

.。

.。

..;

device_initialize(&shost-〉shost_dev);

shost—〉shost_dev。

parent=&shost->shost_gendev;

shost—>shost_dev.class=&shost_class;

returnshost;

}

include/scsi/scsi_host。

h

staticinlineint__must_checkscsi_add_host(structScsi_Host*host,structdevice*dev)

{

returnscsi_add_host_with_dma(host,dev,dev);

drivers/scsi/hosts。

c

intscsi_add_host_with_dma(structScsi_Host*shost,structdevice*dev,structdevice*dma_dev)

{

structscsi_host_template*sht=shost—>hostt;

...。

..;

device_add(&shost—〉shost_gendev);//-——-——

device_add(&shost—〉shost_dev);

;

scsi_sysfs_add_host(shost);

.。

;

}

-———-———-—-—-—---—--—-—-——————-—-———--——--—-—————---—-—------—————-——--——-——-———-———-———————--—----—————-—-—--—-—----—

drivers/scsi/scsi_scan。

c

#ifdefCONFIG_SCSI_SCAN_ASYNC//0

#defineSCSI_SCAN_TYPE_DEFAULT"async"

#else

#defineSCSI_SCAN_TYPE_DEFAULT”sync"

#endif

staticcharscsi_scan_type[6]=SCSI_SCAN_TYPE_DEFAULT;

//变量的值可以在加载scsi中间层模块时通过模块参数设定,未设定则用上面的默认值

module_param_string(scan,scsi_scan_type,sizeof(scsi_scan_type),S_IRUGO);

#definejiffiesraid6_jiffies()

//specifyscanningorrescanningofallpossiblechannels,(target)ids,orluns,onagivenshost.

#defineSCAN_WILD_CARD~0

#defineMAX_COMMAND_SIZE16

voidscsi_scan_host(structScsi_Host*shost)

structtask_struct*p;

structasync_scan_data*data;

if(strncmp(scsi_scan_type,"none”,4)==0)

return;

data=scsi_prep_async_scan(shost);//异步扫描准备与判断shost-〉async_scan=1

if(!

data){//如果data=null,shost—〉async_scan仍为0

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);//shost—>async_scan=0

}

staticvoiddo_scsi_scan_host(structScsi_Host*shost)

if(shost->hostt—>scan_finished){

.。

..。

.;//自定义的扫描逻辑

}else{

//通配符SCAN_WILD_CARD~0,表示需要尝试所有可能的值

//rescan=0,表示第一次扫描,为1,表示重新扫描,即这个接口还有其他地方调用!

scsi_scan_host_selected(shost,SCAN_WILD_CARD,SCAN_WILD_CARD,SCAN_WILD_CARD,0);

}

intscsi_scan_host_selected(structScsi_Host*shost,unsignedintchannel,

unsignedintid,unsignedintlun,intrescan)

{

.....;

//shost->async_scan:

是异步扫描标志,为1-—异步扫描,0-—同步扫描

if(!

shost->async_scan)

scsi_complete_async_scans();

if(scsi_host_scan_allowed(shost)){

if(channel==SCAN_WILD_CARD)

for(channel=0;channel<=shost—〉max_channel;channel++)

scsi_scan_channel(shost,channel,id,lun,rescan);

else

scsi_scan_channel(shost,channel,id,lun,rescan);

}

 

staticvoidscsi_scan_channel(structScsi_Host*shost,unsignedintchannel,

unsignedintid,unsignedintlun,intrescan)

{

uintorder_id;

if(id==SCAN_WILD_CARD)

for(id=0;idmax_id;++id){

if(shost—〉reverse_ordering)

order_id=shost-〉max_id—id—1;

else

order_id=id;

__scsi_scan_target(&shost—〉shost_gendev,channel,order_id,lun,rescan);

}

else

__scsi_scan_target(&shost—〉shost_gendev,channel,id,lun,rescan);//—-—-

staticvoid__scsi_scan_target(structdevice*parent,unsignedintchannel,

unsignedintid,unsignedintlun,intrescan)

structScsi_Host*shost=dev_to_shost(parent);

intbflags=0;

intres;

structscsi_target*starget;

if(shost—>this_id==id)

return;

starget=scsi_alloc_target(parent,channel,id);

if(lun!

=SCAN_WILD_CARD){

scsi_probe_and_add_lun(starget,lun,NULL,NULL,rescan,NULL);//-———-——--

gotoout_reap;

}

res=scsi_probe_and_add_lun(starget,0,&bflags,NULL,rescan,NULL);//-—-——-——

if(res==SCSI_SCAN_LUN_PRESENT||res==SCSI_SCAN_TARGET_PRESENT){

//会调用scsi_probe_and_add_lun

if(scsi_report_lun_scan(starget,bflags,rescan)!

=0)

//会调用scsi_probe_and_add_lun

scsi_sequential_lun_scan(starget,bflags,starget-〉scsi_level,rescan);

}

out_reap:

scsi_target_reap(starget);

put_device(&starget—>dev);

 

staticintscsi_probe_and_add_lun(structscsi_target*starget,uintlun,int*bflagsp,

structscsi_device**sdevp,intrescan,void*hostdata)

{

structscsi_device*sdev;

unsignedchar*result;

intbflags,result_len=256;

structScsi_Host*shost=dev_to_shost(starget—>dev.parent);

sdev=scsi_device_lookup_by_target(starget,lun);

if(sdev){

if(rescan||!

scsi_device_created(sdev)){

if(sdevp)

*sdevp=sdev;

else

scsi_device_put(sdev);

if(bflagsp)

*bflagsp=scsi_get_device_flags(sdev,sdev->vendor,sdev->model);

returnSCSI_SCAN_LUN_PRESENT;

}

.。

.。

;

}else

sdev=scsi_alloc_sdev(starget,lun,hostdata);//--—-————---

result=kmalloc(result_len,GFP_ATOMIC|((shost—>unchecked_isa_dma)?

__GFP_DMA:

0));

scsi_probe_lun(sdev,result,result_len,&bflags);//—-—--—-——-

if(bflagsp)

*bflagsp=bflags;

.。

.。

.;

res=scsi_add_lun(sdev,result,&bflags,shost->async_scan);//—-—-——--—

returnres;

staticstructscsi_device*scsi_alloc_sdev(structscsi_target*starget,unsignedintlun,void*hostdata)

structscsi_device*sdev;

structScsi_Host*shost=dev_to_shost(starget—>dev。

parent);

.;

sdev=kzalloc(sizeof(*sdev)+shost->transportt—>device_size,GFP_ATOMIC);

.。

.。

sdev->request_queue=scsi_alloc_queue(sdev);

.。

...;

scsi_sysfs_device_initialize(sdev);//—--——----

.。

;

returnsdev;

voidscsi_sysfs_device_initialize(structscsi_device*sdev)

structScsi_Host*shost=sdev—〉host;

structscsi_target*starget=sdev—>sdev_t

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 小学教育 > 数学

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2