summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
Diffstat (limited to 'sys')
-rw-r--r--sys/cam/scsi/scsi_da.c59
-rw-r--r--sys/cam/scsi/scsi_da.h39
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,
OpenPOWER on IntegriCloud