|
|
#include "scsi.h"
All members in the request block are writable
by the peripheral driver
except host_sts
, target_sts
,
and req_status
.
All other members must be set
before sending the request to
the host adapter driver.
Some members are not implemented for
some host adapter drivers.
The request block structure contains
information needed by a wide variety of host adapter drivers.
As an example,
the supported host adapter driver
does not support linked commands at present.
Thus the link_ptr and link_id members
are not accessed by the host adapter driver
supplied with your software.
Future support for the link command capability is possible;
set these members to 0 (zero)
to ensure that conflicts do not occur.
The members of the scsi_io_req structure can be grouped according to whether they are set by the peripheral driver or the host adapter driver, whether they are reserved, or used internally by the peripheral driver.
char id;
char lun;
char ha_num;
char bus_num;
struct exten *ext_p;
req_type
is equal to SCSI_INFO,
then this member is used to return special information from the adapter
driver. (See the section below on the SCSI_INFO
command for a full description.)
Otherwise, this member is reserved and should be set to 0.
char opcode;
char dir;
char cmdlen;
paddr_t data_len;
For scatter/gather operations, this is the total length in bytes of all the scatter/gather requests added together.
paddr_t data_ptr;
For scatter/gather operations, this is the address of an array of type long that contains the physical memory locations into which to transfer data. In other words, there are the kernel I/O buffers.
paddr_t data_blk;
For scatter/gather operations, this is the offset into the disk media from which the scatter/gather request will start, in blocks.
union scsi_cdb scsi_cmd;
char r_count;
char hacmd;
int (*io_intr)();
char sense_len;
paddr_t scsi_sense;
paddr_t link_ptr;
paddr_t req_id;
char use_flag;
char internal;
char jq;
char ctlr;
char req_status;
char adapter;
struct buf *rbuf;
char *s1;
char *s2;
char link_id;
struct scsi_io_req *req_forw;
char host_sts;
char target_sts;
req_type
member of the request block.
All SCSI peripheral drivers
must be coded to process these types of requests
and all SCSI host adapter drivers
must be coded to handle these types of requests.
See the sample code on the AHDK CD-ROM disk
for examples of both SCSI peripheral
and SCSI host adapter drivers.
Note that special coding is required
to process scatter/gather requests.
The possible values of the req_type
member are:
The id
, ha
, bus
, and lun
members identify the target.
This command may be sent more than once for a given target.
If the hacmd
member is set to the value
SCSI_DISK_INFO,
the adapter will return information
about any BIOS-compatibility
geometry that it supports.
The ext_p
member in the request block
must point to a struct exten
which will be filled in by the adapter.
The members are filled in as follows:
type
next
data[0]
data[1]
data[2]
Note that these values need not have any relation to the actual physical geometry of the device. If an adapter does not have a BIOS-compatible geometry, it may return the actual values for these members as reported by the device.
If the operating system is to be able to boot from disks attached to this adapter, the BIOS and operating system must agree on the disk's geometry. The exact mechansm of agreement may vary. Some BIOSes (and corresponding drivers) use fixed geometries such as [64 heads, 32 sectors/track] or [255 heads, 63 sectors/track]. Others select between several fixed geometries according to the total capacity of the disk. The values may also come from other sources such as user preferences, configured in the BIOS setup. In this case, some mechanism specific to the driver and the BIOS is required to communicate those values.
The boot program can only access the first 1024 cylinders of a disk; that is approximately the first 1GB of a [64, 32] geometry or the first 7.8GB of a [255,63] geometry. For the device to multi-boot different operating system, it must use a geometry that provides large bootable areas.
The operating system is limited
to a total of 65535 cyliders per disk.
Disks up to 64GB can be accessed
under a [64, 32] geometry;
disks up to 502GB can be accessed
under a [255, 63] geometry;
Peripheral drivers should use
the capacity of the target unit
(from the READ CAPACITY SCSI command),
and the number of heads and sectors per track
to calculate the number of cylinders for the device.
The host adapter only sends back heads and sectors;
the SCSI peripheral driver must calculate the cylinders.
Note that the number of blocks is zero-based,
so you need to add 1 to the last block
to get the correct r_count
value.
Peripheral drivers that are not interested in this information
should set the hacmd
member
to the value SCSI_NO_INFO
which is equal to ``FFh''.
Some adapter drivers in SCO UNIX System V Release 3.2
Operating System Version 2.0 and earlier
required that the hacmd
member be set to
indicate whether the target is a direct-access device or
a sequential-access device.
Direct-access (disk) devices were required to set
hacmd
to SCSI_DISK_INFO,
and sequential-access (tape) devices were required
to set hacmd
to SCSI_TAPE_INFO.
data_ptr
member must point to a
struct scsi_ha_info which will be filled in by the adapter.
The data_len
member should contain the size, in bytes,
of the scsi_ha_info structure.
If the adapter driver receives a command with the req_type member set to a value other than the ones above, it should return the value -1 and take no other action.
scsi_cmd
.
For those releases, the following members
of the scsi_io_req structure were reserved
and set to 0:
sense_len
, scsi_sense
,
link_ptr
, and link_id
.
The ODDI 4 (SCO OpenServer Release 5.0.4) Sdsk peripheral driver is changed to send
req_type = SCSI_INIT req_p->hacmd = SCSI_VER_INFOearly in its open(D2osdi) routine. This
hacmd
is a -1.
Some drivers are coded so that
if they don't understand the hacmd
value,
they may panic or fail.
To avoid this problem,
the driver should check for a
req_p->ext_p
value
so it can then provide the version info.
This change was implemented so that
the Sdsk driver can do its own read cap cmd
and pass that value to the HBA
when asking for the heads and sectors.
In earlier OSDI versions,
the Sdsk driver was asking for
disk heads and sectors from the HBA
and then doing it's own read capicty command
to figure out the disk geometry ( cylinders ).
This required the HBA vendor
to submit its own read capacity
so it could figure out the proper heads and sectors
if it changed with disk size.
The information is passed in an unused area of the
scsi_disk_info(D4osdi)
structure. If there
are non zero values there,
a driver can make use of them.
``Scatter/gather operations'' in HDK Technical Reference