Skip to content

Commit 6eec61b

Browse files
committed
switchtec: Fix false maximum supported PCIe function number issue
The maximum supported PCIe function number is set to 255 instead of the false 48. To be backward compatible, a new ioctl and corresponding data structure are created, while keep the deprecated one. Signed-off-by: Wesley Sheng <[email protected]>
1 parent 3e90056 commit 6eec61b

File tree

3 files changed

+40
-14
lines changed

3 files changed

+40
-14
lines changed

linux/switchtec.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#define MICROSEMI_MGMT_CLASSCODE 0x058000
2525

2626
#define SWITCHTEC_MRPC_PAYLOAD_SIZE 1024
27-
#define SWITCHTEC_MAX_PFF_CSR 48
27+
#define SWITCHTEC_MAX_PFF_CSR 255
2828

2929
#define SWITCHTEC_EVENT_OCCURRED BIT(0)
3030
#define SWITCHTEC_EVENT_CLEAR BIT(0)

linux/switchtec_ioctl.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ struct switchtec_ioctl_flash_part_info {
5050
__u32 active;
5151
};
5252

53-
struct switchtec_ioctl_event_summary {
53+
struct switchtec_ioctl_event_summary_legacy {
5454
__u64 global;
5555
__u64 part_bitmap;
5656
__u32 local_part;
@@ -59,6 +59,15 @@ struct switchtec_ioctl_event_summary {
5959
__u32 pff[48];
6060
};
6161

62+
struct switchtec_ioctl_event_summary {
63+
__u64 global;
64+
__u64 part_bitmap;
65+
__u32 local_part;
66+
__u32 padding;
67+
__u32 part[48];
68+
__u32 pff[255];
69+
};
70+
6271
#define SWITCHTEC_IOCTL_EVENT_STACK_ERROR 0
6372
#define SWITCHTEC_IOCTL_EVENT_PPU_ERROR 1
6473
#define SWITCHTEC_IOCTL_EVENT_ISP_ERROR 2
@@ -128,6 +137,8 @@ struct switchtec_ioctl_pff_port {
128137
_IOWR('W', 0x41, struct switchtec_ioctl_flash_part_info)
129138
#define SWITCHTEC_IOCTL_EVENT_SUMMARY \
130139
_IOR('W', 0x42, struct switchtec_ioctl_event_summary)
140+
#define SWITCHTEC_IOCTL_EVENT_SUMMARY_LEGACY \
141+
_IOR('W', 0x42, struct switchtec_ioctl_event_summary_legacy)
131142
#define SWITCHTEC_IOCTL_EVENT_CTL \
132143
_IOWR('W', 0x43, struct switchtec_ioctl_event_ctl)
133144
#define SWITCHTEC_IOCTL_PFF_TO_PORT \

switchtec.c

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -666,19 +666,25 @@ static int ioctl_flash_part_info(struct switchtec_dev *stdev,
666666

667667
static int ioctl_event_summary(struct switchtec_dev *stdev,
668668
struct switchtec_user *stuser,
669-
struct switchtec_ioctl_event_summary __user *usum)
669+
struct switchtec_ioctl_event_summary __user *usum,
670+
size_t size)
670671
{
671-
struct switchtec_ioctl_event_summary s = {0};
672+
struct switchtec_ioctl_event_summary *s;
672673
int i;
673674
u32 reg;
675+
int ret = 0;
676+
677+
s = kzalloc(sizeof(*s), GFP_KERNEL);
678+
if (!s)
679+
return -ENOMEM;
674680

675-
s.global = ioread32(&stdev->mmio_sw_event->global_summary);
676-
s.part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap);
677-
s.local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary);
681+
s->global = ioread32(&stdev->mmio_sw_event->global_summary);
682+
s->part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap);
683+
s->local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary);
678684

679685
for (i = 0; i < stdev->partition_count; i++) {
680686
reg = ioread32(&stdev->mmio_part_cfg_all[i].part_event_summary);
681-
s.part[i] = reg;
687+
s->part[i] = reg;
682688
}
683689

684690
for (i = 0; i < SWITCHTEC_MAX_PFF_CSR; i++) {
@@ -687,15 +693,19 @@ static int ioctl_event_summary(struct switchtec_dev *stdev,
687693
break;
688694

689695
reg = ioread32(&stdev->mmio_pff_csr[i].pff_event_summary);
690-
s.pff[i] = reg;
696+
s->pff[i] = reg;
691697
}
692698

693-
if (copy_to_user(usum, &s, sizeof(s)))
694-
return -EFAULT;
699+
if (copy_to_user(usum, s, size)) {
700+
ret = -EFAULT;
701+
goto error_case;
702+
}
695703

696704
stuser->event_cnt = atomic_read(&stdev->event_cnt);
697705

698-
return 0;
706+
error_case:
707+
kfree(s);
708+
return ret;
699709
}
700710

701711
static u32 __iomem *global_ev_reg(struct switchtec_dev *stdev,
@@ -986,8 +996,9 @@ static long switchtec_dev_ioctl(struct file *filp, unsigned int cmd,
986996
case SWITCHTEC_IOCTL_FLASH_PART_INFO:
987997
rc = ioctl_flash_part_info(stdev, argp);
988998
break;
989-
case SWITCHTEC_IOCTL_EVENT_SUMMARY:
990-
rc = ioctl_event_summary(stdev, stuser, argp);
999+
case SWITCHTEC_IOCTL_EVENT_SUMMARY_LEGACY:
1000+
rc = ioctl_event_summary(stdev, stuser, argp,
1001+
sizeof(struct switchtec_ioctl_event_summary_legacy));
9911002
break;
9921003
case SWITCHTEC_IOCTL_EVENT_CTL:
9931004
rc = ioctl_event_ctl(stdev, argp);
@@ -998,6 +1009,10 @@ static long switchtec_dev_ioctl(struct file *filp, unsigned int cmd,
9981009
case SWITCHTEC_IOCTL_PORT_TO_PFF:
9991010
rc = ioctl_port_to_pff(stdev, argp);
10001011
break;
1012+
case SWITCHTEC_IOCTL_EVENT_SUMMARY:
1013+
rc = ioctl_event_summary(stdev, stuser, argp,
1014+
sizeof(struct switchtec_ioctl_event_summary));
1015+
break;
10011016
default:
10021017
rc = -ENOTTY;
10031018
break;

0 commit comments

Comments
 (0)