terrychen
驱动小牛
驱动小牛
  • 注册日期2002-04-15
  • 最后登录2014-03-13
  • 粉丝0
  • 关注0
  • 积分174分
  • 威望68点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
阅读:4243回复:32

scsi miniport的问题

楼主#
更多 发布于:2003-12-25 14:15
我在写一个虚拟scsi设备的driver,使用ScsiPortNotification来返回srb到portdriver.但是因为是虚拟设备,所以没有真正的中断,目前是用ScsiPortNotification(RequestTimerCall,)来返回数据,但是好像这个timer最小间隔是10 milliseconds。这样很影响效率,请问一下大家有没有什么办法,可以直接ScsiPortNotification返回给port driver,或者什么方法可以提高效率?

最新喜欢:

aventineaventi...
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2005-01-27 13:37
为什么我用上面的方法,老是停在KeWaitForSingleObject上了??并且没有进我的HwStartIo
我的是xp
liuyan1
驱动老牛
驱动老牛
  • 注册日期2001-08-27
  • 最后登录2023-04-18
  • 粉丝0
  • 关注0
  • 积分1031分
  • 威望477点
  • 贡献值0点
  • 好评度187点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2005-01-26 17:49
daemon-tools alcohol的数据传输速率好象也不高呀。也就100X左右(17M/S)。是不是还是拜这个scsitimer 所害?
听说有人采用backdoor scsiport driver 可以达到71M/S,
采用哪个VSPORT 可以达到84M/s ,不知道是否是真的?
下边这种方法老大们用过吗?

Subject: Re: Anton..Can you help?
From: "Anton Kolomyeytsev" <xxx@cooldev.com>
Date: Thu, 23 Jan 2003 09:29:39 -0500
 

Hi,

you do not need to send SRBs to some unknown miniport, you need to send
SRBs to yourself. From the worker thread you create to call all the code
that need to be executed at PASSIVE_LEVEL and in system thread context you
just call your own miniport to complete the previous request (SRB) you're
handing in the worker thread now. First you need to locate DEVICE_OBJECT
that belongs to you (to your miniport). PDEVICE_OBJECT
g__PDEVICE_OBJECT__Miniport in global data region. In DriverEntry( ... )
you need to run:

PDEVICE_OBJECT l__PDEVICE_OBJECT__Scan = ( ( PDRIVER_OBJECT )(
p__PVOID__DriverObject )->DeviceObject );

while ( l__PDEVICE_OBJECT )
{
ULONG l__ULONG__DeviceType = l__PDEVICE_OBJECT__Scan->DeviceType;

if ( l__ULONG__DeviceType == FILE_DEVICE_CONTROLLER )
{
g__PDEVICE_OBJECT__Miniport = l__PDEVICE_OBJECT__Scan; // Keep the
pointer!!!
break;
}

l__PDEVICE_OBJECT__Scan = l__PDEVICE_OBJECT__Scan->NextDevice;
}

Now you have DEVICE_OBJECT of your miniport in global variable. The way
shown above is not "safe" but it works for me. If you do not like this way
you can always try to enumerate all the SCSI miniports and find your own
instance somewhere in the delayed initialization or later by call to
ZwCreateFile( ..., "\\Device\\Scsi%u", ... ).

Now in the worker thread that just executed code to do something with SRB
you need to run this code (p__PSCSI_REQUEST_BLOCK__Srb is the SRB you're
executing):

KEVENT l__KEVENT;

IO_STATUS_BLOCK l__IO_STATUS_BLOCK;

PIRP l__PIRP;

NTSTATUS l__NTSTATUS;

SCSI_REQUEST_BLOCK l__SCSI_REQUEST_BLOCK;

PIO_STACK_LOCATION l__PIO_STACK_LOCATION;

PVOID l__PVOID__SrbBuffer = ( PVOID )( p__PSCSI_REQUEST_BLOCK__Srb ); //
Keep pointer to SRB here

LARGE_INTEGER l__LARGE_INTEGER__StartingOffset;

KeInitializeEvent(
&l__KEVENT,
NotificationEvent,
FALSE
);

l__LARGE_INTEGER.QuadPart = 1; // SCSIPORT.SYS does this, do not know for
what

l__PIRP =
IoBuildSynchronousFsdRequest(
IRP_MJ_SCSI,
g__PDEVICE_OBJECT__Miniport, // Global device object
&l__PVOID__SrbBuffer,
sizeof( l__PVOID__SrbBuffer ),
&l__LARGE_INTEGER__StartingOffset,
&l__KEVENT,
&l__IO_STATUS_BLOCK
);

RtlZeroMemory(
&l__SCSI_REQUEST_BLOCK,
sizeof( l__SCSI_REQUEST_BLOCK )
);

l__SCSI_REQUEST_BLOCK.TargetId = l__UCHAR__TargetId; // Your target ID
goes here, and all SCSI address should be correct

...

l__SCSI_REQUEST_BLOCK.Function = 2;

l__SCSI_REQUEST_BLOCK.Length = sizeof( SCSI_REQUEST_BLOCK );

