Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

HID: intel-ish-hid: fix endian-conversion

The newly added file causes a ton of sparse warnings about the
incorrect use of __le32 and similar types:

drivers/hid/intel-ish-hid/ishtp/loader.h:41:23: error: invalid bitfield specifier for type restricted __le32.
drivers/hid/intel-ish-hid/ishtp/loader.h:42:27: error: invalid bitfield specifier for type restricted __le32.
drivers/hid/intel-ish-hid/ishtp/loader.h:43:24: error: invalid bitfield specifier for type restricted __le32.
drivers/hid/intel-ish-hid/ishtp/loader.h:44:24: error: invalid bitfield specifier for type restricted __le32.
drivers/hid/intel-ish-hid/ishtp/loader.h:45:22: error: invalid bitfield specifier for type restricted __le32.
drivers/hid/intel-ish-hid/ishtp/loader.c:172:33: warning: restricted __le32 degrades to integer
drivers/hid/intel-ish-hid/ishtp/loader.c:178:50: warning: incorrect type in assignment (different base types)
drivers/hid/intel-ish-hid/ishtp/loader.c:178:50: expected restricted __le32 [usertype] length
drivers/hid/intel-ish-hid/ishtp/loader.c:178:50: got unsigned long
drivers/hid/intel-ish-hid/ishtp/loader.c:179:50: warning: incorrect type in assignment (different base types)
drivers/hid/intel-ish-hid/ishtp/loader.c:179:50: expected restricted __le32 [usertype] fw_off
drivers/hid/intel-ish-hid/ishtp/loader.c:179:50: got unsigned int [usertype] offset
drivers/hid/intel-ish-hid/ishtp/loader.c:180:17: warning: cast from restricted __le32
drivers/hid/intel-ish-hid/ishtp/loader.c:183:24: warning: invalid assignment: +=
drivers/hid/intel-ish-hid/ishtp/loader.c:183:24: left side has type unsigned int
drivers/hid/intel-ish-hid/ishtp/loader.c:183:24: right side has type restricted __le32

Add the necessary conversions and use temporary variables where appropriate
to avoid converting back.

Fixes: 579a267e4617 ("HID: intel-ish-hid: Implement loading firmware from host feature")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Reviewed-by: Zhang Lixu <lixu.zhang@intel.com>
Tested-by: Zhang Lixu <lixu.zhang@intel.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>

authored by

Arnd Bergmann and committed by
Jiri Kosina
9e438fe3 655a8a76

