summaryrefslogtreecommitdiff
path: root/drivers/pci/switch/switchtec.c
diff options
context:
space:
mode:
authorWesley Sheng <wesley.sheng@microchip.com>2019-04-15 17:41:41 +0300
committerBjorn Helgaas <bhelgaas@google.com>2019-04-18 01:20:01 +0300
commitba8a39820d4614b2b04ac74a48d1f8de677de750 (patch)
tree9417afa76040060adf44718e3548f4d1748cc614 /drivers/pci/switch/switchtec.c
parent9e98c678c2d6ae3a17cb2de55d17f69dddaa231b (diff)
downloadlinux-ba8a39820d4614b2b04ac74a48d1f8de677de750.tar.xz
switchtec: Increase PFF limit from 48 to 255
The Switchtec devices supports two PCIe Function Frameworks (PFFs) per upstream port (one for the port itself and one for the management endoint), and each PFF may have up to 255 ports. Previously the driver only supported 48 of those ports, and the SWITCHTEC_IOCTL_EVENT_SUMMARY ioctl only returned information about those 48. Increase SWITCHTEC_MAX_PFF_CSR from 48 to 255 so the driver supports all 255 possible ports. Rename SWITCHTEC_IOCTL_EVENT_SUMMARY and associated struct switchtec_ioctl_event_summary to SWITCHTEC_IOCTL_EVENT_SUMMARY_LEGACY and switchtec_ioctl_event_summary_legacy with so existing applications work unchanged, supporting up to 48 ports. Add replacement SWITCHTEC_IOCTL_EVENT_SUMMARY and struct switchtec_ioctl_event_summary that new and recompiled applications support up to 255 ports. Signed-off-by: Wesley Sheng <wesley.sheng@microchip.com> [bhelgaas: changelog] Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Reviewed-by: Logan Gunthorpe <logang@deltatee.com>
Diffstat (limited to 'drivers/pci/switch/switchtec.c')
-rw-r--r--drivers/pci/switch/switchtec.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/drivers/pci/switch/switchtec.c b/drivers/pci/switch/switchtec.c
index e22766c79fe9..7df9a69f7d93 100644
--- a/drivers/pci/switch/switchtec.c
+++ b/drivers/pci/switch/switchtec.c
@@ -658,19 +658,25 @@ static int ioctl_flash_part_info(struct switchtec_dev *stdev,
static int ioctl_event_summary(struct switchtec_dev *stdev,
struct switchtec_user *stuser,
- struct switchtec_ioctl_event_summary __user *usum)
+ struct switchtec_ioctl_event_summary __user *usum,
+ size_t size)
{
- struct switchtec_ioctl_event_summary s = {0};
+ struct switchtec_ioctl_event_summary *s;
int i;
u32 reg;
+ int ret = 0;
- s.global = ioread32(&stdev->mmio_sw_event->global_summary);
- s.part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap);
- s.local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary);
+ s = kzalloc(sizeof(*s), GFP_KERNEL);
+ if (!s)
+ return -ENOMEM;
+
+ s->global = ioread32(&stdev->mmio_sw_event->global_summary);
+ s->part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap);
+ s->local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary);
for (i = 0; i < stdev->partition_count; i++) {
reg = ioread32(&stdev->mmio_part_cfg_all[i].part_event_summary);
- s.part[i] = reg;
+ s->part[i] = reg;
}
for (i = 0; i < SWITCHTEC_MAX_PFF_CSR; i++) {
@@ -679,15 +685,19 @@ static int ioctl_event_summary(struct switchtec_dev *stdev,
break;
reg = ioread32(&stdev->mmio_pff_csr[i].pff_event_summary);
- s.pff[i] = reg;
+ s->pff[i] = reg;
}
- if (copy_to_user(usum, &s, sizeof(s)))
- return -EFAULT;
+ if (copy_to_user(usum, s, size)) {
+ ret = -EFAULT;
+ goto error_case;
+ }
stuser->event_cnt = atomic_read(&stdev->event_cnt);
- return 0;
+error_case:
+ kfree(s);
+ return ret;
}
static u32 __iomem *global_ev_reg(struct switchtec_dev *stdev,
@@ -977,8 +987,9 @@ static long switchtec_dev_ioctl(struct file *filp, unsigned int cmd,
case SWITCHTEC_IOCTL_FLASH_PART_INFO:
rc = ioctl_flash_part_info(stdev, argp);
break;
- case SWITCHTEC_IOCTL_EVENT_SUMMARY:
- rc = ioctl_event_summary(stdev, stuser, argp);
+ case SWITCHTEC_IOCTL_EVENT_SUMMARY_LEGACY:
+ rc = ioctl_event_summary(stdev, stuser, argp,
+ sizeof(struct switchtec_ioctl_event_summary_legacy));
break;
case SWITCHTEC_IOCTL_EVENT_CTL:
rc = ioctl_event_ctl(stdev, argp);
@@ -989,6 +1000,10 @@ static long switchtec_dev_ioctl(struct file *filp, unsigned int cmd,
case SWITCHTEC_IOCTL_PORT_TO_PFF:
rc = ioctl_port_to_pff(stdev, argp);
break;
+ case SWITCHTEC_IOCTL_EVENT_SUMMARY:
+ rc = ioctl_event_summary(stdev, stuser, argp,
+ sizeof(struct switchtec_ioctl_event_summary));
+ break;
default:
rc = -ENOTTY;
break;