分类: LINUX
2009-02-26 15:29:21
The Linux generic SCSI driver
有三种渠道访问SCSI设备:
1. 通过VFS
2. 通过Primary device names,比如/dev/sda1
3. 通过Generic driver device name,比如/dev/sg0
Primary device names:
SCSI CD-ROM /dev/scd0
SCSI DISK /dev/sda, /dev/sdb, /dev/sdc
Generic (sg) driver device names:
generic names /dev/sg0, /dev/sg1 or /dev/sga, /dev/sgb
两种名字之间的映射关系:
[root@itc-201044-xp sg3_utils-1.26]# sg_map -i
/dev/sg0 /dev/sda ATA Maxtor 6Y080M0 YAR5
[root@itc-201044-xp scsi_test]# lsmod |grep sg
sg 69993 0
scsi_mod 188665 3 sg,libata,sd_mod
Generic SCSI driver interface - /dev/sgX
Linux provides a generic driver for SCSI devices and an application programming interface so users can build applications to send SCSI commands directly to SCSI devices. Users can manually make SCSI commands and set other related parameters in an sg_io_hdr object, then call ioctl() to execute their SCSI commands and get output from the same sg_io_hdr object.
通过sg字符设备接口操作SCSI设备五个步骤:
1. Open the SCSI generic device file (such as sg1) to get the file descriptor of SCSI device.
2. Prepare the SCSI command.
3. Set related memory buffers.
4. Call the ioctl() function to execute the SCSI command,ioctl(fd,SG_IO,p_io_hdr);
5. Close the device file.
typedef struct sg_io_hdr{
int interface_id; /* [i] 'S' for SCSI generic (required) */
int dxfer_direction; /* [i] data transfer direction */
unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
unsigned char mx_sb_len; /* [i] max length to write to sbp */
unsigned short iovec_count; /* [i] 0 implies no scatter gather */
unsigned int dxfer_len; /* [i] byte count of data transfer */
void __user *dxferp; /* [i], [*io] points to data transfer memory or scatter gather list */
unsigned char __user *cmdp; /* [i], [*i] points to command to perform */
void __user *sbp; /* [i], [*o] points to sense_buffer memory */
unsigned int timeout; /* [i] MAX_UINT->no timeout (unit: millisec) */
unsigned int flags; /* [i] 0 -> default, see SG_FLAG... */
int pack_id; /* [i->o] unused internally (normally) */
void __user * usr_ptr; /* [i->o] unused internally */
unsigned char status; /* [o] scsi status */
unsigned char masked_status;/* [o] shifted, masked scsi status */
unsigned char msg_status; /* [o] messaging level data (optional) */
unsigned char sb_len_wr; /* [o] byte count actually written to sbp */
unsigned short host_status; /* [o] errors from host adapter */
unsigned short driver_status;/* [o] errors from software driver */
int resid; /* [o] dxfer_len - actual_transferred */
unsigned int duration; /* [o] time taken by cmd (unit: millisec) */
unsigned int info; /* [o] auxiliary information */
} sg_io_hdr_t; /* 64 bytes long (on i386) */