diff options
Diffstat (limited to 'sys')
-rw-r--r-- | sys/cam/scsi/scsi_da.c | 59 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_da.h | 39 |
2 files changed, 89 insertions, 9 deletions
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 9bc83b1..c59694b 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -3878,9 +3878,9 @@ dashutdown(void * arg, int howto) #else /* !_KERNEL */ /* - * XXX This is only left out of the kernel build to silence warnings. If, - * for some reason this function is used in the kernel, the ifdefs should - * be moved so it is included both in the kernel and userland. + * XXX These are only left out of the kernel build to silence warnings. If, + * for some reason these functions are used in the kernel, the ifdefs should + * be moved so they are included both in the kernel and userland. */ void scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries, @@ -3909,6 +3909,59 @@ scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries, } void +scsi_read_defects(struct ccb_scsiio *csio, uint32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + uint8_t tag_action, uint8_t list_format, + uint32_t addr_desc_index, uint8_t *data_ptr, + uint32_t dxfer_len, int minimum_cmd_size, + uint8_t sense_len, uint32_t timeout) +{ + uint8_t cdb_len; + + /* + * These conditions allow using the 10 byte command. Otherwise we + * need to use the 12 byte command. + */ + if ((minimum_cmd_size <= 10) + && (addr_desc_index == 0) + && (dxfer_len <= SRDD10_MAX_LENGTH)) { + struct scsi_read_defect_data_10 *cdb10; + + cdb10 = (struct scsi_read_defect_data_10 *) + &csio->cdb_io.cdb_bytes; + + cdb_len = sizeof(*cdb10); + bzero(cdb10, cdb_len); + cdb10->opcode = READ_DEFECT_DATA_10; + cdb10->format = list_format; + scsi_ulto2b(dxfer_len, cdb10->alloc_length); + } else { + struct scsi_read_defect_data_12 *cdb12; + + cdb12 = (struct scsi_read_defect_data_12 *) + &csio->cdb_io.cdb_bytes; + + cdb_len = sizeof(*cdb12); + bzero(cdb12, cdb_len); + cdb12->opcode = READ_DEFECT_DATA_12; + cdb12->format = list_format; + scsi_ulto4b(dxfer_len, cdb12->alloc_length); + scsi_ulto4b(addr_desc_index, cdb12->address_descriptor_index); + } + + cam_fill_csio(csio, + retries, + cbfcnp, + /*flags*/ CAM_DIR_IN, + tag_action, + data_ptr, + dxfer_len, + sense_len, + cdb_len, + timeout); +} + +void scsi_sanitize(struct ccb_scsiio *csio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, u_int8_t byte2, u_int16_t control, diff --git a/sys/cam/scsi/scsi_da.h b/sys/cam/scsi/scsi_da.h index 9e5563d..ad4d0db 100644 --- a/sys/cam/scsi/scsi_da.h +++ b/sys/cam/scsi/scsi_da.h @@ -98,8 +98,12 @@ struct scsi_read_defect_data_10 #define SRDD10_PLIST 0x10 #define SRDD10_DLIST_FORMAT_MASK 0x07 #define SRDD10_BLOCK_FORMAT 0x00 +#define SRDD10_EXT_BFI_FORMAT 0x01 +#define SRDD10_EXT_PHYS_FORMAT 0x02 +#define SRDD10_LONG_BLOCK_FORMAT 0x03 #define SRDD10_BYTES_FROM_INDEX_FORMAT 0x04 #define SRDD10_PHYSICAL_SECTOR_FORMAT 0x05 +#define SRDD10_VENDOR_FORMAT 0x06 uint8_t format; uint8_t reserved[4]; uint8_t alloc_length[2]; @@ -138,12 +142,13 @@ struct scsi_read_defect_data_12 #define SRDD12_GLIST 0x08 #define SRDD12_PLIST 0x10 #define SRDD12_DLIST_FORMAT_MASK 0x07 -#define SRDD12_BLOCK_FORMAT 0x00 -#define SRDD12_BYTES_FROM_INDEX_FORMAT 0x04 -#define SRDD12_PHYSICAL_SECTOR_FORMAT 0x05 +#define SRDD12_BLOCK_FORMAT SRDD10_BLOCK_FORMAT +#define SRDD12_BYTES_FROM_INDEX_FORMAT SRDD10_BYTES_FROM_INDEX_FORMAT +#define SRDD12_PHYSICAL_SECTOR_FORMAT SRDD10_PHYSICAL_SECTOR_FORMAT uint8_t format; uint8_t address_descriptor_index[4]; uint8_t alloc_length[4]; +#define SRDD12_MAX_LENGTH 0xffffffff uint8_t reserved; uint8_t control; }; @@ -325,6 +330,8 @@ struct scsi_read_defect_data_hdr_10 #define SRDDH10_PHYSICAL_SECTOR_FORMAT 0x05 u_int8_t format; u_int8_t length[2]; +#define SRDDH10_MAX_LENGTH SRDD10_MAX_LENGTH - \ + sizeof(struct scsi_read_defect_data_hdr_10) }; struct scsi_defect_desc_block @@ -332,10 +339,18 @@ struct scsi_defect_desc_block u_int8_t address[4]; }; +struct scsi_defect_desc_long_block +{ + u_int8_t address[8]; +}; + struct scsi_defect_desc_bytes_from_index { u_int8_t cylinder[3]; u_int8_t head; +#define SDD_EXT_BFI_MADS 0x80000000 +#define SDD_EXT_BFI_FLAG_MASK 0xf0000000 +#define SDD_EXT_BFI_ENTIRE_TRACK 0x0fffffff u_int8_t bytes_from_index[4]; }; @@ -343,6 +358,9 @@ struct scsi_defect_desc_phys_sector { u_int8_t cylinder[3]; u_int8_t head; +#define SDD_EXT_PHYS_MADS 0x80000000 +#define SDD_EXT_PHYS_FLAG_MASK 0xf0000000 +#define SDD_EXT_PHYS_ENTIRE_TRACK 0x0fffffff u_int8_t sector[4]; }; @@ -358,6 +376,8 @@ struct scsi_read_defect_data_hdr_12 u_int8_t format; u_int8_t generation[2]; u_int8_t length[4]; +#define SRDDH12_MAX_LENGTH SRDD12_MAX_LENGTH - \ + sizeof(struct scsi_read_defect_data_hdr_12) }; union disk_pages /* this is the structure copied from osf */ @@ -536,9 +556,9 @@ struct scsi_da_rw_recovery_page { __BEGIN_DECLS /* - * XXX This is only left out of the kernel build to silence warnings. If, - * for some reason this function is used in the kernel, the ifdefs should - * be moved so it is included both in the kernel and userland. + * XXX These are only left out of the kernel build to silence warnings. If, + * for some reason these functions are used in the kernel, the ifdefs should + * be moved so they are included both in the kernel and userland. */ #ifndef _KERNEL void scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries, @@ -547,6 +567,13 @@ void scsi_format_unit(struct ccb_scsiio *csio, u_int32_t retries, u_int8_t *data_ptr, u_int32_t dxfer_len, u_int8_t sense_len, u_int32_t timeout); +void scsi_read_defects(struct ccb_scsiio *csio, uint32_t retries, + void (*cbfcnp)(struct cam_periph *, union ccb *), + uint8_t tag_action, uint8_t list_format, + uint32_t addr_desc_index, uint8_t *data_ptr, + uint32_t dxfer_len, int minimum_cmd_size, + uint8_t sense_len, uint32_t timeout); + void scsi_sanitize(struct ccb_scsiio *csio, u_int32_t retries, void (*cbfcnp)(struct cam_periph *, union ccb *), u_int8_t tag_action, u_int8_t byte2, u_int16_t control, |