l__SCSI_REQUEST_BLOCK.SrbFlags = ( SRB_FLAGS_DATA_IN |
SRB_FLAGS_NO_QUEUE_FREEZE |
SRB_FLAGS_BYPASS_FROZEN_QUEUE ); // DO NOT FORGET TO PUT THIS FLAG OR YOU
MAY RUN A DEADLOCK!!

l__SCSI_REQUEST_BLOCK.DataBuffer = l__PVOID__SrbBuffer;

l__SCSI_REQUEST_BLOCK.DataTransferLength = sizeof( l__PVOID__Buffer );

l__PIO_STACK_LOCATION = IoGetNextIrpStackLocation( l__PIRP );

l__PIO_STACK_LOCATION->MajorFunction = IRP_MJ_SCSI;

l__PIO_STACK_LOCATION->MinorFunction = 1;

l__PIO_STACK_LOCATION->Parameters.Scsi.Srb = &l__SCSI_REQUEST_BLOCK;

l__NTSTATUS =
IoCallDriver(
g__PDEVICE_OBJECT__Miniport, // Global device object
l__PIRP
);

if( l__NTSTATUS == STATUS_PENDING )
{
KeWaitForSingleObject(
&l__KEVENT,
Executive,
KernelMode,
FALSE,
NULL
);

l__NTSTATUS = l__IO_STATUS_BLOCK.Status;
}

Analyze l__NTSTATUS that keep operation completion here.

So the idea is simple. From the thread that runs independently you can
queue SRB that holds the pointer to the SRB you want to complete to your
own miniport (if asking SCSIPORT to process the flag with no queue
freeze). In the context of the SCSI miniport (HwStartIo) you analyze SRB
and complete both SRBs on the same time, first that is pointer in .Buffer
of the "parent" SRB and next this SRB itself ("parent"). That's all...

I'm very sorry but I'm not going to spend more time on this topic - I've
did this already last year and I have other things to do and do not know
anything new about this stuff.

In your particular case I'll recommend to write WDM driver that will be
shared
between 2000/XP/.NET and 98/Me and have storage part separated into port
drivers (different of course ) for both platforms. Very good sample of
doing this is USBLS120 from Microsoft (this sample not part of DDK but can
be found on the net).

Good luck!

Regards,
Anton Kolomyeytsev

楼上的客,楼下的客,听我老坎说明白,要苛屎有草纸,不要扯我的麦席子,要苛尿有夜壶,不要在床上划地图。
liuyan1
驱动老牛
驱动老牛
  • 注册日期2001-08-27
  • 最后登录2023-04-18
  • 粉丝0
  • 关注0
  • 积分1031分
  • 威望477点
  • 贡献值0点
  • 好评度187点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2005-01-25 15:04
我只有3MB/s,差劲啊,有没有details关于预取?

 加一个LRU ,FIFO,OPT的队列就可以提高突发速率。可以达到daemon-tools 那样BT的300-400M/S的速度的。


不过提高数据传输确实恼火,用scsitimer 老是快不了。
楼上的客,楼下的客,听我老坎说明白,要苛屎有草纸,不要扯我的麦席子,要苛尿有夜壶,不要在床上划地图。
tanky
驱动牛犊
驱动牛犊
  • 注册日期2002-03-04
  • 最后登录2007-06-08
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-04-30 16:06
预取这个东西就靠自己发挥了,呵呵,先把数据读到内存,下次就可以在startio拷贝数据,完成请求了。
terrychen
驱动小牛
驱动小牛
  • 注册日期2002-04-15
  • 最后登录2014-03-13
  • 粉丝0
  • 关注0
  • 积分174分
  • 威望68点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-04-29 09:13
我只有3MB/s,差劲啊,有没有details关于预取?
tanky
驱动牛犊
驱动牛犊
  • 注册日期2002-03-04
  • 最后登录2007-06-08
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-04-28 11:56
你是加个预取线程吧,我用这个方法的时候,预取线程和StartIo  总是不能并行运行,总是StartIo把cache搞完后才轮到预取线程运行。不知道你是怎么调优先级的。我的用cdspeed测试只有5M/s,Daemon可以到100M/s,真是变态。

加cache可能会有改善。我们就是这样提速的,差不多在10倍左右。用Nero测试下来,Burst Rate在60M左右。
terrychen
驱动小牛
驱动小牛
  • 注册日期2002-04-15
  • 最后登录2014-03-13
  • 粉丝0
  • 关注0
  • 积分174分
  • 威望68点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-04-27 14:00
我知道nt的code出来了,但是没想到这块也会有,一直都在忙,还没空看这些东西呢,主要还是怕看不懂,呵呵
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-04-27 11:11
o,真的么?太好了,能告诉我哪里有下么
 


可以使用BT下载啊,NT4 Sourcr泄露出来都那么久了,你竟然不知道?难道是闭关练功去了?
附件名称/大小 下载次数 最后更新
2004-04-27_ScsiPort.zip (77KB)  47
terrychen
驱动小牛
驱动小牛
  • 注册日期2002-04-15
  • 最后登录2014-03-13
  • 粉丝0
  • 关注0
  • 积分174分
  • 威望68点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-04-27 09:15
