2021-06-26 21:25:18

by Igor Kononenko

[permalink] [raw]
Subject: [PATCH 5/6] FMS: Add the SCSI Get Configuration command.

The SCSI Get Configuration command is required to obtain information
about a CD/DVD/BL device (MMC-6, 6.5 GET CONFIGURATION Command).

The aforementioned ability will be expected by several multimedia
consumers, such as OS MS Windows, OS ESXi, etc., for selecting the
appropriate FS driver.

End-user-impact: The FMS devices consumers can now retrieve their
capabilities.
FMS supports the ISO-13346(UDF) multimedia file systems

Signed-off-by: Igor Kononenko <[email protected]>
---
drivers/ata/libata-zpodd.c | 8 +-
drivers/usb/gadget/function/f_mass_storage.c | 222 +++++
include/scsi/scsi_proto.h | 1 +
include/uapi/linux/cdrom.h | 844 ++++++++++++++++++-
4 files changed, 1041 insertions(+), 34 deletions(-)

diff --git a/drivers/ata/libata-zpodd.c b/drivers/ata/libata-zpodd.c
index eefda51f97d3..e49ff795a506 100644
--- a/drivers/ata/libata-zpodd.c
+++ b/drivers/ata/libata-zpodd.c
@@ -54,7 +54,7 @@ static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev)
{
char *buf;
unsigned int ret;
- struct rm_feature_desc *desc;
+ struct cdf_removable_medium *desc;
struct ata_taskfile tf;
static const char cdb[ATAPI_CDB_LEN] = { GPCMD_GET_CONFIGURATION,
2, /* only 1 feature descriptor requested */
@@ -82,15 +82,15 @@ static enum odd_mech_type zpodd_get_mech_type(struct ata_device *dev)
return ODD_MECH_TYPE_UNSUPPORTED;
}

- if (be16_to_cpu(desc->feature_code) != 3) {
+ if (be16_to_cpu(desc->code) != 3) {
kfree(buf);
return ODD_MECH_TYPE_UNSUPPORTED;
}

- if (desc->mech_type == 0 && desc->load == 0 && desc->eject == 1) {
+ if (desc->mechanism == 0 && desc->load == 0 && desc->eject == 1) {
kfree(buf);
return ODD_MECH_TYPE_SLOT;
- } else if (desc->mech_type == 1 && desc->load == 0 &&
+ } else if (desc->mechanism == 1 && desc->load == 0 &&
desc->eject == 1) {
kfree(buf);
return ODD_MECH_TYPE_DRAWER;
diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c
index 4865937799aa..7e736e5594f9 100644
--- a/drivers/usb/gadget/function/f_mass_storage.c
+++ b/drivers/usb/gadget/function/f_mass_storage.c
@@ -366,6 +366,87 @@ struct cdb_handler {
/* SCSI command ASCII name */
char *name;
};
+/*-------------------------------------------------------------------------*/
+
+#define CDF_PROFILES_COUNT (ARRAY_SIZE(cdf_supported_profiles))
+
+/* List of supported profiles */
+static struct mmc_profile cdf_supported_profiles[] = {
+ { .profile = cpu_to_be16(MMC_PROFILE_BD_ROM) },
+ { .profile = cpu_to_be16(MMC_PROFILE_DVD_ROM) },
+ { .profile = cpu_to_be16(MMC_PROFILE_CD_ROM) },
+};
+
+struct cdf_profile_list_custom {
+ struct cdf_profile_list header;
+ /* We support several profiles, whose indices are declared in the
+ * enum above
+ */
+ struct mmc_profile profiles[CDF_PROFILES_COUNT];
+} __packed;
+
+/**
+ * Type to allocate of all supported features
+ * @param populate - callback to fill the specified feature data which
+ * is depended by medium
+ */
+struct cdr_features;
+struct cdr_features {
+ union {
+ struct cdf_profile_list_custom profile_list;
+ struct cdf_core core;
+ struct cdf_morphing morphing;
+ struct cdf_removable_medium removable;
+ struct cdf_random_readable random_readable;
+ struct cdf_multi_read multi_read;
+ struct cdf_cd_read cd_read;
+ struct cdf_dvd_read dvd_read;
+ struct cdf_rt_streaming rt_streaming;
+ } __packed feature;
+ void (*populate)(struct fsg_common *common,
+ struct cdr_features **features);
+};
+
+/**
+ * @brief Adjust the Profile List members of actual data which is depended
+ * on the inserted medium image
+ *
+ * @param common - the FSG instance
+ * @param feature - a list of profile descriptors which to be configured
+ */
+static void cdf_populate_profile_list(struct fsg_common *common,
+ struct cdr_features **feature);
+
+#define CDF_SET_VPC(v, p, c) .vpc = { .ver = (v), .per = (p), .cur = (c) }
+
+#define CDF_FT_SIZE(member) \
+ ((sizeof(((struct cdr_features *)0)->feature.member)) - \
+ sizeof(struct cdb_ft_generic))
+
+#define CDR_FT_ITEM(item, c, ...) \
+ CDR_FT_ITEM_S(item, c, CDF_FT_SIZE(item), __VA_ARGS__)
+
+#define CDR_FT_ITEM_S(item, c, s, ...) \
+ .feature.item = { .code = cpu_to_be16(c), .length = (s), __VA_ARGS__ }
+
+static struct cdr_features features_table[] = {
+ { CDR_FT_ITEM_S(profile_list.header, CDF_PROFILE_LIST_CODE,
+ CDF_FT_SIZE(profile_list), CDF_SET_VPC(0, 1, 1)),
+ .populate = &cdf_populate_profile_list },
+ { CDR_FT_ITEM(core, CDF_CORE, CDF_SET_VPC(2, 1, 1), .dbevent = 1,
+ .interface = cpu_to_be32(CF_PIS_USB)) },
+ { CDR_FT_ITEM(morphing, CDF_MORPHING_CODE, CDF_SET_VPC(1, 1, 1),
+ .ocevent = 1) },
+ { CDR_FT_ITEM(removable, CDF_REMOVEBLE_MEDIA, CDF_SET_VPC(2, 1, 1),
+ .mechanism = CDF_LMT__TRAY_TYPE, .eject = 1, .lock = 1) },
+ { CDR_FT_ITEM(random_readable, CDF_RANDOM_READ, CDF_SET_VPC(0, 0, 1),
+ .block_size = cpu_to_be32(CD_FRAMESIZE),
+ .blocking = cpu_to_be16(0x10), .pp = 1) },
+ { CDR_FT_ITEM(dvd_read, CDF_DVD_READ, CDF_SET_VPC(2, 1, 1),
+ .multi110 = 1, .dualr = 1) },
+ { CDR_FT_ITEM(rt_streaming, CDF_REAL_TIME_STREAM, CDF_SET_VPC(5, 0, 1),
+ .rbcb = 1, .scs = 1, .mp2a = 1, .wspd = 1, .sw = 1) },
+};

/*------------------------------------------------------------------------*/

@@ -1851,6 +1932,143 @@ static void send_status(struct fsg_common *common)
return;
}

+/**
+ * Attempts to guess medium type by looking at the length of the disc layout.
+ */
+static inline __be16 cdr_guess_medium_type(struct fsg_common *common)
+{
+ struct fsg_lun *curlun = common->curlun;
+ size_t length = curlun->num_sectors;
+
+ if (length <= CD_MAX_FRAMES) {
+ LDBG(curlun, "Disc layout size implies CD-ROM image\n");
+ return MMC_PROFILE_CD_ROM;
+ } else if (length <= CD_DVD_MAX_FRAMES) {
+ LDBG(curlun,
+ "Disc layout size implies single-layer DVD-ROM image\n");
+ return MMC_PROFILE_DVD_ROM;
+ } else if (length <= CD_DVDDL_MAX_FRAMES) {
+ LDBG(curlun,
+ "Disc layout size implies dual-layer DVD-ROM image\n");
+ return MMC_PROFILE_DVD_ROM;
+ } else if (length <= CD_BD_MAX_FRAMES) {
+ LDBG(curlun,
+ "Disc layout size implies single-layer BD-ROM image\n");
+ return MMC_PROFILE_BD_ROM;
+ } else if (length <= CD_BDDL_MAX_FRAMES) {
+ LDBG(curlun,
+ "Disc layout size implies dual-layer BD-ROM image\n");
+ return MMC_PROFILE_BD_ROM;
+ }
+
+ LDBG(curlun,
+ "Disc layout size (%u) exceeds all known media types, assuming BD - ROM !\n",
+ length);
+ return MMC_PROFILE_BD_ROM;
+}
+
+/* Adjust current profile which depended on an inserted medium */
+static inline void cdf_populate_profile_list(struct fsg_common *common,
+ struct cdr_features **feature)
+{
+ __be16 current_media_type = cdr_guess_medium_type(common);
+ struct mmc_profile *profiles =
+ (*feature)->feature.profile_list.profiles;
+ int i;
+
+ /* copy profile list to the response buffer */
+ memcpy(profiles, cdf_supported_profiles,
+ sizeof(cdf_supported_profiles));
+ for (i = 0; i < CDF_PROFILES_COUNT; ++i) {
+ /*
+ * Reset the current profile bit,
+ * because it might be set from the previous one
+ */
+ profiles[i].current_p = 0;
+ if (be16_to_cpu(profiles[i].profile) == current_media_type) {
+ DBG(common, "Fill current profile: curr=(%04Xh)\n",
+ be16_to_cpu(profiles[i].profile));
+ profiles[i].current_p = 1;
+ }
+ }
+}
+
+static int do_get_configuration(struct fsg_common *common,
+ struct fsg_buffhd *bh)
+{
+ struct fsg_lun *curlun = common->curlun;
+ int i;
+ struct cdb_get_configuration *cdb =
+ (struct cdb_get_configuration *)common->cmnd;
+ size_t buffer_size = sizeof(struct feature_header);
+ size_t generic_desc_size = sizeof(struct cdb_ft_generic);
+ struct feature_header *ret_header = (struct feature_header *)bh->buf;
+ u8 *ret_data = ((u8 *)ret_header) + buffer_size;
+
+ LDBG(curlun, "Requesting features from 0x%04X, with RT flag 0x%02X\n",
+ be16_to_cpu(cdb->sfn), cdb->rt);
+
+ if (!common->curlun || !common->curlun->cdrom)
+ return -EINVAL;
+
+ /* Go over *all* features, and copy them according to RT value */
+ for (i = 0; i < ARRAY_SIZE(features_table); ++i) {
+ struct cdb_ft_generic *generic =
+ (struct cdb_ft_generic *)&features_table[i];
+ struct cdr_features *feature = &features_table[i];
+
+ if (feature->populate != NULL)
+ feature->populate(common, &feature);
+
+ // a) RT is 0x00 and feature's code >= SFN
+ // b) RT is 0x01, feature's code >= SFN and feature has 'current' bit set
+ // c) RT is 0x02 and feature's code == SFN
+
+ if (be16_to_cpu(generic->code) >= be16_to_cpu(cdb->sfn)) {
+ if ((cdb->rt == CDR_CFG_RT_FULL) ||
+ (cdb->rt == CDR_CFG_RT_CURRENT &&
+ generic->vpc.cur) ||
+ (cdb->rt == CDR_CFG_RT_SPECIFIED_SFN &&
+ be16_to_cpu(generic->code) ==
+ be16_to_cpu(cdb->sfn))) {
+ LDBG(curlun, "Copying feature 0x%04X\n",
+ be16_to_cpu(generic->code));
+
+ memset(ret_data, 0,
+ (generic->length + generic_desc_size));
+ /* Copy feature */
+ memcpy(ret_data, feature,
+ (generic->length + generic_desc_size));
+ buffer_size +=
+ (generic->length + generic_desc_size);
+ ret_data +=
+ (generic->length + generic_desc_size);
+
+ /* Break the loop if RT is CDR_CFG_RT_SPECIFIED_SFN */
+ if (cdb->rt == CDR_CFG_RT_SPECIFIED_SFN) {
+ LDBG(curlun,
+ "Got the feature we wanted (0x%04X), breaking the loop\n",
+ be16_to_cpu(cdb->sfn));
+ break;
+ }
+ }
+ }
+ }
+
+ memset(ret_header, 0, sizeof(struct feature_header));
+ /* Header */
+ ret_header->data_len = cpu_to_be32(buffer_size - generic_desc_size);
+ ret_header->curr_profile =
+ cpu_to_be16(cdr_guess_medium_type(common));
+
+ dump_msg(common, "feature header", (u8 *)ret_header,
+ sizeof(struct feature_header));
+
+ dump_msg(common, "features table", (u8 *)bh->buf, buffer_size);
+
+ common->data_size_to_handle = buffer_size;
+ return 0;
+}

/*-------------------------------------------------------------------------*/

@@ -2035,6 +2253,9 @@ static struct cdb_command_check cdb_checker_table[] = {
{ CDB_REG_CHECKER(TEST_UNIT_READY, 6, CDB_NO_SIZE_FIELD, DATA_DIR_NONE,
0x0000, MEDIUM_REQUIRED) },

+ { CDB_REG_NO_CHECKER(GET_CONFIGURATION, CDB_SIZE_FIELD_7,
+ DATA_DIR_TO_HOST, MEDIUM_REQUIRED) },
+
{ CDB_REG_CHECKER_BLK(VERIFY, 10, CDB_NO_SIZE_FIELD, DATA_DIR_NONE,
0x0000, MEDIUM_REQUIRED) },
{ CDB_REG_CHECKER_BLK(WRITE_6, 6, CDB_SIZE_FIELD_4, DATA_DIR_FROM_HOST,
@@ -2065,6 +2286,7 @@ static struct cdb_handler cdb_handlers_table[] = {
{ CDB_REG_HANDLER(SYNCHRONIZE_CACHE, &do_synchronize_cache) },
{ CDB_REG_HANDLER(TEST_UNIT_READY, NULL) },

+ { CDB_REG_HANDLER_BUFFHD(GET_CONFIGURATION, &do_get_configuration) },
/*
* Although optional, this command is used by MS-Windows. We
* support a minimal version: BytChk must be 0.
diff --git a/include/scsi/scsi_proto.h b/include/scsi/scsi_proto.h
index c36860111932..6b2a8ee1f0a3 100644
--- a/include/scsi/scsi_proto.h
+++ b/include/scsi/scsi_proto.h
@@ -73,6 +73,7 @@
#define UNMAP 0x42
#define READ_TOC 0x43
#define READ_HEADER 0x44
+#define GET_CONFIGURATION 0x46
#define GET_EVENT_STATUS_NOTIFICATION 0x4a
#define LOG_SELECT 0x4c
#define LOG_SENSE 0x4d
diff --git a/include/uapi/linux/cdrom.h b/include/uapi/linux/cdrom.h
index 1d7b4333c3aa..442693fdc059 100644
--- a/include/uapi/linux/cdrom.h
+++ b/include/uapi/linux/cdrom.h
@@ -349,6 +349,12 @@ struct cdrom_generic_command
/* most drives don't deliver everything: */
#define CD_FRAMESIZE_RAW1 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE) /*2340*/
#define CD_FRAMESIZE_RAW0 (CD_FRAMESIZE_RAW-CD_SYNC_SIZE-CD_HEAD_SIZE) /*2336*/
+/* total frames on the specific medium-disk format */
+#define CD_MAX_FRAMES (CD_MINS * CD_SECS * CD_FRAMES)
+#define CD_DVD_MAX_FRAMES (2295104)
+#define CD_DVDDL_MAX_FRAMES (4173824)
+#define CD_BD_MAX_FRAMES (12219392)
+#define CD_BDDL_MAX_FRAMES (24438784)

#define CD_XA_HEAD (CD_HEAD_SIZE+CD_SUBHEAD_SIZE) /* "before data" part of raw XA frame */
#define CD_XA_TAIL (CD_EDC_SIZE+CD_ECC_SIZE) /* "after data" part of raw XA frame */
@@ -896,12 +902,173 @@ typedef struct {
__be32 last_rec_address;
} track_information;

+/* CDB Get Configuration command */
+
+/**
+ * The Drive shall return the Feature Header and all Feature Descriptors supported by the
+ * Drive without regard to currency
+ */
+#define CDR_CFG_RT_FULL 0x00
+/**
+ * The Drive shall return the Feature Header and only those Feature Descriptors in which
+ * the Current bit is set to one.
+ */
+#define CDR_CFG_RT_CURRENT 0x01
+/**
+ * The Feature Header and the Feature Descriptor identified by Starting Feature Number
+ * shall be returned. If the Drive does not support the specified feature, only the Feature
+ * Header shall be returned.
+ */
+#define CDR_CFG_RT_SPECIFIED_SFN 0x02
+#define CDR_CFG_RT_RESERVED 0x03
+
+/**
+ * @brief GET CONFIGURATION Command
+ * The GET CONFIGURATION command provides a Host with information about Drive capabilities;
+ * both current and potential.
+ *
+ * @note The command shall not return a CHECK CONDITION Status due to a pending
+ * UNIT ATTENTION Condition.
+ */
+struct cdb_get_configuration {
+ __u8 code;
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved1 : 6;
+ /* The RT field identifies the type of data to be returned by the Drive */
+ __u8 rt : 2;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 rt : 2;
+ __u8 reserved1 : 6;
+#endif
+ /**
+ * The Starting Feature Number field indicates the first Feature number to be returned.
+ * All supported Feature numbers higher than the Starting Feature Number shall be
+ * returned.
+ */
+ __be16 sfn;
+ __u8 reserved2[3];
+ /**
+ * The Allocation Length field specifies the maximum length in bytes of the
+ * Get Configuration response data. An Allocation Length field of zero indicates that no
+ * data shall be transferred
+ */
+ __be16 length;
+ __u8 control;
+
+} __packed;
+
+/* Features */
+
+/* Feature and Profile Descriptors*/
+
+/**
+ * @brief The Version, Persisten and Current byte.
+ * This structure is required for many CDB features.
+ */
+struct cdb_ft_vpc_byte {
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved1 : 2;
+ /**
+ * The Version field is reserved and shall be set to zero unless otherwise specified
+ * within the Feature Description
+ */
+ __u8 ver : 4;
+ /**
+ * The Persistent bit, when set to zero, shall indicate that this Feature may change
+ * its current status.
+ * When set to one, shall indicate that this Feature is always active.
+ * The Drive shall not set this bit to one if the Current bit is, or may become, zero.
+ */
+ __u8 per : 1;
+ /**
+ * The Current bit, when set to zero, indicates that this Feature is not currently
+ * active and that the Feature Dependent Data may not be valid.
+ * When set to one, this Feature is currently active and the Feature Dependent Data is
+ * valid.
+ */
+ __u8 cur : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 cur : 1;
+ __u8 per : 1;
+ __u8 ver : 4;
+ __u8 reserved1 : 2;
+#endif
+} __packed;
+
+/**
+ * @brief Feature Descriptor generic
+ * A Feature Descriptor shall describe each Feature supported by a Drive. All
+ * Feature descriptors shall be a multiple of four bytes
+ */
+struct cdb_ft_generic {
+ /**
+ * The Feature Code field shall identify a Feature supported by the Drive
+ */
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+
+ /**
+ * The Additional Length field indicates the number of Feature specific
+ * bytes that follow this header. This field shall be an integral multiple
+ * of 4
+ */
+ __u8 length;
+} __packed;
+
+/* Profile list */
+#define MMC_PROFILE_NONE 0x0000
+#define MMC_PROFILE_CD_ROM 0x0008
+#define MMC_PROFILE_CD_R 0x0009
+#define MMC_PROFILE_CD_RW 0x000A
+#define MMC_PROFILE_DVD_ROM 0x0010
+#define MMC_PROFILE_DVD_R_SR 0x0011
+#define MMC_PROFILE_DVD_RAM 0x0012
+#define MMC_PROFILE_DVD_RW_RO 0x0013
+#define MMC_PROFILE_DVD_RW_SR 0x0014
+#define MMC_PROFILE_DVD_R_DL_SR 0x0015
+#define MMC_PROFILE_DVD_R_DL_JR 0x0016
+#define MMC_PROFILE_DVD_RW_DL 0x0017
+#define MMC_PROFILE_DVD_DDR 0x0018
+#define MMC_PROFILE_DVD_PLUS_RW 0x001A
+#define MMC_PROFILE_DVD_PLUS_R 0x001B
+#define MMC_PROFILE_DVD_PLUS_RW_DL 0x002A
+#define MMC_PROFILE_DVD_PLUS_R_DL 0x002B
+#define MMC_PROFILE_BD_ROM 0x0040
+#define MMC_PROFILE_BD_R_SRM 0x0041
+#define MMC_PROFILE_BD_R_RRM 0x0042
+#define MMC_PROFILE_BD_RE 0x0043
+#define MMC_PROFILE_HDDVD_ROM 0x0050
+#define MMC_PROFILE_HDDVD_R 0x0051
+#define MMC_PROFILE_HDDVD_RAM 0x0052
+#define MMC_PROFILE_HDDVD_RW 0x0053
+#define MMC_PROFILE_HDDVD_R_DL 0x0058
+#define MMC_PROFILE_HDDVD_RW_DL 0x005A
+#define MMC_PROFILE_INVALID 0xFFFF
+
+/**
+ * @brief The CDB Feature Header
+ * Response data consists of a header field and zero or more variable length
+ * Feature descriptors
+ */
struct feature_header {
+ /**
+ * The Data Length field indicates the amount of data available given a
+ * sufficient allocation length following this field.
+ * This length shall not be truncated due to an insufficient Allocation
+ * Length
+ */
__u32 data_len;
__u8 reserved1;
__u8 reserved2;
+ /**
+ * The Current Profile field shall identify one of the profiles from the
+ * Profile List Feature. If there are no Profiles currently active, this
+ * field shall contain zero.
+ */
__u16 curr_profile;
-};
+} __packed;

struct mode_page_header {
__be16 mode_data_length;
@@ -912,41 +1079,658 @@ struct mode_page_header {
__be16 desc_length;
};

-/* removable medium feature descriptor */
-struct rm_feature_desc {
- __be16 feature_code;
+/**
+ * @brief Profile descriptors are returned in the order of preferred
+ * operation – most desirable to least desirable. e.g., a DVD-ROM
+ * that is also able to read a CD-ROM should list the DVD-ROM
+ * Profile first and the CD-ROM Profile second.
+ */
+struct mmc_profile {
+ /* The Profile Number identifies a Profile */
+ __be16 profile;
+
#if defined(__BIG_ENDIAN_BITFIELD)
- __u8 reserved1:2;
- __u8 feature_version:4;
- __u8 persistent:1;
- __u8 curr:1;
+ __u8 reserved1 : 7;
+ /**
+ * The current_p bit, when set to one, shall indicate that this
+ * Profile is currently active.
+ */
+ __u8 current_p : 1;
#elif defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 curr:1;
- __u8 persistent:1;
- __u8 feature_version:4;
- __u8 reserved1:2;
-#endif
- __u8 add_len;
-#if defined(__BIG_ENDIAN_BITFIELD)
- __u8 mech_type:3;
- __u8 load:1;
- __u8 eject:1;
- __u8 pvnt_jmpr:1;
- __u8 dbml:1;
- __u8 lock:1;
-#elif defined(__LITTLE_ENDIAN_BITFIELD)
- __u8 lock:1;
- __u8 dbml:1;
- __u8 pvnt_jmpr:1;
- __u8 eject:1;
- __u8 load:1;
- __u8 mech_type:3;
+ __u8 current_p : 1;
+ __u8 reserved1 : 7;
#endif
+
__u8 reserved2;
- __u8 reserved3;
- __u8 reserved4;
+} __packed;
+
+/**
+ * @brief Profile List Feature (0000h)
+ *
+ * This Feature identifies Profiles supported by the Drive.
+ * Profiles are defined as collections of Features and provide a method
+ * to quickly determine the Drive’s type.
+ */
+struct cdf_profile_list {
+ /* The Feature Code */
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+ /**
+ * The Additional Length field shall be set
+ * to ((number of Profile Descriptors) * 4).
+ */
+ __u8 length;
+} __packed;
+
+/**
+ * @brief The core feature: phisycal interface standards
+ */
+enum cdf_cf_pis {
+ CF_PIS_UNSPECIFIED = 0x00000000U,
+ CF_PIS_SCSI_FAMILY,
+ CF_PIS_ATAPI,
+ CF_PIS_IEEE_1394_1995,
+ CF_PIS_IEEE_1394A,
+ CF_PIS_FIBRE_CHANNEL,
+ CF_PIS_IEEE_1394_B,
+ CF_PIS_USB,
+ CF_PIS_RESERVED,
+ CF_PIS_DEF_INCITS = 0x00010000U,
+ CF_PIS_DEF_SFF = 0x00020000U,
+ CF_PIS_DEF_IEEE = 0x00030000U,
+ CF_PIS_DEF_RESERVED = 0x00040000U
};

+/**
+ * @brief Core Feature (0001h)
+ * This Feature identifies a Drive that supports functionality common
+ * to all devices.
+ */
+struct cdf_core {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+
+ /* The Additional Length field shall be set to 8. */
+ __u8 length;
+ /**
+ * The Physical Interface Standard field shall be set to a value
+ * selected from @enum cdf_cf_pis
+ * It is possible that more than one physical interface exists
+ * between the Host and Drive, e.g., an IEEE1394 Host connecting
+ * to an ATAPI bridge to an ATAPI Drive. The Drive may not be aware
+ * of interfaces beyond the ATAPI.
+ */
+ __be32 interface;
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved2 : 6;
+ /**
+ * The INQ2 bit permits the Drive to indicate support for certain
+ * features of the INQUIRY command. If INQ2 is set to one, the
+ * Drive shall support validation of EVPD, Page Code, and the
+ * 16-bit Allocation Length fields
+ */
+ __u8 inq2 : 1;
+ /**
+ * DBE (Device Busy Event) shall be set to one.
+ */
+ __u8 dbevent : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 dbevent : 1;
+ __u8 inq2 : 1;
+ __u8 reserved2 : 6;
+#endif
+
+ __u8 reserved3[3];
+} __packed;
+
+/**
+ * @brief Morphing Feature (0002h)
+ * This Feature identifies the ability of the Drive to notify
+ * A Host about operational changes and accept Host requests to
+ * prevent operational changes.
+ */
+struct cdf_morphing {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+
+ __u8 length;
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved2 : 6;
+ __u8 ocevent : 1;
+ __u8 async : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 async : 1;
+ __u8 ocevent : 1;
+ __u8 reserved2 : 6;
+#endif
+
+ __u8 reserved3[3];
+} __packed;
+
+/**
+ * @brief Removable Medium: Loading Mechanism Types
+ */
+enum cdf_removable_media_lmt {
+ CDF_LMT__CADDY_SLOT_TYPE,
+ CDF_LMT__TRAY_TYPE,
+ CDF_LMT__POP_UP_TYPE,
+ CDF_LMT__RESERVED1,
+ CDF_LMT__EMBEDDED_INDIVIDUALLY,
+ CDF_LMT__EMBEDDED_MAGAZINE,
+ CDF_LMT__RESERVED2,
+};
+
+/**
+ * @brief Removable Medium Feature (0003h)
+ *
+ * This Feature identifies a Drive that has a medium that is removable.
+ * Media shall be considered removable if it is possible to remove it
+ * from the loaded position, i.e., a single mechanism changer, even if
+ * the media is captive to the changer.
+ *
+ * The Drive shall generate Events for media changes.
+ * Event Notification Class 4 (Media Events) shall be supported. This
+ * includes reporting user requests to load/eject the medium.
+ */
+struct cdf_removable_medium {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+ /* The Additional Length field shall be set to 4. */
+ __u8 length;
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+ /**
+ * The Loading Mechanism Type field shall be set according to
+ * @enum cdf_removable_media_lmt
+ */
+ __u8 mechanism : 3;
+ /**
+ * If the Load bit is set to zero, the Drive is unable to load
+ * the medium or cartridge via the START STOP UNIT command with
+ * the LoEj bit set to one, e.g. the tray type loading mechanism
+ * that is found in many portable PCs.
+ * If the Load bit is set to one, the Drive is able to load the
+ * medium or cartridge.
+ */
+ __u8 load : 1;
+ /**
+ * The Eject bit, when set to zero, indicates that the device is
+ * unable to eject the medium or magazine via the normal START STOP UNIT
+ * command with the LoEj bit set.
+ * When set to one, indicates that the device is able to eject
+ * the medium or magazine.
+ */
+ __u8 eject : 1;
+ /**
+ * The Pvnt Jmpr bit, when set to zero, shall indicate that the
+ * Prevent Jumper is present.
+ * When set to one, the Prevent Jumper is not present.
+ * The Pvnt Jmpr bit shall not change state, even if the physical
+ * jumper is added or removed during operation.
+ */
+ __u8 prvnt_jmp : 1;
+ __u8 reserved2 : 1;
+ /**
+ * If Lock is set to zero, there is no locking mechanism for locking
+ * the medium into the Drive. If Lock is set to one, the Drive is
+ * capable of locking the media into the Drive.
+ */
+ __u8 lock : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 lock : 1;
+ __u8 reserved2 : 1;
+ __u8 prvnt_jmp : 1;
+ __u8 eject : 1;
+ __u8 load : 1;
+ __u8 mechanism : 3;
+#endif
+
+ __u8 reserved3[3];
+} __packed;
+
+/**
+ * @brief Random Readable Feature (0010h)
+ *
+ * This Feature identifies a Drive that is able to read data from logical
+ * blocks referenced by Logical Block Addresses, but not requiring that
+ * either the addresses or the read sequences occur in any particular order.
+ */
+struct cdf_random_readable {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+ /* The Additional Length field shall be set to 8. */
+ __u8 length;
+ /**
+ * The Logical Block Size shall be set to the number of bytes per
+ * logical block.
+ */
+ __be32 block_size;
+ /**
+ * The Blocking field shall indicate the number of logical blocks per
+ * device readable unit.
+ * If there is more than one Blocking on the medium possible,
+ * the Blocking field shall be set to zero.
+ */
+ __be16 blocking;
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved2 : 7;
+ /**
+ * The PP (Page Present) bit, when set to zero, shall indicate that
+ * the Read/Write Error Recovery mode page may not be present.
+ * When set to one, shall indicate that the Read/Write Error Recovery
+ * mode page is present.
+ */
+ __u8 pp : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 pp : 1;
+ __u8 reserved2 : 7;
+#endif
+
+ __u8 reserved3;
+} __packed;
+
+/*
+ * Multi-read Feature (001Dh)
+ * The Drive shall conform to the OSTA Multi-Read
+ * specification 1.00, with the exception of CD Play
+ * capability (the CD Audio Feature is not required).
+ */
+struct cdf_multi_read {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+
+ __u8 length;
+} __packed;
+
+/*
+ * CD Read Feature (001Eh)
+ * This Feature identifies a Drive that is able to read
+ * CD specific information from the media and is able
+ * to read user data from all types of CD sectors.
+ */
+struct cdf_cd_read {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+
+ __u8 length;
+#if defined(__BIG_ENDIAN_BITFIELD)
+
+ /*
+ * If DAP is set to one, the READ CD and READ CD MSF
+ * commands support the DAP bit in bit 1, byte 1
+ * of the CDB.
+ */
+ __u8 dap : 1;
+ __u8 reserved2 : 5;
+
+ /*
+ * The C2 Flags, when set to one, indicates the Drive
+ * supports the C2 Error Pointers.
+ * When set to zero the Drive does not support
+ * C2 Error Pointers.
+ */
+ __u8 c2flags : 1;
+ /*
+ * The CD-Text bit, when set to one, indicates the Drive
+ * supports Format Code 5h of the READ TOC/PMA/ATIP
+ * command.
+ * When set to zero, CD-Text is not supported.
+ */
+ __u8 cdtext : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 cdtext : 1;
+ __u8 c2flags : 1;
+ __u8 reserved2 : 5;
+ __u8 dap : 1;
+#endif
+
+ __u8 reserved3[3];
+} __packed;
+
+/*
+ * DVD Read Feature (001Fh)
+ * This Feature identifies a Drive that is able to read DVD
+ * specific information from the media.
+ */
+struct cdf_dvd_read {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+
+ __u8 length;
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved2 : 7;
+ /*
+ * If MULTI110 is set to one, the Drive shall
+ * be compliant with the DVD Multi Drive Read-only
+ * specifications as defined in [DVD-Ref8].
+ */
+ __u8 multi110 : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 multi110 : 1;
+ __u8 reserved2 : 7;
+#endif
+ __u8 reserved3;
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved4 : 6;
+ /*
+ * If the DVD-RW Dual Layer (Dual-RW) bit is set to one,
+ * the Drive is able to read DVD-RW DL media that has the
+ * Complete state.
+ * If the Dual-RW bit is set to zero, the Drive is unable
+ * to read the DVD-RW DL media.
+ */
+ __u8 dualrw : 1;
+ /*
+ * If the DVD-R Dual Layer (Dual-R) bit is set to one,
+ * the Drive shall support reading all recording modes
+ * (i.e., Sequential recording and Layer Jump recording modes)
+ * of DVD-R DL discs.
+ * The Drive shall support Remapping on DVD-R DL discs.
+ */
+ __u8 dualr : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 dualr : 1;
+ __u8 dualrw : 1;
+ __u8 reserved4 : 6;
+#endif
+
+ __u8 reserved5;
+} __packed;
+
+/**
+ * @brief DVD+R Feature (002Bh)
+ * The presence of the DVD+R Feature indicates that the Drive is
+ * capable of reading a recorded DVD+R disc that is written according
+ * to [DVD+Ref1].
+ * Specifically, this includes the capability of reading DCBs.
+ */
+struct cdf_dvd_plus_r {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+
+ __u8 length;
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved2 : 7;
+ /**
+ * If the Write bit is set to one, then the Drive is also capable
+ * of writing DVD+R discs according to [DVD+Ref1].
+ */
+ __u8 write : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 write : 1;
+ __u8 reserved2 : 7;
+#endif
+
+ __u8 reserved3[3];
+} __packed;
+
+/**
+ * @brief CD Track at Once Feature (002Dh)
+ * This Feature identifies a Drive that is able to write data to
+ * a CD track.
+ */
+struct cdf_cd_track_at_once {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+
+ __u8 length;
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved2 : 1;
+ /**
+ * The BUF bit, if set to 1, shall indicate that the Drive
+ * is capable of zero loss linking.
+ */
+ __u8 buf : 1;
+ __u8 reserved1 : 1;
+ /**
+ * The R-W Raw bit, if set to 1, shall indicate that the Drive
+ * supports writing R-W Sub code in the Raw mode.
+ * The R-W Sub-code bit shall be set if this bit is set.
+ */
+ __u8 rw_raw : 1;
+ /**
+ * The R-W Pack bit, if set to 1, shall indicate that the Drive
+ * supports writing R-W Sub code in the Packed mode.
+ * The R-W Sub-code bit shall be set if this bit is set.
+ */
+ __u8 rw_pack : 1;
+ /**
+ * The Test Write bit indicates that the Drive is able to
+ * perform test writes.
+ */
+ __u8 test_write : 1;
+ /**
+ * The CD-RW bit indicates support for overwriting a Track at
+ * Once track with another.
+ */
+ __u8 cd_rw : 1;
+ /**
+ * The R-W Sub-code bit indicates that the Drive is able to
+ * record the R-W Sub-channels with user supplied data.
+ */
+ __u8 rw_subcode : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 rw_subcode : 1;
+ __u8 cd_rw : 1;
+ __u8 test_write : 1;
+ __u8 rw_pack : 1;
+ __u8 rw_raw : 1;
+ __u8 reserved3 : 1;
+ __u8 buf : 1;
+ __u8 reserved2 : 1;
+#endif
+
+ __u8 reserved4;
+ /**
+ * The data type references to the
+ * "Incremental Streaming Writable Feature"
+ */
+ __be16 data_type_supported;
+} __packed;
+
+/**
+ * @brief BD Read Feature (0040h)
+ * This Feature identifies a Drive that is able to read control
+ * structures and user data from the BD disc.
+ */
+struct cdf_bd_read {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+
+ __u8 length;
+
+ __u8 reserved2[4];
+ /**
+ * If the Version K bit (K = 0...15) of the Class M (M = 0...3)
+ * bit map is set to zero, the Drive claims no read capabilities
+ * for BD-R(E)(ROM) discs of Class M and Version K.
+ * If the Version K bit of Class M is set to one, the Drive is
+ * able to read BD-RE discs of class M and Version K.
+ *
+ */
+
+ /* Class M (M = 0..3) BD-RE Read Support */
+ __be16 class0_bdre_read_support;
+ __be16 class1_bdre_read_support;
+ __be16 class2_bdre_read_support;
+ __be16 class3_bdre_read_support;
+ /* Class M (M = 0..3) BD-R Read Support */
+ __be16 class0_bdr_read_support;
+ __be16 class1_bdr_read_support;
+ __be16 class2_bdr_read_support;
+ __be16 class3_bdr_read_support;
+ /* Class M (M = 0..3) BD-ROM Read Support */
+ __be16 class0_bdrom_read_support;
+ __be16 class1_bdrom_read_support;
+ __be16 class2_bdrom_read_support;
+ __be16 class3_bdrom_read_support;
+} __packed;
+
+/**
+ * @brief Power Management Feature (0100h)
+ * This Feature identifies a Drive that is able to perform Host and
+ * Drive directed power management.
+ */
+struct cdf_power_mgmt {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+
+ __u8 length;
+} __packed;
+
+/**
+ * @brief Real Time Streaming Feature (0107h)
+ * This Feature identifies a Drive that is able to perform reading
+ * and writing within Host specified (and Drive verified) performance
+ * ranges. This Feature also indicates whether the Drive supports the
+ * Stream playback operation.
+ */
+struct cdf_rt_streaming {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+
+ __u8 length;
+
+#if defined(__BIG_ENDIAN_BITFIELD)
+ __u8 reserved2 : 3;
+ /**
+ * The Read Buffer Capacity Block (RBCB) bit indicates that the
+ * Drive supports the READ_BUFFER_CAPACITY command and its Block
+ * bit.
+ */
+ __u8 rbcb : 1;
+ /**
+ * The Set CD Speed (SCS) bit of one indicates that the Drive
+ * supports the SET_CD_SPEED command. Otherwise, the Drive does not
+ * support the SET_CD_SPEED command.
+ */
+ __u8 scs : 1;
+ /**
+ * The mode page 2A (MP2A) bit of one indicates that the MM
+ * Capabilities & Mechanical Status mode page (2Ah) with the Drive
+ * Write Speed Performance Descriptor Blocks is supported.
+ * Otherwise, the MM Capabilities & Mechanical Status mode
+ * page (2Ah), with the Drive Write Speed Performance Descriptor
+ * Blocks are not supported by the Drive.
+ */
+ __u8 mp2a : 1;
+ /**
+ * A Write Speed Performance Descriptor (WSPD) bit of one indicates
+ * that the Drive supports the Write Speed (Type field = 03h) data
+ * of GET PERFORMANCE command and the WRC field of SET STREAMING
+ * command. This bit shall be set to one, if Drive supports writing
+ * speed selection.
+ */
+ __u8 wspd : 1;
+ /**
+ * A Stream Writing (SW) bit of one indicates that the Drive
+ * supports the Stream recording operation. A SW bit of zero
+ * indicates that the Drive may not support the Stream recording
+ * operation.
+ */
+ __u8 sw : 1;
+#elif defined(__LITTLE_ENDIAN_BITFIELD)
+ __u8 sw : 1;
+ __u8 wspd : 1;
+ __u8 mp2a : 1;
+ __u8 scs : 1;
+ __u8 rbcb : 1;
+ __u8 reserved2 : 3;
+#endif
+
+ __u8 reserved3[3];
+} __packed;
+
+/**
+ * @brief Disc Control Blocks (DCBs) Feature (010Ah)
+ *
+ * This Feature identifies a Drive that is able to read and/or write
+ * DCBs from or to the media.
+ */
+struct cdf_dcbs {
+ __be16 code;
+
+ struct cdb_ft_vpc_byte vpc;
+
+ /**
+ * The Additional Length field shall be set to N * 4, where n is
+ * the number of Supported DCB entries. The Supported DCB entry
+ * n fields shall each contain the Content Descriptor of a
+ * supported DCB.
+ * Entries shall be sorted in ascending order.
+ */
+ __u8 length;
+
+ /**
+ * Non supported read and/or write the DCBs blocks.
+ */
+ __be32 supported_dcb_entry[0];
+};
+
+/*
+ * feature codes list
+ */
+
+/* A list of all Profiles supported by the Drive*/
+#define CDF_PROFILE_LIST_CODE 0x0000
+/* Mandatory behavior for all devices */
+#define CDF_CORE 0x0001
+
+#define CDF_MORPHING_CODE 0x0002
+/* The medium may be removed from the device */
+#define CDF_REMOVEBLE_MEDIA 0x0003
+#define CDF_RANDOM_READ 0x0010
+/* The Drive is able to read all CD media types; based on OSTA MultiRead */
+#define CDF_MULTI_READ 0x001D
+/* The ability to read CD specific structures */
+#define CDF_CD_READ 0x001E
+/* The ability to read DVD specific structures*/
+#define CDF_DVD_READ 0x001F
+/* Write support for randomly addressed writes */
+#define CDF_RWRT 0x0020
+/* Write support for sequential recording */
+#define CDF_INC_STREAM_WR 0x0021
+/* Hardware Defect Management */
+#define CDF_HWDM 0x0024
+/* The ability to recognize and read and optionally write MRW formatted media */
+#define CDF_MRW 0x0028
+/* The ability to read DVD+R recorded media formats */
+#define CDF_DVD_R 0x002B
+/* Ability to write CD with Track at Once recording */
+#define CDF_CD_TRACK_ONCE 0x002D
+/* The ability to read control structures and user data from a BD disc */
+#define CDF_BD_READ 0x0040
+/* The ability to write control structures and user data to certain BD discs */
+#define CDF_BD_WRITE 0x0041
+/* Host and device directed power management */
+#define CDF_POWER_MGMT 0x0100
+/* Ability to perform DVD CSS/CPPM authentication and RPC */
+#define CDF_DVD_CSS 0x0106
+/* Ability to read and write using Host requested performance parameters */
+#define CDF_REAL_TIME_STREAM 0x0107
+/* The ability to read and/or write DCBs*/
+#define CDF_DCBS 0x010A
+
/**
* The READ TOC/PMA/ATIP format field values
*/
--
2.32.0


2021-06-27 00:46:36

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 5/6] FMS: Add the SCSI Get Configuration command.

Hi Igor,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on mkp-scsi/for-next]
[also build test WARNING on scsi/for-next linus/master balbi-usb/testing/next v5.13-rc7 next-20210625]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Igor-Kononenko/usb-gadget-mass-storage-Improve-the-signature-of-SCSI-handler-function/20210627-061851
base: https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next
config: powerpc-randconfig-r035-20210627 (attached as .config)
compiler: powerpc64-linux-gcc (GCC) 9.3.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# https://github.com/0day-ci/linux/commit/db2ec6f1e52293817f380a4875e01c36a4195c19
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Igor-Kononenko/usb-gadget-mass-storage-Improve-the-signature-of-SCSI-handler-function/20210627-061851
git checkout db2ec6f1e52293817f380a4875e01c36a4195c19
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross ARCH=powerpc

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>

All warnings (new ones prefixed by >>):

In file included from include/linux/printk.h:7,
from include/linux/kernel.h:17,
from include/asm-generic/bug.h:20,
from arch/powerpc/include/asm/bug.h:109,
from include/linux/bug.h:5,
from arch/powerpc/include/asm/mmu.h:147,
from arch/powerpc/include/asm/paca.h:18,
from arch/powerpc/include/asm/current.h:13,
from include/linux/sched.h:12,
from include/linux/blkdev.h:5,
from drivers/usb/gadget/function/f_mass_storage.c:201:
drivers/usb/gadget/function/f_mass_storage.c: In function 'cdr_guess_medium_type':
>> include/linux/kern_levels.h:5:18: warning: format '%u' expects argument of type 'unsigned int', but argument 4 has type 'size_t' {aka 'long unsigned int'} [-Wformat=]
5 | #define KERN_SOH "\001" /* ASCII Start Of Header */
| ^~~~~~
include/linux/kern_levels.h:15:20: note: in expansion of macro 'KERN_SOH'
15 | #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
| ^~~~~~~~
include/linux/printk.h:427:9: note: in expansion of macro 'KERN_DEBUG'
427 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~~~~~
drivers/usb/gadget/function/storage_common.h:24:4: note: in expansion of macro 'pr_debug'
24 | func("%s/%s: " fmt, *(lun)->name_pfx, \
| ^~~~
drivers/usb/gadget/function/storage_common.h:30:34: note: in expansion of macro '_LMSG'
30 | #define LDBG(lun, fmt, args...) _LMSG(pr_debug, lun, fmt, ## args)
| ^~~~~
drivers/usb/gadget/function/f_mass_storage.c:1964:2: note: in expansion of macro 'LDBG'
1964 | LDBG(curlun,
| ^~~~
drivers/usb/gadget/function/f_mass_storage.c:1965:27: note: format string is defined here
1965 | "Disc layout size (%u) exceeds all known media types, assuming BD - ROM !\n",
| ~^
| |
| unsigned int
| %lu
In file included from include/linux/printk.h:7,
from include/linux/kernel.h:17,
from include/asm-generic/bug.h:20,
from arch/powerpc/include/asm/bug.h:109,
from include/linux/bug.h:5,
from arch/powerpc/include/asm/mmu.h:147,
from arch/powerpc/include/asm/paca.h:18,
from arch/powerpc/include/asm/current.h:13,
from include/linux/sched.h:12,
from include/linux/blkdev.h:5,
from drivers/usb/gadget/function/f_mass_storage.c:201:
include/linux/kern_levels.h:5:18: warning: format '%u' expects argument of type 'unsigned int', but argument 3 has type 'size_t' {aka 'long unsigned int'} [-Wformat=]
5 | #define KERN_SOH "\001" /* ASCII Start Of Header */
| ^~~~~~
include/linux/kern_levels.h:15:20: note: in expansion of macro 'KERN_SOH'
15 | #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
| ^~~~~~~~
include/linux/printk.h:427:9: note: in expansion of macro 'KERN_DEBUG'
427 | printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~~~~~
drivers/usb/gadget/function/storage_common.h:27:4: note: in expansion of macro 'pr_debug'
27 | func("%s: " fmt, (lun)->name, ## args); \
| ^~~~
drivers/usb/gadget/function/storage_common.h:30:34: note: in expansion of macro '_LMSG'
30 | #define LDBG(lun, fmt, args...) _LMSG(pr_debug, lun, fmt, ## args)
| ^~~~~
drivers/usb/gadget/function/f_mass_storage.c:1964:2: note: in expansion of macro 'LDBG'
1964 | LDBG(curlun,
| ^~~~
drivers/usb/gadget/function/f_mass_storage.c:1965:27: note: format string is defined here
1965 | "Disc layout size (%u) exceeds all known media types, assuming BD - ROM !\n",
| ~^
| |
| unsigned int
| %lu
drivers/usb/gadget/function/f_mass_storage.c: At top level:
drivers/usb/gadget/function/f_mass_storage.c:311:23: warning: initialized field overwritten [-Woverride-init]
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2231:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2231 | { CDB_REG_CHECKER_BLK(READ_6, 6, CDB_SIZE_FIELD_4, DATA_DIR_TO_HOST,
| ^~~~~~~~~~~~~~~~~~~
drivers/usb/gadget/function/f_mass_storage.c:311:23: note: (near initialization for 'cdb_checker_table[6].do_check_command')
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2231:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2231 | { CDB_REG_CHECKER_BLK(READ_6, 6, CDB_SIZE_FIELD_4, DATA_DIR_TO_HOST,
| ^~~~~~~~~~~~~~~~~~~
drivers/usb/gadget/function/f_mass_storage.c:311:23: warning: initialized field overwritten [-Woverride-init]
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2233:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2233 | { CDB_REG_CHECKER_BLK(READ_10, 10, CDB_SIZE_FIELD_7, DATA_DIR_TO_HOST,
| ^~~~~~~~~~~~~~~~~~~
drivers/usb/gadget/function/f_mass_storage.c:311:23: note: (near initialization for 'cdb_checker_table[7].do_check_command')
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2233:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2233 | { CDB_REG_CHECKER_BLK(READ_10, 10, CDB_SIZE_FIELD_7, DATA_DIR_TO_HOST,
| ^~~~~~~~~~~~~~~~~~~
drivers/usb/gadget/function/f_mass_storage.c:311:23: warning: initialized field overwritten [-Woverride-init]
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2235:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2235 | { CDB_REG_CHECKER_BLK(READ_12, 12, CDB_SIZE_FIELD_6, DATA_DIR_TO_HOST,
| ^~~~~~~~~~~~~~~~~~~
drivers/usb/gadget/function/f_mass_storage.c:311:23: note: (near initialization for 'cdb_checker_table[8].do_check_command')
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2235:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2235 | { CDB_REG_CHECKER_BLK(READ_12, 12, CDB_SIZE_FIELD_6, DATA_DIR_TO_HOST,
| ^~~~~~~~~~~~~~~~~~~
drivers/usb/gadget/function/f_mass_storage.c:311:23: warning: initialized field overwritten [-Woverride-init]
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2259:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2259 | { CDB_REG_CHECKER_BLK(VERIFY, 10, CDB_NO_SIZE_FIELD, DATA_DIR_NONE,
--
drivers/usb/gadget/function/f_mass_storage.c: In function 'invalidate_sub':
drivers/usb/gadget/function/f_mass_storage.c:1166:16: warning: variable 'rc' set but not used [-Wunused-but-set-variable]
1166 | unsigned long rc;
| ^~
In file included from include/linux/kernel.h:17,
from include/asm-generic/bug.h:20,
from arch/powerpc/include/asm/bug.h:109,
from include/linux/bug.h:5,
from arch/powerpc/include/asm/mmu.h:147,
from arch/powerpc/include/asm/paca.h:18,
from arch/powerpc/include/asm/current.h:13,
from include/linux/sched.h:12,
from include/linux/blkdev.h:5,
from drivers/usb/gadget/function/f_mass_storage.c:201:
drivers/usb/gadget/function/f_mass_storage.c: In function 'cdr_guess_medium_type':
>> include/linux/kern_levels.h:5:18: warning: format '%u' expects argument of type 'unsigned int', but argument 4 has type 'size_t' {aka 'long unsigned int'} [-Wformat=]
5 | #define KERN_SOH "\001" /* ASCII Start Of Header */
| ^~~~~~
include/linux/printk.h:140:10: note: in definition of macro 'no_printk'
140 | printk(fmt, ##__VA_ARGS__); \
| ^~~
include/linux/kern_levels.h:15:20: note: in expansion of macro 'KERN_SOH'
15 | #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
| ^~~~~~~~
include/linux/printk.h:430:12: note: in expansion of macro 'KERN_DEBUG'
430 | no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~~~~~
drivers/usb/gadget/function/storage_common.h:24:4: note: in expansion of macro 'pr_debug'
24 | func("%s/%s: " fmt, *(lun)->name_pfx, \
| ^~~~
drivers/usb/gadget/function/storage_common.h:30:34: note: in expansion of macro '_LMSG'
30 | #define LDBG(lun, fmt, args...) _LMSG(pr_debug, lun, fmt, ## args)
| ^~~~~
drivers/usb/gadget/function/f_mass_storage.c:1964:2: note: in expansion of macro 'LDBG'
1964 | LDBG(curlun,
| ^~~~
drivers/usb/gadget/function/f_mass_storage.c:1965:27: note: format string is defined here
1965 | "Disc layout size (%u) exceeds all known media types, assuming BD - ROM !\n",
| ~^
| |
| unsigned int
| %lu
In file included from include/linux/kernel.h:17,
from include/asm-generic/bug.h:20,
from arch/powerpc/include/asm/bug.h:109,
from include/linux/bug.h:5,
from arch/powerpc/include/asm/mmu.h:147,
from arch/powerpc/include/asm/paca.h:18,
from arch/powerpc/include/asm/current.h:13,
from include/linux/sched.h:12,
from include/linux/blkdev.h:5,
from drivers/usb/gadget/function/f_mass_storage.c:201:
include/linux/kern_levels.h:5:18: warning: format '%u' expects argument of type 'unsigned int', but argument 3 has type 'size_t' {aka 'long unsigned int'} [-Wformat=]
5 | #define KERN_SOH "\001" /* ASCII Start Of Header */
| ^~~~~~
include/linux/printk.h:140:10: note: in definition of macro 'no_printk'
140 | printk(fmt, ##__VA_ARGS__); \
| ^~~
include/linux/kern_levels.h:15:20: note: in expansion of macro 'KERN_SOH'
15 | #define KERN_DEBUG KERN_SOH "7" /* debug-level messages */
| ^~~~~~~~
include/linux/printk.h:430:12: note: in expansion of macro 'KERN_DEBUG'
430 | no_printk(KERN_DEBUG pr_fmt(fmt), ##__VA_ARGS__)
| ^~~~~~~~~~
drivers/usb/gadget/function/storage_common.h:27:4: note: in expansion of macro 'pr_debug'
27 | func("%s: " fmt, (lun)->name, ## args); \
| ^~~~
drivers/usb/gadget/function/storage_common.h:30:34: note: in expansion of macro '_LMSG'
30 | #define LDBG(lun, fmt, args...) _LMSG(pr_debug, lun, fmt, ## args)
| ^~~~~
drivers/usb/gadget/function/f_mass_storage.c:1964:2: note: in expansion of macro 'LDBG'
1964 | LDBG(curlun,
| ^~~~
drivers/usb/gadget/function/f_mass_storage.c:1965:27: note: format string is defined here
1965 | "Disc layout size (%u) exceeds all known media types, assuming BD - ROM !\n",
| ~^
| |
| unsigned int
| %lu
drivers/usb/gadget/function/f_mass_storage.c: At top level:
drivers/usb/gadget/function/f_mass_storage.c:311:23: warning: initialized field overwritten [-Woverride-init]
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2231:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2231 | { CDB_REG_CHECKER_BLK(READ_6, 6, CDB_SIZE_FIELD_4, DATA_DIR_TO_HOST,
| ^~~~~~~~~~~~~~~~~~~
drivers/usb/gadget/function/f_mass_storage.c:311:23: note: (near initialization for 'cdb_checker_table[6].do_check_command')
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2231:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2231 | { CDB_REG_CHECKER_BLK(READ_6, 6, CDB_SIZE_FIELD_4, DATA_DIR_TO_HOST,
| ^~~~~~~~~~~~~~~~~~~
drivers/usb/gadget/function/f_mass_storage.c:311:23: warning: initialized field overwritten [-Woverride-init]
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2233:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2233 | { CDB_REG_CHECKER_BLK(READ_10, 10, CDB_SIZE_FIELD_7, DATA_DIR_TO_HOST,
| ^~~~~~~~~~~~~~~~~~~
drivers/usb/gadget/function/f_mass_storage.c:311:23: note: (near initialization for 'cdb_checker_table[7].do_check_command')
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2233:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2233 | { CDB_REG_CHECKER_BLK(READ_10, 10, CDB_SIZE_FIELD_7, DATA_DIR_TO_HOST,
| ^~~~~~~~~~~~~~~~~~~
drivers/usb/gadget/function/f_mass_storage.c:311:23: warning: initialized field overwritten [-Woverride-init]
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2235:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2235 | { CDB_REG_CHECKER_BLK(READ_12, 12, CDB_SIZE_FIELD_6, DATA_DIR_TO_HOST,
| ^~~~~~~~~~~~~~~~~~~
drivers/usb/gadget/function/f_mass_storage.c:311:23: note: (near initialization for 'cdb_checker_table[8].do_check_command')
311 | .do_check_command = &check_command_size_in_blocks
| ^
drivers/usb/gadget/function/f_mass_storage.c:2235:4: note: in expansion of macro 'CDB_REG_CHECKER_BLK'
2235 | { CDB_REG_CHECKER_BLK(READ_12, 12, CDB_SIZE_FIELD_6, DATA_DIR_TO_HOST,
| ^~~~~~~~~~~~~~~~~~~


vim +5 include/linux/kern_levels.h

314ba3520e513a Joe Perches 2012-07-30 4
04d2c8c83d0e3a Joe Perches 2012-07-30 @5 #define KERN_SOH "\001" /* ASCII Start Of Header */
04d2c8c83d0e3a Joe Perches 2012-07-30 6 #define KERN_SOH_ASCII '\001'
04d2c8c83d0e3a Joe Perches 2012-07-30 7

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (16.79 kB)
.config.gz (43.90 kB)
Download all attachments

2021-06-27 04:53:07

by kernel test robot

[permalink] [raw]
Subject: Re: [PATCH 5/6] FMS: Add the SCSI Get Configuration command.

Hi Igor,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on mkp-scsi/for-next]
[also build test WARNING on scsi/for-next linus/master balbi-usb/testing/next v5.13-rc7 next-20210625]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Igor-Kononenko/usb-gadget-mass-storage-Improve-the-signature-of-SCSI-handler-function/20210627-061851
base: https://git.kernel.org/pub/scm/linux/kernel/git/mkp/scsi.git for-next
config: i386-randconfig-s002-20210627 (attached as .config)
compiler: gcc-9 (Debian 9.3.0-22) 9.3.0
reproduce:
# apt-get install sparse
# sparse version: v0.6.3-341-g8af24329-dirty
# https://github.com/0day-ci/linux/commit/db2ec6f1e52293817f380a4875e01c36a4195c19
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Igor-Kononenko/usb-gadget-mass-storage-Improve-the-signature-of-SCSI-handler-function/20210627-061851
git checkout db2ec6f1e52293817f380a4875e01c36a4195c19
# save the attached .config to linux build tree
make W=1 C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=i386 SHELL=/bin/bash drivers/usb/gadget/function/

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <[email protected]>


sparse warnings: (new ones prefixed by >>)
>> drivers/usb/gadget/function/f_mass_storage.c:1988:57: sparse: sparse: restricted __be16 degrades to integer
>> drivers/usb/gadget/function/f_mass_storage.c:2060:30: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned int [usertype] data_len @@ got restricted __be32 [usertype] @@
drivers/usb/gadget/function/f_mass_storage.c:2060:30: sparse: expected unsigned int [usertype] data_len
drivers/usb/gadget/function/f_mass_storage.c:2060:30: sparse: got restricted __be32 [usertype]
>> drivers/usb/gadget/function/f_mass_storage.c:2062:17: sparse: sparse: cast from restricted __be16
>> drivers/usb/gadget/function/f_mass_storage.c:2061:34: sparse: sparse: incorrect type in assignment (different base types) @@ expected unsigned short [usertype] curr_profile @@ got restricted __be16 [usertype] @@
drivers/usb/gadget/function/f_mass_storage.c:2061:34: sparse: expected unsigned short [usertype] curr_profile
drivers/usb/gadget/function/f_mass_storage.c:2061:34: sparse: got restricted __be16 [usertype]
drivers/usb/gadget/function/f_mass_storage.c:2231:11: sparse: sparse: Initializer entry defined twice
drivers/usb/gadget/function/f_mass_storage.c:2231:11: sparse: also defined here
drivers/usb/gadget/function/f_mass_storage.c:2233:11: sparse: sparse: Initializer entry defined twice
drivers/usb/gadget/function/f_mass_storage.c:2233:11: sparse: also defined here
drivers/usb/gadget/function/f_mass_storage.c:2235:11: sparse: sparse: Initializer entry defined twice
drivers/usb/gadget/function/f_mass_storage.c:2235:11: sparse: also defined here
drivers/usb/gadget/function/f_mass_storage.c:2259:11: sparse: sparse: Initializer entry defined twice
drivers/usb/gadget/function/f_mass_storage.c:2259:11: sparse: also defined here
drivers/usb/gadget/function/f_mass_storage.c:2261:11: sparse: sparse: Initializer entry defined twice
drivers/usb/gadget/function/f_mass_storage.c:2261:11: sparse: also defined here
drivers/usb/gadget/function/f_mass_storage.c:2263:11: sparse: sparse: Initializer entry defined twice
drivers/usb/gadget/function/f_mass_storage.c:2263:11: sparse: also defined here
drivers/usb/gadget/function/f_mass_storage.c:2265:11: sparse: sparse: Initializer entry defined twice
drivers/usb/gadget/function/f_mass_storage.c:2265:11: sparse: also defined here
drivers/usb/gadget/function/f_mass_storage.c: note: in included file (through include/linux/rcuwait.h, include/linux/percpu-rwsem.h, include/linux/fs.h, ...):
include/linux/sched/signal.h:285:28: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@
include/linux/sched/signal.h:285:28: sparse: expected struct spinlock [usertype] *lock
include/linux/sched/signal.h:285:28: sparse: got struct spinlock [noderef] __rcu *
include/linux/sched/signal.h:287:30: sparse: sparse: incorrect type in argument 1 (different address spaces) @@ expected struct spinlock [usertype] *lock @@ got struct spinlock [noderef] __rcu * @@
include/linux/sched/signal.h:287:30: sparse: expected struct spinlock [usertype] *lock
include/linux/sched/signal.h:287:30: sparse: got struct spinlock [noderef] __rcu *

vim +1988 drivers/usb/gadget/function/f_mass_storage.c

1969
1970 /* Adjust current profile which depended on an inserted medium */
1971 static inline void cdf_populate_profile_list(struct fsg_common *common,
1972 struct cdr_features **feature)
1973 {
1974 __be16 current_media_type = cdr_guess_medium_type(common);
1975 struct mmc_profile *profiles =
1976 (*feature)->feature.profile_list.profiles;
1977 int i;
1978
1979 /* copy profile list to the response buffer */
1980 memcpy(profiles, cdf_supported_profiles,
1981 sizeof(cdf_supported_profiles));
1982 for (i = 0; i < CDF_PROFILES_COUNT; ++i) {
1983 /*
1984 * Reset the current profile bit,
1985 * because it might be set from the previous one
1986 */
1987 profiles[i].current_p = 0;
> 1988 if (be16_to_cpu(profiles[i].profile) == current_media_type) {
1989 DBG(common, "Fill current profile: curr=(%04Xh)\n",
1990 be16_to_cpu(profiles[i].profile));
1991 profiles[i].current_p = 1;
1992 }
1993 }
1994 }
1995
1996 static int do_get_configuration(struct fsg_common *common,
1997 struct fsg_buffhd *bh)
1998 {
1999 struct fsg_lun *curlun = common->curlun;
2000 int i;
2001 struct cdb_get_configuration *cdb =
2002 (struct cdb_get_configuration *)common->cmnd;
2003 size_t buffer_size = sizeof(struct feature_header);
2004 size_t generic_desc_size = sizeof(struct cdb_ft_generic);
2005 struct feature_header *ret_header = (struct feature_header *)bh->buf;
2006 u8 *ret_data = ((u8 *)ret_header) + buffer_size;
2007
2008 LDBG(curlun, "Requesting features from 0x%04X, with RT flag 0x%02X\n",
2009 be16_to_cpu(cdb->sfn), cdb->rt);
2010
2011 if (!common->curlun || !common->curlun->cdrom)
2012 return -EINVAL;
2013
2014 /* Go over *all* features, and copy them according to RT value */
2015 for (i = 0; i < ARRAY_SIZE(features_table); ++i) {
2016 struct cdb_ft_generic *generic =
2017 (struct cdb_ft_generic *)&features_table[i];
2018 struct cdr_features *feature = &features_table[i];
2019
2020 if (feature->populate != NULL)
2021 feature->populate(common, &feature);
2022
2023 // a) RT is 0x00 and feature's code >= SFN
2024 // b) RT is 0x01, feature's code >= SFN and feature has 'current' bit set
2025 // c) RT is 0x02 and feature's code == SFN
2026
2027 if (be16_to_cpu(generic->code) >= be16_to_cpu(cdb->sfn)) {
2028 if ((cdb->rt == CDR_CFG_RT_FULL) ||
2029 (cdb->rt == CDR_CFG_RT_CURRENT &&
2030 generic->vpc.cur) ||
2031 (cdb->rt == CDR_CFG_RT_SPECIFIED_SFN &&
2032 be16_to_cpu(generic->code) ==
2033 be16_to_cpu(cdb->sfn))) {
2034 LDBG(curlun, "Copying feature 0x%04X\n",
2035 be16_to_cpu(generic->code));
2036
2037 memset(ret_data, 0,
2038 (generic->length + generic_desc_size));
2039 /* Copy feature */
2040 memcpy(ret_data, feature,
2041 (generic->length + generic_desc_size));
2042 buffer_size +=
2043 (generic->length + generic_desc_size);
2044 ret_data +=
2045 (generic->length + generic_desc_size);
2046
2047 /* Break the loop if RT is CDR_CFG_RT_SPECIFIED_SFN */
2048 if (cdb->rt == CDR_CFG_RT_SPECIFIED_SFN) {
2049 LDBG(curlun,
2050 "Got the feature we wanted (0x%04X), breaking the loop\n",
2051 be16_to_cpu(cdb->sfn));
2052 break;
2053 }
2054 }
2055 }
2056 }
2057
2058 memset(ret_header, 0, sizeof(struct feature_header));
2059 /* Header */
> 2060 ret_header->data_len = cpu_to_be32(buffer_size - generic_desc_size);
> 2061 ret_header->curr_profile =
> 2062 cpu_to_be16(cdr_guess_medium_type(common));
2063
2064 dump_msg(common, "feature header", (u8 *)ret_header,
2065 sizeof(struct feature_header));
2066
2067 dump_msg(common, "features table", (u8 *)bh->buf, buffer_size);
2068
2069 common->data_size_to_handle = buffer_size;
2070 return 0;
2071 }
2072

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (9.08 kB)
.config.gz (46.02 kB)
Download all attachments

2021-06-28 09:58:27

by Christoph Hellwig

[permalink] [raw]
Subject: Re: [PATCH 5/6] FMS: Add the SCSI Get Configuration command.

What is FMS? And why do only patches 5 and 6 show up on the list?
And why does this mix changes to the SCSI layer, libata, usb-gadget and
the CDROM UAPI in a single patch?