Loading drivers/scsi/ufs/ufs.h +1 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ #define GENERAL_UPIU_REQUEST_SIZE 32 #define QUERY_DESC_MAX_SIZE 255 #define QUERY_DESC_MIN_SIZE 2 #define QUERY_DESC_HDR_SIZE 2 #define QUERY_OSF_SIZE (GENERAL_UPIU_REQUEST_SIZE - \ (sizeof(struct utp_upiu_header))) Loading drivers/scsi/ufs/ufshcd.c +89 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include <linux/async.h> #include <scsi/ufs/ioctl.h> #include <linux/devfreq.h> #include <linux/nls.h> #include "ufshcd.h" #include "unipro.h" Loading Loading @@ -270,6 +271,16 @@ static inline void ufshcd_disable_irq(struct ufs_hba *hba) } } /* replace non-printable or non-ASCII characters with spaces */ static inline void ufshcd_remove_non_printable(char *val) { if (!val) return; if (*val < 0x20 || *val > 0x7e) *val = ' '; } static void ufshcd_print_host_regs(struct ufs_hba *hba) { /* Loading Loading @@ -2123,6 +2134,84 @@ int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32 size) return err; } /** * ufshcd_read_string_desc - read string descriptor * @hba: pointer to adapter instance * @desc_index: descriptor index * @buf: pointer to buffer where descriptor would be read * @size: size of buf * @ascii: if true convert from unicode to ascii characters * * Return 0 in case of success, non-zero otherwise */ int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, u8 *buf, u32 size, bool ascii) { int err = 0; int retries; for (retries = 0; retries < QUERY_REQ_RETRIES; retries++) { err = ufshcd_read_desc(hba, QUERY_DESC_IDN_STRING, desc_index, buf, size); if (!err) break; dev_dbg(hba->dev, "%s: error %d retrying %d\n", __func__, err, retries); } if (err) { dev_err(hba->dev, "%s: reading String Desc failed after %d retries. err = %d\n", __func__, QUERY_REQ_RETRIES, err); goto out; } if (ascii) { int desc_len; int ascii_len; int i; char *buff_ascii; desc_len = buf[0]; /* remove header and divide by 2 to move from UTF16 to UTF8 */ ascii_len = (desc_len - QUERY_DESC_HDR_SIZE) / 2 + 1; if (size < ascii_len + QUERY_DESC_HDR_SIZE) { dev_err(hba->dev, "%s: buffer allocated size is too small\n", __func__); err = -ENOMEM; goto out; } buff_ascii = kmalloc(ascii_len, GFP_KERNEL); if (!buff_ascii) { dev_err(hba->dev, "%s: Failed allocating %d bytes\n", __func__, ascii_len); err = -ENOMEM; goto out_free_buff; } /* * the descriptor contains string in UTF16 format * we need to convert to utf-8 so it can be displayed */ utf16s_to_utf8s((wchar_t *)&buf[QUERY_DESC_HDR_SIZE], desc_len - QUERY_DESC_HDR_SIZE, UTF16_BIG_ENDIAN, buff_ascii, ascii_len); /* replace non-printable or non-ASCII characters with spaces */ for (i = 0; i < ascii_len; i++) ufshcd_remove_non_printable(&buff_ascii[i]); memset(buf + QUERY_DESC_HDR_SIZE, 0, size - QUERY_DESC_HDR_SIZE); memcpy(buf + QUERY_DESC_HDR_SIZE, buff_ascii, ascii_len); buf[QUERY_DESC_LENGTH_OFFSET] = ascii_len + QUERY_DESC_HDR_SIZE; out_free_buff: kfree(buff_ascii); } out: return err; } /** * ufshcd_read_unit_desc_param - read the specified unit descriptor parameter * @hba: Pointer to adapter instance Loading drivers/scsi/ufs/ufshcd.h +4 −0 Original line number Diff line number Diff line Loading @@ -704,6 +704,10 @@ static inline int ufshcd_dme_peer_get(struct ufs_hba *hba, int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32 size); #define ASCII_STD true #define UTF16_STD false int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, u8 *buf, u32 size, bool ascii); /* variant specific ops structures */ #ifdef CONFIG_SCSI_UFS_MSM extern const struct ufs_hba_variant_ops ufs_hba_msm_vops; Loading Loading
drivers/scsi/ufs/ufs.h +1 −0 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ #define GENERAL_UPIU_REQUEST_SIZE 32 #define QUERY_DESC_MAX_SIZE 255 #define QUERY_DESC_MIN_SIZE 2 #define QUERY_DESC_HDR_SIZE 2 #define QUERY_OSF_SIZE (GENERAL_UPIU_REQUEST_SIZE - \ (sizeof(struct utp_upiu_header))) Loading
drivers/scsi/ufs/ufshcd.c +89 −0 Original line number Diff line number Diff line Loading @@ -40,6 +40,7 @@ #include <linux/async.h> #include <scsi/ufs/ioctl.h> #include <linux/devfreq.h> #include <linux/nls.h> #include "ufshcd.h" #include "unipro.h" Loading Loading @@ -270,6 +271,16 @@ static inline void ufshcd_disable_irq(struct ufs_hba *hba) } } /* replace non-printable or non-ASCII characters with spaces */ static inline void ufshcd_remove_non_printable(char *val) { if (!val) return; if (*val < 0x20 || *val > 0x7e) *val = ' '; } static void ufshcd_print_host_regs(struct ufs_hba *hba) { /* Loading Loading @@ -2123,6 +2134,84 @@ int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32 size) return err; } /** * ufshcd_read_string_desc - read string descriptor * @hba: pointer to adapter instance * @desc_index: descriptor index * @buf: pointer to buffer where descriptor would be read * @size: size of buf * @ascii: if true convert from unicode to ascii characters * * Return 0 in case of success, non-zero otherwise */ int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, u8 *buf, u32 size, bool ascii) { int err = 0; int retries; for (retries = 0; retries < QUERY_REQ_RETRIES; retries++) { err = ufshcd_read_desc(hba, QUERY_DESC_IDN_STRING, desc_index, buf, size); if (!err) break; dev_dbg(hba->dev, "%s: error %d retrying %d\n", __func__, err, retries); } if (err) { dev_err(hba->dev, "%s: reading String Desc failed after %d retries. err = %d\n", __func__, QUERY_REQ_RETRIES, err); goto out; } if (ascii) { int desc_len; int ascii_len; int i; char *buff_ascii; desc_len = buf[0]; /* remove header and divide by 2 to move from UTF16 to UTF8 */ ascii_len = (desc_len - QUERY_DESC_HDR_SIZE) / 2 + 1; if (size < ascii_len + QUERY_DESC_HDR_SIZE) { dev_err(hba->dev, "%s: buffer allocated size is too small\n", __func__); err = -ENOMEM; goto out; } buff_ascii = kmalloc(ascii_len, GFP_KERNEL); if (!buff_ascii) { dev_err(hba->dev, "%s: Failed allocating %d bytes\n", __func__, ascii_len); err = -ENOMEM; goto out_free_buff; } /* * the descriptor contains string in UTF16 format * we need to convert to utf-8 so it can be displayed */ utf16s_to_utf8s((wchar_t *)&buf[QUERY_DESC_HDR_SIZE], desc_len - QUERY_DESC_HDR_SIZE, UTF16_BIG_ENDIAN, buff_ascii, ascii_len); /* replace non-printable or non-ASCII characters with spaces */ for (i = 0; i < ascii_len; i++) ufshcd_remove_non_printable(&buff_ascii[i]); memset(buf + QUERY_DESC_HDR_SIZE, 0, size - QUERY_DESC_HDR_SIZE); memcpy(buf + QUERY_DESC_HDR_SIZE, buff_ascii, ascii_len); buf[QUERY_DESC_LENGTH_OFFSET] = ascii_len + QUERY_DESC_HDR_SIZE; out_free_buff: kfree(buff_ascii); } out: return err; } /** * ufshcd_read_unit_desc_param - read the specified unit descriptor parameter * @hba: Pointer to adapter instance Loading
drivers/scsi/ufs/ufshcd.h +4 −0 Original line number Diff line number Diff line Loading @@ -704,6 +704,10 @@ static inline int ufshcd_dme_peer_get(struct ufs_hba *hba, int ufshcd_read_device_desc(struct ufs_hba *hba, u8 *buf, u32 size); #define ASCII_STD true #define UTF16_STD false int ufshcd_read_string_desc(struct ufs_hba *hba, int desc_index, u8 *buf, u32 size, bool ascii); /* variant specific ops structures */ #ifdef CONFIG_SCSI_UFS_MSM extern const struct ufs_hba_variant_ops ufs_hba_msm_vops; Loading