USB系列之七:ASPI介绍及命令测试

  在以前的一篇博文《关于构建DOS下编程平台的总结》中曾经介绍了一种在DOS下驱动U盘的方法,我们大致回顾一下。在config.sys中加入两个驱动程序,就可以驱动U盘:
device = aspiohci.sys
device=di1000dd.sys
  这两个驱动程序在上述博文中有下载。
  如果大家仔细地阅读过我关于USB的文章的话,应该对OHCI这个东西不会陌生,在USB系列文章中,用大量的篇幅介绍了OHCI,这是因为OHCI这种符合USB1.1的控制器在使用上比UHCI要普遍,同时现在唯一符合USB2.0规范的EHCI与OHCI兼容,就是说OHCI的驱动可以驱动EHCI,不过性能发挥不出来而已。我们回过头来看上面的两个驱动,第一个驱动文件的文件名是:aspiOHCI.sys,这次我特别把OHCI这四个字母大写以示强调,这说明这个驱动程序是一个针对OHC的驱动,那么或许大家要问,前面的ASPI又是什么含义呢?的确大有意义,本文将简单介绍这个ASPI。
  ASPI是Advanced SCSI Programming Interface的缩写,可能统一的翻译叫:高级SCSI编程接口,SCSI这个词听起来也应该不陌生,除了从事计算机行业经常遇到外,在我的USB系列文章中也多次提到,首先在《USB系列之三:从你的U盘里读出更多的内容》中,提到如果USB设备的接口描述符的Interface Class字段如果为8,表明这是一个Mass Storage Device,同时,如果Sub Class字段为6,说明这个Mass Storage Device执行SCSI命令,实际上,在我手里的U盘都是执行SCSI命令的,在这篇博文中,我们甚至还给出了SCSI的两个重要规范的下载,SPC-3和SBC-2,在后面的博文中不论是读扇区、写扇区,还是读取U盘容量,检查设备READY等,实际上都是使用的SCSI命令结构(我想这一点认真读过USB系列文章的读者应该很有体会),那么现在又出现了这个ASPI,是不是利用这个接口也可以完成U盘的驱动呢?当然可以,而且看上去会比DOSUSB更容易些。
  在接下来的3篇文章中(也可能会是4篇),计划用2篇文章完成ASPI的介绍和测试,并在第3篇文章中完成一个基于ASPI的U盘驱动程序。
  首先,我们给出ASPI For DOS的规范下载(这个规范已经很难找了,但ASPI For Win32很容易找):  http://blog.hengch.com/specification/aspi_for_dos.pdf
  其次,我们所有的文章将借助下面的ASPI驱动来完成任务:aspiohci.sys下载:http://blog.hengch.com/software/aspiohci.sys
  请把这个驱动程序在config.sys中加载,否则,我们后面的程序将无法运行。这个驱动程序将把一个叫做"SCSIMGR$"的字符设备加到DOS的设备驱动程序链中,当要调用ASPI的功能前,需要首先找到它的入口地址,然后通过一个远程调用call far来调用。在ASPI For DOS中的第4页有一段程序说明了如何获得ASPI的入口地址,以及调用ASPI的方法,要注意的是,在调用ASPI前,需要填写一个SRB(SCSI Request Block)表,并且要先把这个表的段地址和偏移地址压入堆栈,然后调用ASPI,这也就是为什么调用ASPI后要把SP+4的原因,因为在调用前压入了两个字的内容。
  调用ASPI,SRB这个东西十分重要,必须认真理解规范中的内容,由于他是可变长度的,不同的命令,字段含义也不尽相同,我们将结合后面的演示程序尽量做一个说明。
    演示程序:Testing ASPI Commands (http://blog.hengch.com/source/aspitest.zip
    这个程序主要测试了ASPI的命令,在ASPI For DOS中,ASPI提供了7个命令,分别是:

    Command Code  Description
    ------------  ---------------------------------------
                Host Adapter Inquiry Command
                Get Device Type Command
                Execute SCSI I/O Command
                Abort SCSI I/O Command
                Reset SCSI Device Command
                Set Host Adapter Parameters Command
                Get Disk Drive Information Command

  我们写的这个程序测试了其中的4个命令,Command Code分别是00、01、06和04,02命令我们会在下一篇文章中做测试,05命令我们用不上,03命令测试起来有些难度。
  下面我们结合源程序做一下简单的说明。
  public.mac文件中定义了4个宏,分别是:pusha、popa、printStr、getCh和callAspi,在源程序中如果看到这四个宏可以到public.mac中去看看源代码。
  aspi.inc中定义了ASPI中的SRB(SCSI Request Block),当在源程序中看到诸如srb.srb......这样的变量时,可以去这个文件中查一查是什么东西,看这个文件中的定义,需要结合ASPI For DOS文档,否则不知所云。
  关键的部分当然在aspitest.asm中,主流部分有比较详细的注释,但有些地方还说明一下。
  在我的环境下,运行aspitest程序后的显示结果如下:

    ASPI test program v1..

    Open SCSIMRG success!    ASPI entry : :6a5c

    Show INQUIRY result
    Command status:     Request Signature: 55aa
    Extended buffer length:     Number of host adapter:
    Host adapter SCSI ID:
    SCSI manager ID: OHCI10 USB ASPI     Host Adapter Identifier:
    Supported Extensions: 

    Show Device Type
    Host Adapter Number:     Target ID:
    Command status:     Peripheral Device Type: 

    Show Disk Drive Information
    Command status:     Drive Flag:
    Int 13h Drive:     Preferred Head Translation:
    Preferred Sector Translation: 

    Show Reset Result
    Command status: 

  1、INQUIRY命令后,Command Status = 01表示命令执行完毕;Request Signature变成55aah(调用前为0aa55h)说明支持某些扩展请求机制(Extended Request Mechanism),具体支持那些要看Supported Extensions字段,在这里为0002h,从ASPI For DOS文档中得知,这表明支持剩余字节长度报告功能,就是说,当我们需要ASPI给我们传输数据时,我们在发送请求时比如设置10个字节,传输完毕时如果只传输了8个字节,则剩余的2个字节它会报告给你,在执行这个命令中我们也可以看到这个功能,我们可以看源程序,在调用ASPI执行INQUIRY命令前,我们把Extended Buffer Length这个字段置成了4,要求给我们传输4个字节,结果只给传回了2个字节(就是Supported Extensions字段的一个字),所以在命令执行完毕后,Extended Buffer Length字段变成了2,这在结果显示中可以看到;Number of Host Adapter是指Host Adapter的数量,本例中为1,说明只有当Host Adapter Number为0是有效的,其它均无效;Host Adapter SCSI ID实际返回的是可用的最大SCSI ID的值,现在为7,并不是指0-7有8个SCSI设备可用,具体那个有效需要在下面进行判断。

  2、在执行Get Device Type命令时,我们做了一个循环,把所有可能的SCSI设备做了一个扫描,根据文档,当Command Status返回82h时,说明SCSI设备没有安装,只有当我们扫描到一个合法的SCSI设备时,我们才显示这个设备的Device Type,在我的环境下,扫描结果显示,只有当Host Adapter Number=0,SCSI ID=0是设备有效,其余均无效;我们这个设备的Device Type=00,查SPC-3(这个文档在以前的文章中有过介绍,也有下载链接)得知,这是一个Direct access block device。
  3、Reset这个命令在我做测试时,Command Status返回0,说明还没有执行完毕,按照文档,等待若干时间后Command Status应该可以变为1,但实际情况却不行,这可能与DOS的单任务特性有关,但也可能Reset命令实际上已经完成,只是状态无法返回,总之在使用这个命令时请慎重,尤其不要等待状态,如果那位读者在使用此命令时情况与我的不同希望能告知我,邮件地址:hengch@163.com

下一篇关于ASPI的文章将在此基础上专门测试执行SCSI命令对U盘进行读写扇区操作。

上一篇:Jquery笔记之第二天


下一篇:ASP.NET 管道事件与HttpModule, HttpHandler简单理解 -摘自网络