Skip to content

Commit 9411aac

Browse files
author
Jiri Kosina
committed
Merge branch 'for-6.13/intel-ish' into for-linus
- exposing firmware versions for Intel-ISH devices that load firmware from the host (Zhang Lixu) - switch to flex-array members (Erick Archer)
2 parents b14927b + ac0cba6 commit 9411aac

6 files changed

Lines changed: 144 additions & 18 deletions

File tree

drivers/hid/intel-ish-hid/ipc/pci-ish.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,13 +381,58 @@ static int __maybe_unused ish_resume(struct device *device)
381381

382382
static SIMPLE_DEV_PM_OPS(ish_pm_ops, ish_suspend, ish_resume);
383383

384+
static ssize_t base_version_show(struct device *cdev,
385+
struct device_attribute *attr, char *buf)
386+
{
387+
struct ishtp_device *dev = dev_get_drvdata(cdev);
388+
389+
return sysfs_emit(buf, "%u.%u.%u.%u\n", dev->base_ver.major,
390+
dev->base_ver.minor, dev->base_ver.hotfix,
391+
dev->base_ver.build);
392+
}
393+
static DEVICE_ATTR_RO(base_version);
394+
395+
static ssize_t project_version_show(struct device *cdev,
396+
struct device_attribute *attr, char *buf)
397+
{
398+
struct ishtp_device *dev = dev_get_drvdata(cdev);
399+
400+
return sysfs_emit(buf, "%u.%u.%u.%u\n", dev->prj_ver.major,
401+
dev->prj_ver.minor, dev->prj_ver.hotfix,
402+
dev->prj_ver.build);
403+
}
404+
static DEVICE_ATTR_RO(project_version);
405+
406+
static struct attribute *ish_firmware_attrs[] = {
407+
&dev_attr_base_version.attr,
408+
&dev_attr_project_version.attr,
409+
NULL
410+
};
411+
412+
static umode_t firmware_is_visible(struct kobject *kobj, struct attribute *attr,
413+
int i)
414+
{
415+
struct ishtp_device *dev = dev_get_drvdata(kobj_to_dev(kobj));
416+
417+
return dev->driver_data->fw_generation ? attr->mode : 0;
418+
}
419+
420+
static const struct attribute_group ish_firmware_group = {
421+
.name = "firmware",
422+
.attrs = ish_firmware_attrs,
423+
.is_visible = firmware_is_visible,
424+
};
425+
426+
__ATTRIBUTE_GROUPS(ish_firmware);
427+
384428
static struct pci_driver ish_driver = {
385429
.name = KBUILD_MODNAME,
386430
.id_table = ish_pci_tbl,
387431
.probe = ish_probe,
388432
.remove = ish_remove,
389433
.shutdown = ish_shutdown,
390434
.driver.pm = &ish_pm_ops,
435+
.dev_groups = ish_firmware_groups,
391436
};
392437

393438
module_pci_driver(ish_driver);

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

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
7070
unsigned char *payload;
7171
struct device_info *dev_info;
7272
int i, j;
73-
size_t payload_len, total_len, cur_pos, raw_len;
73+
size_t payload_len, total_len, cur_pos, raw_len, msg_len;
7474
int report_type;
7575
struct report_list *reports_list;
76-
char *reports;
76+
struct report *report;
7777
size_t report_len;
7878
struct ishtp_cl_data *client_data = ishtp_get_client_data(hid_ishtp_cl);
7979
int curr_hid_dev = client_data->cur_hid_dev;
@@ -280,14 +280,13 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
280280
case HOSTIF_PUBLISH_INPUT_REPORT_LIST:
281281
report_type = HID_INPUT_REPORT;
282282
reports_list = (struct report_list *)payload;
283-
reports = (char *)reports_list->reports;
283+
report = reports_list->reports;
284284

