在以前的一篇博文《关于构建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盘进行读写扇区操作。

USB系列之七:ASPI介绍及命令测试的更多相关文章

  1. USB系列之八:透过ASPI执行SCSI命令

    在<USB系列之七>里我们介绍了ASPI的规范,并对一系列ASPI的命令做了测试,其中的02号命令是执行SCSI命令,我们专门在这篇文章中介绍,在<USB系列七>中,我们已经了 ...

  2. USB系列之九:基于ASPI的U盘驱动程序

    USB系列之七和之八介绍了ASPI,并通过一些实例说明了基于ASPI的编程方法,本文使用前两篇文章介绍的知识以及以前介绍的有关DOS驱动程序下驱动程序的内容实际完成一个简单的基于ASPI的U盘驱动程序 ...

  3. USB系列之四:向U盘上写数据

    在<USB系列之三>中,我们实现了一系列的SCSI命令,在这个系列中,我们要实现向U盘上写扇区的命令,所以,本文相对比较容易,更多地是给出一个实现的源程序. 在<USB系列之三> ...

  4. USB系列之三:从你的U盘里读出更多的内容

    U盘是我们最常使用的一种USB设备,本文继续使用DOSUSB做驱动,试图以读取扇区的方式读取你的U盘.本文可能涉及的协议可能会比较多. 一.了解你的U盘    首先我们用上一篇文章介绍的程序usbvi ...

  5. OpenvSwitch系列之七 meter表限速

    Open vSwitch系列之一 Open vSwitch诞生 Open vSwitch系列之二 安装指定版本ovs Open vSwitch系列之三 ovs-vsctl命令使用 Open vSwit ...

  6. USB系列之六:基于DOSUSB的简单U盘驱动程序

    首先要说明的是,该驱动程序仅实现了部分块设备的功能,如果作为成品软件使用,会感觉性能比较差,而且有些功能(比如FORMAT)是不能完成的,发表此驱动程序的目的旨在说明USB的编程原理以及DOS下驱动程 ...

  7. .NET 4 并行(多核)编程系列之一入门介绍

    .NET 4 并行(多核)编程系列之一入门介绍 本系列文章将会对.NET 4中的并行编程技术(也称之为多核编程技术)以及应用作全面的介绍. 本篇文章的议题如下:  1. 并行编程和多线程编程的区别.  ...

  8. 【Xamarin挖墙脚系列:mac 终端 常用命令+Mac OS X的快捷键+beamoff 】

    原文:[Xamarin挖墙脚系列:mac 终端 常用命令+Mac OS X的快捷键+beamoff ] 基本命令 1.列出文件 ls 参数 目录名        例: 看看驱动目录下有什么:ls /S ...

  9. USB系列之二:读取USB设备的描述符

    在前面的文章中,我们已经给出了USB协议的链接地址,从这篇文章起,我们会涉及到许多USB 1.1的内容,我们的指导思想是先从熟悉USB 1.1协议入手,先使用现成的HCD和USBD,直接面对客户端驱动 ...

随机推荐

  1. 编译不通过:提示XXXX不是类或命名空间名 的解决办法

    手动写了一个类,需要引入预编译头stdafx.h.结果编译时提示XXXX不是类或命名空间名. 处理方法:将#include "stdafx.h"放在最前面.

  2. tyvj1297 小气的小B

    描述 其实你们都不知道,小B是很小气的.一天小B带着他的弟弟小B'一起去摘果子,走着走着,他们忽然发现了一颗长满了果子的树.由于弟弟长得太矮了,弟弟只有让哥哥小B帮他摘一些果子下来.哥哥小B说:&qu ...

  3. 【HDU1856】More is better(并查集基础题)

    裸并查集,但有二坑: 1.需要路径压缩,不写的话会TLE 2.根据题目大意,如果0组男孩合作的话,应该最大的子集元素数目为1.所以res初始化为1即可. #include <iostream&g ...

  4. Python 入门教程 9 ---- A Day at the Supermarket

    第一节 1 介绍了for循环的用法 for variable in values: statement 2 for循环打印出列表的每一项 for item in [1 , 2 , 3]: print ...

  5. .NET 中使用 HttpWebResponse 时 Cookie 的读取

    今天把一个网站登录配置到以前写的蜘蛛程序中,发现不能成功登录.检查后才发现,那个网站在登录成功后,输出了一个特殊路径的 Cookie,由于是使用 HttpWebRequest.Cookies 来获取的 ...

  6. BOOST 线程完全攻略 - 扩展 - 可被关闭的线程类

    本文假设读者已经基本了解boost线程库的使用方法. boost是个开源工程,线程这一块也在不断完善之中,到现在这个阶段,boost::thread仅仅实现了一个完美的技术框架,但是读者在实际使用中会 ...

  7. Java中String直接赋字符串和new String的区别

    解析Java中的String对象的数据类型 1. String是一个对象.  因为对象的默认值是null,所以String的默认值也是null:但它又是一种特殊的对象,有其它对象没有的一些特性. 2. ...

  8. stm32之通用定时器TIM

    STM32系列的CPU,有多达8个定时器: 1.其中TMI1和TIM8是能够产生三对PWM互补输出的高级定时器,常用于三相电机的驱动:它们的时钟有APB2的输出产生: 2.其它6个为普通定时器,时钟由 ...

  9. OMXCodec与OMX事件处理流程

    学习了解Mutilmedia Framework有一段时间了,今天闲下来稍微整理整理.OMXCodec.cpp类属于libstagefright,在整个MM PF 相当OMX的适配层,供awesome ...

  10. LinearLayout使用简单实例

    1.代码 import android.annotation.SuppressLint; import android.app.Activity; import android.app.ActionB ...