E.1. 中级

内核源代码中的以下头文件与中级相关

        /usr/src/linux/include/scsi/scsi.h
        /usr/src/linux/include/scsi/scsi_ioctl.h

这些文件供应用程序使用(__KERNEL__ 条件编译块中的部分除外)。它们也可能在 /usr/include/scsi 目录中找到,但最好不要信任这些版本,因为它们与 glibc 库一起维护,并且可能落后于正在使用的内核版本。通常在 Linux 系统中/usr/include/linux可以被认为是内核源代码 include 区域的符号链接(通常是/usr/src/linux/include/linux)。此符号链接可用于包含正确的scsi_ioctl.h使用以下技巧#include <linux/../scsi/scsi_ioctl.h>

此包含文件/usr/src/linux/drivers/scsi/scsi.h是 SCSI 子系统的关键内部头文件。因此,此处将不作讨论,仅指出它与本节开头提到的包含文件具有相同的文件名(但在不同的目录中)。这有时会引起混淆。

中级drivers/scsi/scsi_scan.c文件维护一个已知 SCSI 设备数组,其中包含特殊性。[这以前被称为“黑名单”,但这被认为带有评判色彩。] 该数组称为“device_list”。各种值为

E.1.1. 中级编译选项

无。

E.1.2. 中级 ioctl

请参阅以下文件

/usr/src/linux/include/scsi/scsi.h

请注意,include/scsi/scsi.h 中定义的 SCSI 状态常量比 SCSI 标准中的值右移 1 位

scsi.h constant      value     SCSI 2 standard value
----------------------------------------------------
CHECK_CONDITION       0x1           0x2
CHECK_GOOD            0x2           0x4
BUSY                  0x4           0x8
....

ioctl() 摘要如下

SCSI_IOCTL_SEND_COMMAND
  This interface is deprecated - users should use
  the scsi generic (sg) interface instead, as this
  is a more flexible approach to performing
  generic SCSI commands on a device.

  The structure that we are passed should look like:

  struct sdata {
   unsigned int inlen;     [i] Length of data written to device
   unsigned int outlen;    [i] Length of data read from device
   unsigned char cmd[x];   [i] SCSI command (6 <= x <= 16)
                           [o] Data read from device starts here
                           [o] On error, sense buffer starts here
   unsigned char wdata[y]; [i] Data written to device starts here
  };
  Notes:
    -  The SCSI command length is determined by examining
       the 1st byte of the given command. There is no way
       to override this.
    -  Data transfers are limited to PAGE_SIZE (4K on
       i386, 8K on alpha).
    -  The length (x + y) must be at least OMAX_SB_LEN
       bytes long to accommodate the sense buffer when
       an error occurs. The sense buffer is truncated to
       OMAX_SB_LEN (16) bytes so that old code will not
       be surprised.
    -  If a Unix error occurs (e.g. ENOMEM) then the user
       will receive a negative return and the Unix error
       code in 'errno'. If the SCSI command succeeds then
       0 is returned. Positive numbers returned are the
       compacted SCSI error codes (4 bytes in one int)
       where the lowest byte is the SCSI status. See the
       drivers/scsi/scsi.h file for more information on this.

SCSI_IOCTL_GET_IDLUN
  This ioctl takes a pointer to a "struct scsi_idlun" object
  as its third argument. The "struct scsi_idlun" definition
  is found in <scsi/scsi.h>. It gets populated with scsi
  host, channel, device id and lun data for the given device.
  Unfortunately that header file "hides" that structure
  behind a "#ifdef __KERNEL__" block. To use this, that
  structure needs to be replicated in the user's program.
  Something like:
  typedef struct my_scsi_idlun {
      int four_in_one;    /* 4 separate bytes of info
                             compacted into 1 int */
      int host_unique_id; /* distinguishes adapter cards from
                             same supplier */
  } My_scsi_idlun;
      "four_in_one" is made up as follows:
      (scsi_device_id | (lun << 8) | (channel << 16) |
      (host << 24))
  These 4 components are assumed (or masked) to be 1 byte each.

SCSI_IOCTL_GET_BUS_NUMBER
  In lk 2.2 and earlier this ioctl was needed to get the
  host number. During lk 2.3 development the
  SCSI_IOCTL_GET_IDLUN ioctl was changed to include this
  information. Hence this ioctl is only needed for
  backward compatibility.
SCSI_IOCTL_TAGGED_ENABLE
  Probably a remnant of the past when the mid level
  addressed such issues. Now this functionality is
  controlled by the lower level drivers. Best ignored.
SCSI_IOCTL_TAGGED_DISABLE
  See comment for SCSI_IOCTL_TAGGED_ENABLE.
SCSI_IOCTL_PROBE_HOST
  This ioctl expects its 3rd argument to be a pointer to
  a union that looks like this:
  union probe_host {
    unsigned int length;  /* [i] max length of
                                 output ASCII string */
    char str[length];     /* [o] N.B. may need '\0' 
    				 appended */
  };
  The host associated with the device's fd either has a
  host dependent information string or failing that its
  name, output into the given structure. Note that the
  output starts at the beginning of given structure
  (overwriting the input length). N.B. A trailing '\0'
  may need to be put on the output string if it has been
  truncated by the input length. A return value of 1
  indicates the host is present, 0 indicates that the
  host isn't present (how can that happen?) and a
  negative value indicates an error.

SCSI_IOCTL_DOORLOCK
SCSI_IOCTL_DOORUNLOCK
SCSI_IOCTL_TEST_UNIT_READY
  Returns 0 if the unit (device) is ready, a positive
  number if it is not or a negative number when there
  is an OS error.

SCSI_IOCTL_START_UNIT
SCSI_IOCTL_STOP_UNIT
SCSI_EMULATED_HOST          {same as SG_EMULATED_HOST <new>}

SCSI_IOCTL_GET_PCI
  Yields the PCI slot name (pci_dev::slot_name) associated with the lower
  level (adapter) driver that controls the current device. Up to 8 characters
  are output to the locations pointed to by 'arg'. If the current device
  is not controlled by a PCI device then errno is set to ENXIO.
  [This ioctl() was introduced in lk 2.4.4]