Skip to content

Commit 9e438fe

Browse files
arndbJiri Kosina
authored andcommitted
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: 579a267 ("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>
1 parent 655a8a7 commit 9e438fe

File tree

2 files changed

+57
-45
lines changed

2 files changed

+57
-45
lines changed

drivers/hid/intel-ish-hid/ishtp/loader.c

Lines changed: 38 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -84,43 +84,46 @@ static int loader_write_message(struct ishtp_device *dev, void *buf, int len)
8484
static int loader_xfer_cmd(struct ishtp_device *dev, void *req, int req_len,
8585
void *resp, int resp_len)
8686
{
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;
8989
struct device *devc = dev->devc;
9090
int rv;
9191

9292
dev->fw_loader_rx_buf = resp;
9393
dev->fw_loader_rx_size = resp_len;
9494

9595
rv = loader_write_message(dev, req, req_len);
96+
req_hdr.val32 = le32_to_cpup(req);
97+
9698
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);
98100
return rv;
99101
}
100102

101103
/* Wait the ACK */
102104
wait_event_interruptible_timeout(dev->wait_loader_recvd_msg, dev->fw_loader_received,
103105
ISHTP_LOADER_TIMEOUT);
106+
resp_hdr.val32 = le32_to_cpup(resp);
104107
dev->fw_loader_rx_size = 0;
105108
dev->fw_loader_rx_buf = NULL;
106109
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);
108111
return -ETIMEDOUT;
109112
}
110113

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);
113116
return -EBADMSG;
114117
}
115118

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);
119122
return -EBADMSG;
120123
}
121124

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);
124127
return -EIO;
125128
}
126129