285285
for (j = 0; j < reports_list->num_of_reports; j++) {
286-
recv_msg = (struct hostif_msg *)(reports +
287-
sizeof(uint16_t));
288-
report_len = *(uint16_t *)reports;
289-
payload = reports + sizeof(uint16_t) +
290-
sizeof(struct hostif_msg_hdr);
286+
recv_msg = container_of(&report->msg,
287+
struct hostif_msg, hdr);
288+
report_len = report->size;
289+
payload = recv_msg->payload;
291290
payload_len = report_len -
292291
sizeof(struct hostif_msg_hdr);
293292

@@ -304,7 +303,7 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
304303
0);
305304
}
306305

307-
reports += sizeof(uint16_t) + report_len;
306+
report += sizeof(*report) + payload_len;
308307
}
309308
break;
310309
default:
@@ -316,12 +315,12 @@ static void process_recv(struct ishtp_cl *hid_ishtp_cl, void *recv_buf,
316315

317316
}
318317

319-
if (!cur_pos && cur_pos + payload_len +
320-
sizeof(struct hostif_msg) < total_len)
318+
msg_len = payload_len + sizeof(struct hostif_msg);
319+
if (!cur_pos && cur_pos + msg_len < total_len)
321320
++client_data->multi_packet_cnt;
322321

323-
cur_pos += payload_len + sizeof(struct hostif_msg);
324-
payload += payload_len + sizeof(struct hostif_msg);
322+
cur_pos += msg_len;
323+
payload += msg_len;
325324

