| @@ -658,19 +658,25 @@ static int ioctl_flash_part_info(struct switchtec_dev *stdev, · 657 unmodified lines |
| 658 | | 658 | |
| 659 | static int ioctl_event_summary(struct switchtec_dev *stdev, | 659 | static int ioctl_event_summary(struct switchtec_dev *stdev, |
| 660 | struct switchtec_user *stuser, | 660 | struct switchtec_user *stuser, |
| 661 | struct switchtec_ioctl_event_summary __user *usum) | 661 | struct switchtec_ioctl_event_summary __user *usum, |
| | 662 | size_t size) |
| 662 | { | 663 | { |
| 663 | struct switchtec_ioctl_event_summary s = {0}; | 664 | struct switchtec_ioctl_event_summary *s; |
| 664 | int i; | 665 | int i; |
| 665 | u32 reg; | 666 | u32 reg; |
| | 667 | int ret = 0; |
| 666 | | 668 | |
| 667 | s.global = ioread32(&stdev->mmio_sw_event->global_summary); | 669 | s = kzalloc(sizeof(*s), GFP_KERNEL); |
| 668 | s.part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap); | 670 | if (!s) |
| 669 | s.local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary); | 671 | return -ENOMEM; |
| | 672 | |
| | 673 | s->global = ioread32(&stdev->mmio_sw_event->global_summary); |
| | 674 | s->part_bitmap = ioread32(&stdev->mmio_sw_event->part_event_bitmap); |
| | 675 | s->local_part = ioread32(&stdev->mmio_part_cfg->part_event_summary); |
| 670 | | 676 | |
| 671 | for (i = 0; i < stdev->partition_count; i++) { | 677 | for (i = 0; i < stdev->partition_count; i++) { |
| 672 | reg = ioread32(&stdev->mmio_part_cfg_all[i].part_event_summary); | 678 | reg = ioread32(&stdev->mmio_part_cfg_all[i].part_event_summary); |
| 673 | s.part[i] = reg; | 679 | s->part[i] = reg; |
| 674 | } | 680 | } |
| 675 | | 681 | |
| 676 | for (i = 0; i < SWITCHTEC_MAX_PFF_CSR; i++) { | 682 | for (i = 0; i < SWITCHTEC_MAX_PFF_CSR; i++) { |
| @@ -679,15 +685,19 @@ static int ioctl_event_summary(struct switchtec_dev *stdev, · 2 unmodified lines |
| 679 | break; | 685 | break; |
| 680 | | 686 | |
| 681 | reg = ioread32(&stdev->mmio_pff_csr[i].pff_event_summary); | 687 | reg = ioread32(&stdev->mmio_pff_csr[i].pff_event_summary); |
| 682 | s.pff[i] = reg; | 688 | s->pff[i] = reg; |
| 683 | } | 689 | } |
| 684 | | 690 | |
| 685 | if (copy_to_user(usum, &s, sizeof(s))) | 691 | if (copy_to_user(usum, s, size)) { |
| 686 | return -EFAULT; | 692 | ret = -EFAULT; |
| | 693 | goto error_case; |
| | 694 | } |
| 687 | | 695 | |
| 688 | stuser->event_cnt = atomic_read(&stdev->event_cnt); | 696 | stuser->event_cnt = atomic_read(&stdev->event_cnt); |
| 689 | | 697 | |
| 690 | return 0; | 698 | error_case: |
| | 699 | kfree(s); |
| | 700 | return ret; |
| 691 | } | 701 | } |
| 692 | | 702 | |
| 693 | static u32 __iomem *global_ev_reg(struct switchtec_dev *stdev, | 703 | 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, · 283 unmodified lines |
| 977 | case SWITCHTEC_IOCTL_FLASH_PART_INFO: | 987 | case SWITCHTEC_IOCTL_FLASH_PART_INFO: |
| 978 | rc = ioctl_flash_part_info(stdev, argp); | 988 | rc = ioctl_flash_part_info(stdev, argp); |
| 979 | break; | 989 | break; |
| 980 | case SWITCHTEC_IOCTL_EVENT_SUMMARY: | 990 | case SWITCHTEC_IOCTL_EVENT_SUMMARY_LEGACY: |
| 981 | rc = ioctl_event_summary(stdev, stuser, argp); | 991 | rc = ioctl_event_summary(stdev, stuser, argp, |
| | 992 | sizeof(struct switchtec_ioctl_event_summary_legacy)); |
| 982 | break; | 993 | break; |
| 983 | case SWITCHTEC_IOCTL_EVENT_CTL: | 994 | case SWITCHTEC_IOCTL_EVENT_CTL: |
| 984 | rc = ioctl_event_ctl(stdev, argp); | 995 | rc = ioctl_event_ctl(stdev, argp); |
| @@ -989,6 +1000,10 @@ static long switchtec_dev_ioctl(struct file *filp, unsigned int cmd, · 4 unmodified lines |
| 989 | case SWITCHTEC_IOCTL_PORT_TO_PFF: | 1000 | case SWITCHTEC_IOCTL_PORT_TO_PFF: |
| 990 | rc = ioctl_port_to_pff(stdev, argp); | 1001 | rc = ioctl_port_to_pff(stdev, argp); |
| 991 | break; | 1002 | break; |
| | 1003 | case SWITCHTEC_IOCTL_EVENT_SUMMARY: |
| | 1004 | rc = ioctl_event_summary(stdev, stuser, argp, |
| | 1005 | sizeof(struct switchtec_ioctl_event_summary)); |
| | 1006 | break; |
| 992 | default: | 1007 | default: |
| 993 | rc = -ENOTTY; | 1008 | rc = -ENOTTY; |
| 994 | break; | 1009 | break; |
| @@ -1162,7 +1177,8 @@ static int mask_event(struct switchtec_dev *stdev, int eid, int idx) · 167 unmodified lines |
| 1162 | if (!(hdr & SWITCHTEC_EVENT_OCCURRED && hdr & SWITCHTEC_EVENT_EN_IRQ)) | 1177 | if (!(hdr & SWITCHTEC_EVENT_OCCURRED && hdr & SWITCHTEC_EVENT_EN_IRQ)) |
| 1163 | return 0; | 1178 | return 0; |
| 1164 | | 1179 | |
| 1165 | if (eid == SWITCHTEC_IOCTL_EVENT_LINK_STATE) | 1180 | if (eid == SWITCHTEC_IOCTL_EVENT_LINK_STATE || |
| | 1181 | eid == SWITCHTEC_IOCTL_EVENT_MRPC_COMP) |
| 1166 | return 0; | 1182 | return 0; |
| 1167 | | 1183 | |
| 1168 | dev_dbg(&stdev->dev, "%s: %d %d %x\n", __func__, eid, idx, hdr); | 1184 | dev_dbg(&stdev->dev, "%s: %d %d %x\n", __func__, eid, idx, hdr); |