@@ -157,30 +160,33 @@ static void release_dma_bufs(struct ishtp_device *dev,
157160
* @fragment: The ISHTP firmware fragment descriptor
158161
* @dma_bufs: The array of DMA fragment buffers
159162
* @fragment_size: The size of a single DMA fragment
163+
* @fragment_count: Number of fragments
160164
*
161165
* Return: 0 on success, negative error code on failure
162166
*/
163167
static int prepare_dma_bufs(struct ishtp_device *dev,
164168
const struct firmware *ish_fw,
165169
struct loader_xfer_dma_fragment *fragment,
166-
void **dma_bufs, u32 fragment_size)
170+
void **dma_bufs, u32 fragment_size, u32 fragment_count)
167171
{
168172
dma_addr_t dma_addr;
169173
u32 offset = 0;
174+
u32 length;
170175
int i;
171176

172-
for (i = 0; i < fragment->fragment_cnt && offset < ish_fw->size; i++) {
177+
for (i = 0; i < fragment_count && offset < ish_fw->size; i++) {
173178
dma_bufs[i] = dma_alloc_coherent(dev->devc, fragment_size, &dma_addr, GFP_KERNEL);
174179
if (!dma_bufs[i])
175180
return -ENOMEM;
176181

177182
fragment->fragment_tbl[i].ddr_adrs = cpu_to_le64(dma_addr);
178-
fragment->fragment_tbl[i].length = clamp(ish_fw->size - offset, 0, fragment_size);
179-
fragment->fragment_tbl[i].fw_off = offset;
180-
memcpy(dma_bufs[i], ish_fw->data + offset, fragment->fragment_tbl[i].length);
183+
length = clamp(ish_fw->size - offset, 0, fragment_size);
184+
fragment->fragment_tbl[i].length = cpu_to_le32(length);
185+
fragment->fragment_tbl[i].fw_off = cpu_to_le32(offset);
186+
memcpy(dma_bufs[i], ish_fw->data + offset, length);
181187
clflush_cache_range(dma_bufs[i], fragment_size);
182188

183-
offset += fragment->fragment_tbl[i].length;
189+
offset += length;
184190
}
185191

186192
return 0;
@@ -208,17 +214,17 @@ void ishtp_loader_work(struct work_struct *work)
208214
{
209215
DEFINE_RAW_FLEX(struct loader_xfer_dma_fragment, fragment, fragment_tbl, FRAGMENT_MAX_NUM);
210216
struct ishtp_device *dev = container_of(work, struct ishtp_device, work_fw_loader);
211-
struct loader_xfer_query query = {
212-
.header.command = LOADER_CMD_XFER_QUERY,
213-
};
214-
struct loader_start start = {
215-
.header.command = LOADER_CMD_START,
216-
};
217+
union loader_msg_header query_hdr = { .command = LOADER_CMD_XFER_QUERY, };
218+
union loader_msg_header start_hdr = { .command = LOADER_CMD_START, };
219+
union loader_msg_header fragment_hdr = { .command = LOADER_CMD_XFER_FRAGMENT, };
220+
struct loader_xfer_query query = { .header = cpu_to_le32(query_hdr.val32), };
221+
struct loader_start start = { .header = cpu_to_le32(start_hdr.val32), };
217222
union loader_recv_message recv_msg;
218223
char *filename = dev->driver_data->fw_filename;
219224
const struct firmware *ish_fw;
220225
void *dma_bufs[FRAGMENT_MAX_NUM] = {};
221226
u32 fragment_size;
227+
u32 fragment_count;
222228
int retry = ISHTP_LOADER_RETRY_TIMES;
223229
int rv;
224230

@@ -228,23 +234,24 @@ void ishtp_loader_work(struct work_struct *work)
228234
return;
229235
}
230236

231-
fragment->fragment.header.command = LOADER_CMD_XFER_FRAGMENT;
232-
fragment->fragment.xfer_mode = LOADER_XFER_MODE_DMA;
233-
fragment->fragment.is_last = 1;
234-
fragment->fragment.size = ish_fw->size;
237+
fragment->fragment.header = cpu_to_le32(fragment_hdr.val32);
238+
fragment->fragment.xfer_mode = cpu_to_le32(LOADER_XFER_MODE_DMA);
239+
fragment->fragment.is_last = cpu_to_le32(1);
240+
fragment->fragment.size = cpu_to_le32(ish_fw->size);
235241
/* Calculate the size of a single DMA fragment */
236242
fragment_size = PFN_ALIGN(DIV_ROUND_UP(ish_fw->size, FRAGMENT_MAX_NUM));
237243
/* Calculate the count of DMA fragments */
238-
fragment->fragment_cnt = DIV_ROUND_UP(ish_fw->size, fragment_size);
244+
fragment_count = DIV_ROUND_UP(ish_fw->size, fragment_size);
245+
fragment->fragment_cnt = cpu_to_le32(fragment_count);
239246

240-
rv = prepare_dma_bufs(dev, ish_fw, fragment, dma_bufs, fragment_size);
247+
rv = prepare_dma_bufs(dev, ish_fw, fragment, dma_bufs, fragment_size, fragment_count);
241248
if (rv) {
242249
dev_err(dev->devc, "prepare DMA buffer failed.\n");
243250
goto out;
244251
}
245252

246253
do {
247-
query.image_size = ish_fw->size;
254+
query.image_size = cpu_to_le32(ish_fw->size);
248255
rv = loader_xfer_cmd(dev, &query, sizeof(query), recv_msg.raw_data,
249256
sizeof(struct loader_xfer_query_ack));
250257
if (rv)
@@ -257,7 +264,7 @@ void ishtp_loader_work(struct work_struct *work)
257264
recv_msg.query_ack.version_build);
258265

259266
rv = loader_xfer_cmd(dev, fragment,
260-
struct_size(fragment, fragment_tbl, fragment->fragment_cnt),
267+
struct_size(fragment, fragment_tbl, fragment_count),
261268
recv_msg.raw_data, sizeof(struct loader_xfer_fragment_ack));
262269
if (rv)
263270
continue; /* try again if failed */

drivers/hid/intel-ish-hid/ishtp/loader.h

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,23 @@ struct work_struct;
3030
#define LOADER_XFER_MODE_DMA BIT(0)
3131

3232
/**
33-
* struct loader_msg_header - ISHTP firmware loader message header
33+
* union loader_msg_header - ISHTP firmware loader message header
3434
* @command: Command type
3535
* @is_response: Indicates if the message is a response
3636
* @has_next: Indicates if there is a next message
3737
* @reserved: Reserved for future use
3838
* @status: Status of the message
39-
*/
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;
39+
* @val32: entire header as a 32-bit value
40+
*/
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;
4650
};
4751

4852
/**
@@ -51,7 +55,7 @@ struct loader_msg_header {
5155
* @image_size: Size of the image
5256
*/
5357
struct loader_xfer_query {
54-
struct loader_msg_header header;
58+
__le32 header;
5559
__le32 image_size;
5660
};
5761

@@ -103,7 +107,7 @@ struct loader_capability {
103107
* @capability: Loader capability
104108
*/
105109
struct loader_xfer_query_ack {
106-
struct loader_msg_header header;
110+
__le32 header;
107111
__le16 version_major;
108112
__le16 version_minor;
109113
__le16 version_hotfix;
@@ -122,7 +126,7 @@ struct loader_xfer_query_ack {
122126
* @is_last: Is last
123127
*/
124128
struct loader_xfer_fragment {
125-
struct loader_msg_header header;
129+
__le32 header;
126130
__le32 xfer_mode;
127131
__le32 offset;
128132
__le32 size;
@@ -134,7 +138,7 @@ struct loader_xfer_fragment {
134138
* @header: Header of the message
135139
*/
136140
struct loader_xfer_fragment_ack {
137-
struct loader_msg_header header;
141+
__le32 header;
138142
};
139143

140144
/**
@@ -170,18 +174,19 @@ struct loader_xfer_dma_fragment {
170174
* @header: Header of the message
171175
*/
172176
struct loader_start {
173-
struct loader_msg_header header;
177+
__le32 header;
174178
};
175179

176180
/**
177181
* struct loader_start_ack - ISHTP firmware loader start acknowledgment
178182
* @header: Header of the message
179183
*/
180184
struct loader_start_ack {
181-
struct loader_msg_header header;
185+
__le32 header;
182186
};
183187

184188
union loader_recv_message {
189+
__le32 header;
185190
struct loader_xfer_query_ack query_ack;
186191
struct loader_xfer_fragment_ack fragment_ack;
187192
struct loader_start_ack start_ack;

0 commit comments

Comments
 (0)