--- /dev/null Wed Oct 6 01:33:00 2004 +++ src/sys/cam/scsi/scsi_ufi.h Wed Oct 6 01:41:49 2004 @@ -0,0 +1,108 @@ +/* + * Structures and definitions for SCSI commands to UFI Floppy Devices, + * commonly used to format such devices. + * + * $FreeBSD$ + * + */ + +#ifndef _SCSI_SCSI_UFI_H +#define _SCSI_SCSI_UFI_H 1 + +#include + +/* + * Opcodes + */ +#define READ_FORMAT_CAPACITY 0x23 +#define WRITE_AND_VERIFY 0x2E /* XXX */ +#define VERIFY 0x2F /* XXX */ + +/* + * READ_FORMAT_CAPACITY cdbs are *always* 12 bytes long, + * and must contain the LUN, and the length of the returned + * format capacity list which the host is able to handle. + */ + +struct scsi_read_format_capacity +{ + uint8_t opcode; /* READ_FORMAT_CAPACITY */ + uint8_t lun; /* top 3 bits contain LUN */ + uint8_t unused00[4]; + uint8_t alloc_len[2]; /* always scsi i.e. big endian */ + uint8_t unused01[3]; +}; + +/* + * VERIFY is used to verify the physical disk medium. It is a 12-byte CDB. + * Replies to this come in through the usual sense key mechanism. + */ + +struct scsi_verify +{ + uint8_t opcode; /* VERIFY */ + uint8_t lun; /* All other bits should be zero */ +#define SVFY_RELADR 0x01 /* Always 0 for UFI. */ +#define SVFY_BYTECHK 0x02 /* Always 0 for UFI. */ +#define SVFY_DPO 0x10 /* Always 0 for UFI. */ +#define SVFY_LUN_MASK 0xE0 /* Top 3 MSBs are LUN */ + uint8_t addr[4]; /* LBA to begin verification at */ + uint8_t unused00[1]; + uint8_t len[4]; /* number of blocks to verify */ + uint8_t unused01[3]; +}; + +/* + * WRITE_AND_VERIFY writes a track and verifies it. + * Replies to this come in through the usual sense key mechanism. + */ + +struct scsi_write_and_verify +{ + uint8_t opcode; /* WRITE_AND_VERIFY */ + uint8_t lun; /* All other bits should be zero */ +#define SVFY_RELADR 0x01 /* Always 0 for UFI. */ +#define SVFY_BYTECHK 0x02 /* Always 0 for UFI. */ +#define SVFY_DPO 0x10 /* Always 0 for UFI. */ +#define SVFY_LUN_MASK 0xE0 /* Top 3 MSBs are LUN */ + uint8_t addr[4]; /* LBA to begin verification at */ + uint8_t unused00[1]; + uint8_t len[4]; /* number of blocks to write and verify */ + uint8_t unused01[3]; +}; + +/* + * Replies to READ_FORMAT_CAPACITY look like this: + * + * scsi_capacity_list_hdr + * scsi_capacity_descriptor (maximum/current) + * + * The appropriate csio_decode() format string looks like this: + * "{} *i3 {Len} i1 {Blocks} i4 {} *b6 {Code} b2 {Blocklen} i3" + * + * If the capacity list header length is greater than + * sizeof(struct format_capacity_descriptor), then there are + * additional format capacity descriptors available which + * denote which format(s) the drive can handle. + * + */ + +struct format_capacity_list_header { + uint8_t unused[3]; + uint8_t capacity_list_length; +}; + +struct format_capacity_descriptor { + uint8_t num_blocks[4]; /* total number of LBAs */ + uint8_t code; /* only present in max/cur descriptor */ +#define FCD_CODE_MASK 0x03 /* mask for code field above */ +#define FCD_UNFORMATTED 0x01 /* unformatted media present, + * maximum capacity returned */ +#define FCD_FORMATTED 0x02 /* formatted media present, + * current capacity returned */ +#define FCD_NOMEDIA 0x03 /* no media present, + * maximum device capacity returned */ + uint8_t block_len[3]; /* length of an LBA in bytes */ +}; + +#endif /* _SCSI_SCSI_UFI_H */