+56 -44
+38 -31
drivers/hid/intel-ish-hid/ishtp/loader.c
··· 84 84 static int loader_xfer_cmd(struct ishtp_device *dev, void *req, int req_len, 85 85 void *resp, int resp_len) 86 86 { 87 - struct loader_msg_header *req_hdr = req; 88 - struct loader_msg_header *resp_hdr = resp; 87 + union loader_msg_header req_hdr; 88 + union loader_msg_header resp_hdr; 89 89 struct device *devc = dev->devc; 90 90 int rv; 91 91 ··· 93 93 dev->fw_loader_rx_size = resp_len; 94 94 95 95 rv = loader_write_message(dev, req, req_len); 96 + req_hdr.val32 = le32_to_cpup(req); 97 + 96 98 if (rv < 0) { 97 - dev_err(devc, "write cmd %u failed:%d\n", req_hdr->command, rv); 99 + dev_err(devc, "write cmd %u failed:%d\n", req_hdr.command, rv); 98 100 return rv; 99 101 } 100 102 101 103 /* Wait the ACK */ 102 104 wait_event_interruptible_timeout(dev->wait_loader_recvd_msg, dev->fw_loader_received, 103 105 ISHTP_LOADER_TIMEOUT); 106 + resp_hdr.val32 = le32_to_cpup(resp); 104 107 dev->fw_loader_rx_size = 0; 105 108 dev->fw_loader_rx_buf = NULL; 106 109 if (!dev->fw_loader_received) { 107 - dev_err(devc, "wait response of cmd %u timeout\n", req_hdr->command); 110 + dev_err(devc, "wait response of cmd %u timeout\n", req_hdr.command); 108 111 return -ETIMEDOUT; 109 112 } 110 113 111 - if (!resp_hdr->is_response) { 112 - dev_err(devc, "not a response for %u\n", req_hdr->command); 114 + if (!resp_hdr.is_response) { 115 + dev_err(devc, "not a response for %u\n", req_hdr.command); 113 116 return -EBADMSG; 114 117 } 115 118 116 - if (req_hdr->command != resp_hdr->command) { 117 - dev_err(devc, "unexpected cmd response %u:%u\n", req_hdr->command, 118 - resp_hdr->command); 119 + if (req_hdr.command != resp_hdr.command) { 120 + dev_err(devc, "unexpected cmd response %u:%u\n", req_hdr.command, 121 + resp_hdr.command); 119 122 return -EBADMSG; 120 123 } 121 124 122 - if (resp_hdr->status) { 123 - dev_err(devc, "cmd %u failed %u\n", req_hdr->command, resp_hdr->status); 125 + if (resp_hdr.status) { 126 + dev_err(devc, "cmd %u failed %u\n", req_hdr.command, resp_hdr.status); 124 127 return -EIO; 125 128 } 126 129 ··· 160 157 * @fragment: The ISHTP firmware fragment descriptor 161 158 * @dma_bufs: The array of DMA fragment buffers 162 159 * @fragment_size: The size of a single DMA fragment 160 + * @fragment_count: Number of fragments 163 161 * 164 162 * Return: 0 on success, negative error code on failure 165 163 */ 166 164 static int prepare_dma_bufs(struct ishtp_device *dev, 167 165 const struct firmware *ish_fw, 168 166 struct loader_xfer_dma_fragment *fragment, 169 - void **dma_bufs, u32 fragment_size) 167 + void **dma_bufs, u32 fragment_size, u32 fragment_count) 170 168 { 171 169 dma_addr_t dma_addr; 172 170 u32 offset = 0; 171 + u32 length; 173 172 int i; 174 173 175 - for (i = 0; i < fragment->fragment_cnt && offset < ish_fw->size; i++) { 174 + for (i = 0; i < fragment_count && offset < ish_fw->size; i++) { 176 175 dma_bufs[i] = dma_alloc_coherent(dev->devc, fragment_size, &dma_addr, GFP_KERNEL); 177 176 if (!dma_bufs[i]) 178 177 return -ENOMEM; 179 178 180 179 fragment->fragment_tbl[i].ddr_adrs = cpu_to_le64(dma_addr); 181 - fragment->fragment_tbl[i].length = clamp(ish_fw->size - offset, 0, fragment_size); 182 - fragment->fragment_tbl[i].fw_off = offset; 183 - memcpy(dma_bufs[i], ish_fw->data + offset, fragment->fragment_tbl[i].length); 180 + length = clamp(ish_fw->size - offset, 0, fragment_size); 181 + fragment->fragment_tbl[i].length = cpu_to_le32(length); 182 + fragment->fragment_tbl[i].fw_off = cpu_to_le32(offset); 183 + memcpy(dma_bufs[i], ish_fw->data + offset, length); 184 184 clflush_cache_range(dma_bufs[i], fragment_size); 185 185 186 - offset += fragment->fragment_tbl[i].length; 186 + offset += length; 187 187 } 188 188 189 189 return 0; ··· 214 208 { 215 209 DEFINE_RAW_FLEX(struct loader_xfer_dma_fragment, fragment, fragment_tbl, FRAGMENT_MAX_NUM); 216 210 struct ishtp_device *dev = container_of(work, struct ishtp_device, work_fw_loader); 217 - struct loader_xfer_query query = { 218 - .header.command = LOADER_CMD_XFER_QUERY, 219 - }; 220 - struct loader_start start = { 221 - .header.command = LOADER_CMD_START, 222 - }; 211 + union loader_msg_header query_hdr = { .command = LOADER_CMD_XFER_QUERY, }; 212 + union loader_msg_header start_hdr = { .command = LOADER_CMD_START, }; 213 + union loader_msg_header fragment_hdr = { .command = LOADER_CMD_XFER_FRAGMENT, }; 214 + struct loader_xfer_query query = { .header = cpu_to_le32(query_hdr.val32), }; 215 + struct loader_start start = { .header = cpu_to_le32(start_hdr.val32), }; 223 216 union loader_recv_message recv_msg; 224 217 char *filename = dev->driver_data->fw_filename; 225 218 const struct firmware *ish_fw; 226 219 void *dma_bufs[FRAGMENT_MAX_NUM] = {}; 227 220 u32 fragment_size; 221 + u32 fragment_count; 228 222 int retry = ISHTP_LOADER_RETRY_TIMES; 229 223 int rv; 230 224 ··· 234 228 return; 235 229 } 236 230 237 - fragment->fragment.header.command = LOADER_CMD_XFER_FRAGMENT; 238 - fragment->fragment.xfer_mode = LOADER_XFER_MODE_DMA; 239 - fragment->fragment.is_last = 1; 240 - fragment->fragment.size = ish_fw->size; 231 + fragment->fragment.header = cpu_to_le32(fragment_hdr.val32); 232 + fragment->fragment.xfer_mode = cpu_to_le32(LOADER_XFER_MODE_DMA); 233 + fragment->fragment.is_last = cpu_to_le32(1); 234 + fragment->fragment.size = cpu_to_le32(ish_fw->size); 241 235 /* Calculate the size of a single DMA fragment */ 242 236 fragment_size = PFN_ALIGN(DIV_ROUND_UP(ish_fw->size, FRAGMENT_MAX_NUM)); 243 237 /* Calculate the count of DMA fragments */ 244 - fragment->fragment_cnt = DIV_ROUND_UP(ish_fw->size, fragment_size); 238 + fragment_count = DIV_ROUND_UP(ish_fw->size, fragment_size); 239 + fragment->fragment_cnt = cpu_to_le32(fragment_count); 245 240 246 - rv = prepare_dma_bufs(dev, ish_fw, fragment, dma_bufs, fragment_size); 241 + rv = prepare_dma_bufs(dev, ish_fw, fragment, dma_bufs, fragment_size, fragment_count); 247 242 if (rv) { 248 243 dev_err(dev->devc, "prepare DMA buffer failed.\n"); 249 244 goto out; 250 245 } 251 246 252 247 do { 253 - query.image_size = ish_fw->size; 248 + query.image_size = cpu_to_le32(ish_fw->size); 254 249 rv = loader_xfer_cmd(dev, &query, sizeof(query), recv_msg.raw_data, 255 250 sizeof(struct loader_xfer_query_ack)); 256 251 if (rv) ··· 264 257 recv_msg.query_ack.version_build); 265 258 266 259 rv = loader_xfer_cmd(dev, fragment, 267 - struct_size(fragment, fragment_tbl, fragment->fragment_cnt), 260 + struct_size(fragment, fragment_tbl, fragment_count), 268 261 recv_msg.raw_data, sizeof(struct loader_xfer_fragment_ack)); 269 262 if (rv) 270 263 continue; /* try again if failed */
+18 -13
drivers/hid/intel-ish-hid/ishtp/loader.h
··· 30 30 #define LOADER_XFER_MODE_DMA BIT(0) 31 31 32 32 /** 33 - * struct loader_msg_header - ISHTP firmware loader message header 33 + * union loader_msg_header - ISHTP firmware loader message header 34 34 * @command: Command type 35 35 * @is_response: Indicates if the message is a response 36 36 * @has_next: Indicates if there is a next message 37 37 * @reserved: Reserved for future use 38 38 * @status: Status of the message 39 + * @val32: entire header as a 32-bit value 39 40 */ 40 - struct loader_msg_header { 41 - __le32 command:7; 42 - __le32 is_response:1; 43 - __le32 has_next:1; 44 - __le32 reserved:15; 45 - __le32 status:8; 41 + union loader_msg_header { 42 + struct { 43 + __u32 command:7; 44 + __u32 is_response:1; 45 + __u32 has_next:1; 46 + __u32 reserved:15; 47 + __u32 status:8; 48 + }; 49 + __u32 val32; 46 50 }; 47 51 48 52 /** ··· 55 51 * @image_size: Size of the image 56 52 */ 57 53 struct loader_xfer_query { 58 - struct loader_msg_header header; 54 + __le32 header; 59 55 __le32 image_size; 60 56 }; 61 57 ··· 107 103 * @capability: Loader capability 108 104 */ 109 105 struct loader_xfer_query_ack { 110 - struct loader_msg_header header; 106 + __le32 header; 111 107 __le16 version_major; 112 108 __le16 version_minor; 113 109 __le16 version_hotfix; ··· 126 122 * @is_last: Is last 127 123 */ 128 124 struct loader_xfer_fragment { 129 - struct loader_msg_header header; 125 + __le32 header; 130 126 __le32 xfer_mode; 131 127 __le32 offset; 132 128 __le32 size; ··· 138 134 * @header: Header of the message 139 135 */ 140 136 struct loader_xfer_fragment_ack { 141 - struct loader_msg_header header; 137 + __le32 header; 142 138 }; 143 139 144 140 /** ··· 174 170 * @header: Header of the message 175 171 */ 176 172 struct loader_start { 177 - struct loader_msg_header header; 173 + __le32 header; 178 174 }; 179 175 180 176 /** ··· 182 178 * @header: Header of the message 183 179 */ 184 180 struct loader_start_ack { 185 - struct loader_msg_header header; 181 + __le32 header; 186 182 }; 187 183 188 184 union loader_recv_message { 185 + __le32 header; 189 186 struct loader_xfer_query_ack query_ack; 190 187 struct loader_xfer_fragment_ack fragment_ack; 191 188 struct loader_start_ack start_ack;