o,真的么?太好了,能告诉我哪里有下么
slwqw
驱动大牛
驱动大牛
  • 注册日期2002-07-18
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望197点
  • 贡献值0点
  • 好评度147点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-04-26 16:46
NT4 Source里边有SCSIPORT.SYS的源代码,可以拿来参考一下。
terrychen
驱动小牛
驱动小牛
  • 注册日期2002-04-15
  • 最后登录2014-03-13
  • 粉丝0
  • 关注0
  • 积分174分
  • 威望68点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-04-26 14:05
我这里也没有port driver的例子,我自己也在找,现在只在www.storagecraft.com这里发现有人写了这个,准备让公司去买一套过来看看。
zh01
驱动牛犊
驱动牛犊
  • 注册日期2001-07-10
  • 最后登录2008-04-24
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望2点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2004-04-25 23:28
请问你的例子是什么系统
port driver 在win98下才会用吧
terrychen
驱动小牛
驱动小牛
  • 注册日期2002-04-15
  • 最后登录2014-03-13
  • 粉丝0
  • 关注0
  • 积分174分
  • 威望68点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-04-21 18:06
我用cache没有提高performance,用timer的方式效率一定很低的,微软的办法是重写一个port driver.
你们那里有没有写port driver的高手?
kangzh
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2012-08-06
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2004-04-21 17:49
terrychen:
你的scsi效率提高了吗?有没有比较好的方法亚
kangzh
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2012-08-06
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2004-04-16 11:57
seaquester 大虾,救救小弟阿
把这段代码放到链表中,同时在线程中处理,就出现超时,但如果先把srb放到list中,并马上取出执行,就没有任何问题,请问这是怎么回事.

Srb->SrbStatus = SRB_STATUS_SUCCESS;
Srb->ScsiStatus = SCSISTAT_GOOD;
DbgPrint(\"this=%x,m_ScsiHBA=%x\\n\",this,m_ScsiHBA);
(this->*m_CmdTable[Srb->Cdb[0]])(Srb);
ScsiPortNotification(NextRequest,
(PVOID)m_ScsiHBA,
Srb );
ScsiPortNotification(RequestComplete,
(PVOID)m_ScsiHBA,
Srb );

kangzh
驱动小牛
驱动小牛
  • 注册日期2004-03-09
  • 最后登录2012-08-06
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望22点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
16楼#
发布于:2004-04-02 17:21
问问各位大牛:俺在Read10中调用如下SubRequest,之后在一个线程中接受事件来处理该Srb,之后将处理的Srb放到定时器的TimerCall中
完成提交,但在重新启动时好像死机一样,好像是Scsi miniport加载时一直处于等待状态,大家说一下我的这种做法可以吗?正确该怎么做呢

BOOLEAN CVThreadDevice::SubmitRequest(PSCSI_REQUEST_BLOCK Srb)
{
Srb->SrbStatus = SRB_STATUS_PENDING;

if( KeGetCurrentIrql()>DISPATCH_LEVEL )
{
VPrint(("Current IRQL: %x\n",KeGetCurrentIrql() ));
//
// KeSetEvent can only be running at DISPATCH_LEVEL and less
//
LoadStatus(Srb,recNOT_READY);
//
// use RequestReturn of base class here!
//
CVDevice::RequestReturn(Srb);
return TRUE;
}

((PSRB_EXTENSION)Srb->SrbExtension)->Srb = Srb;

ExInterlockedInsertTailList(
&RequestHead,
&((PSRB_EXTENSION)Srb->SrbExtension)->ListEntry,
&ListLock
);
//
// Signal the worker for processing
//
KeSetEvent(
&ThreadEvent,
IO_NO_INCREMENT,
FALSE );

return TRUE;
}
terrychen
驱动小牛
驱动小牛
  • 注册日期2002-04-15
  • 最后登录2014-03-13
  • 粉丝0
  • 关注0
  • 积分174分
  • 威望68点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
17楼#
发布于:2003-12-31 21:23
这个我已经改了,改成了128k,但是一般系统不会一次i/o请求超过64k的,所以没什么用,估计miniport没戏了,得用别的port driver了
cool-net
驱动小牛
驱动小牛
  • 注册日期2003-03-18
  • 最后登录2010-01-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
18楼#
发布于:2003-12-31 19:42
如果你是用文件虚拟设备的话,加cache不是很必要,应为文件系统本来就有cache(注意WRITE_THROUGH只控制写,而INTERMEDIATE_BUFFER不能控制FileSystem的cache)。

你可以把MaximumTransferLength加大点儿试试。
有错误才会有进步,所以我的人生目标是: 错误不断,毁人不倦!
terrychen
驱动小牛
驱动小牛
  • 注册日期2002-04-15
  • 最后登录2014-03-13
  • 粉丝0
  • 关注0
  • 积分174分
  • 威望68点
  • 贡献值0点
  • 好评度15点
  • 原创分0分
  • 专家分0分
19楼#
发布于:2003-12-31 08:59
加cache,能不能说具体一点呢?我PORT_CONFIGURATION_INFORMATION里面的cachedata也true了,没有什么反映啊,版主说说吧
上一页
游客

返回顶部