326325
} while (cur_pos < total_len);
327326
}

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ struct hostif_msg_hdr {
3131

3232
struct hostif_msg {
3333
struct hostif_msg_hdr hdr;
34+
uint8_t payload[];
3435
} __packed;
3536

3637
struct hostif_msg_to_sensor {
@@ -52,15 +53,17 @@ struct ishtp_version {
5253
uint16_t build;
5354
} __packed;
5455

56+
struct report {
57+
uint16_t size;
58+
struct hostif_msg_hdr msg;
59+
} __packed;
60+
5561
/* struct for ISHTP aggregated input data */
5662
struct report_list {
5763
uint16_t total_size;
5864
uint8_t num_of_reports;
5965
uint8_t flags;
60-
struct {
61-
uint16_t size_of_report;
62-
uint8_t report[1];
63-
} __packed reports[1];
66+
struct report reports[];
6467
} __packed;
6568

6669
/* HOSTIF commands */

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,13 @@ struct ishtp_driver_data {
140140
char *fw_generation;
141141
};
142142

143+
struct ish_version {
144+
u16 major;
145+
u16 minor;
146+
u16 hotfix;
147+
u16 build;
148+
};
149+
143150
/**
144151
* struct ishtp_device - ISHTP private device struct
145152
*/
@@ -236,6 +243,11 @@ struct ishtp_device {
236243
/* Dump to trace buffers if enabled*/
237244
ishtp_print_log print_log;
238245

246+
/* Base version of Intel's released firmware */
247+
struct ish_version base_ver;
248+
/* Vendor-customized project version */
249+
struct ish_version prj_ver;
250+
239251
/* Debug stats */
240252
unsigned int ipc_rx_cnt;
241253
unsigned long long ipc_rx_bytes_cnt;

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

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,28 @@ static int request_ish_firmware(const struct firmware **firmware_p,
308308
return _request_ish_firmware(firmware_p, filename, dev);
309309
}
310310

311+
static int copy_manifest(const struct firmware *fw, struct ish_global_manifest *manifest)
312+
{
313+
u32 offset;
314+
315+
for (offset = 0; offset + sizeof(*manifest) < fw->size; offset += ISH_MANIFEST_ALIGNMENT) {
316+
memcpy(manifest, fw->data + offset, sizeof(*manifest));
317+
318+
if (le32_to_cpu(manifest->sig_fourcc) == ISH_GLOBAL_SIG)
319+
return 0;
320+
}
321+
322+
return -1;
323+
}
324+
325+
static void copy_ish_version(struct version_in_manifest *src, struct ish_version *dst)
326+
{
327+
dst->major = le16_to_cpu(src->major);
328+
dst->minor = le16_to_cpu(src->minor);
329+
dst->hotfix = le16_to_cpu(src->hotfix);
330+
dst->build = le16_to_cpu(src->build);
331+
}
332+
311333
/**
312334
* ishtp_loader_work() - Load the ISHTP firmware
313335
* @work: The work structure
@@ -336,6 +358,7 @@ void ishtp_loader_work(struct work_struct *work)
336358
struct loader_xfer_query query = { .header = cpu_to_le32(query_hdr.val32), };
337359
struct loader_start start = { .header = cpu_to_le32(start_hdr.val32), };
338360
union loader_recv_message recv_msg;
361+
struct ish_global_manifest manifest;
339362
const struct firmware *ish_fw;
340363
void *dma_bufs[FRAGMENT_MAX_NUM] = {};
341364
u32 fragment_size;
@@ -372,7 +395,7 @@ void ishtp_loader_work(struct work_struct *work)
372395
if (rv)
373396
continue; /* try again if failed */
374397

375-
dev_dbg(dev->devc, "ISH Version %u.%u.%u.%u\n",
398+
dev_dbg(dev->devc, "ISH Bootloader Version %u.%u.%u.%u\n",
376399
recv_msg.query_ack.version_major,
377400
recv_msg.query_ack.version_minor,
378401
recv_msg.query_ack.version_hotfix,
@@ -390,6 +413,16 @@ void ishtp_loader_work(struct work_struct *work)
390413
continue; /* try again if failed */
391414

392415
dev_info(dev->devc, "firmware loaded. size:%zu\n", ish_fw->size);
416+
if (!copy_manifest(ish_fw, &manifest)) {
417+
copy_ish_version(&manifest.base_ver, &dev->base_ver);
418+
copy_ish_version(&manifest.prj_ver, &dev->prj_ver);
419+
dev_info(dev->devc, "FW base version: %u.%u.%u.%u\n",
420+
dev->base_ver.major, dev->base_ver.minor,
421+
dev->base_ver.hotfix, dev->base_ver.build);
422+
dev_info(dev->devc, "FW project version: %u.%u.%u.%u\n",
423+
dev->prj_ver.major, dev->prj_ver.minor,
424+
dev->prj_ver.hotfix, dev->prj_ver.build);
425+
}
393426
break;
394427
} while (--retry);
395428

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#include <linux/bits.h>
1212
#include <linux/jiffies.h>
13+
#include <linux/sizes.h>
1314
#include <linux/types.h>
1415

1516
#include "ishtp-dev.h"
@@ -228,4 +229,37 @@ struct ish_firmware_variant {
228229
*/
229230
void ishtp_loader_work(struct work_struct *work);
230231

232+
/* ISH Manifest alignment in binary is 4KB aligned */
233+
#define ISH_MANIFEST_ALIGNMENT SZ_4K
234+
235+
/* Signature for ISH global manifest */
236+
#define ISH_GLOBAL_SIG 0x47485349 /* FourCC 'I', 'S', 'H', 'G' */
237+
238+
struct version_in_manifest {
239+
__le16 major;
240+
__le16 minor;
241+
__le16 hotfix;
242+
__le16 build;
243+
};
244+
245+
/**
246+
* struct ish_global_manifest - global manifest for ISH
247+
* @sig_fourcc: Signature FourCC, should be 'I', 'S', 'H', 'G'.
248+
* @len: Length of the manifest.
249+
* @header_version: Version of the manifest header.
250+
* @flags: Flags for additional information.
251+
* @base_ver: Base version of Intel's released firmware.
252+
* @reserved: Reserved space for future use.
253+
* @prj_ver: Vendor-customized project version.
254+
*/
255+
struct ish_global_manifest {
256+
__le32 sig_fourcc;
257+
__le32 len;
258+
__le32 header_version;
259+
__le32 flags;
260+
struct version_in_manifest base_ver;
261+
__le32 reserved[13];
262+
struct version_in_manifest prj_ver;
263+
};
264+
231265
#endif /* _ISHTP_LOADER_H_ */

0 commit comments

Comments
 (0)