diff options
Diffstat (limited to 'drivers/net/enic/vnic_dev.c')
-rw-r--r-- | drivers/net/enic/vnic_dev.c | 52 |
1 files changed, 41 insertions, 11 deletions
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c index 69b9b70c7da..cbc0ba953fc 100644 --- a/drivers/net/enic/vnic_dev.c +++ b/drivers/net/enic/vnic_dev.c | |||
@@ -573,22 +573,18 @@ int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr) | |||
573 | return err; | 573 | return err; |
574 | } | 574 | } |
575 | 575 | ||
576 | int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) | 576 | int vnic_dev_notify_setcmd(struct vnic_dev *vdev, |
577 | void *notify_addr, dma_addr_t notify_pa, u16 intr) | ||
577 | { | 578 | { |
578 | u64 a0, a1; | 579 | u64 a0, a1; |
579 | int wait = 1000; | 580 | int wait = 1000; |
580 | int r; | 581 | int r; |
581 | 582 | ||
582 | if (!vdev->notify) { | 583 | memset(notify_addr, 0, sizeof(struct vnic_devcmd_notify)); |
583 | vdev->notify = pci_alloc_consistent(vdev->pdev, | 584 | vdev->notify = notify_addr; |
584 | sizeof(struct vnic_devcmd_notify), | 585 | vdev->notify_pa = notify_pa; |
585 | &vdev->notify_pa); | ||
586 | if (!vdev->notify) | ||
587 | return -ENOMEM; | ||
588 | memset(vdev->notify, 0, sizeof(struct vnic_devcmd_notify)); | ||
589 | } | ||
590 | 586 | ||
591 | a0 = vdev->notify_pa; | 587 | a0 = (u64)notify_pa; |
592 | a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL; | 588 | a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL; |
593 | a1 += sizeof(struct vnic_devcmd_notify); | 589 | a1 += sizeof(struct vnic_devcmd_notify); |
594 | 590 | ||
@@ -597,7 +593,27 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) | |||
597 | return r; | 593 | return r; |
598 | } | 594 | } |
599 | 595 | ||
600 | void vnic_dev_notify_unset(struct vnic_dev *vdev) | 596 | int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr) |
597 | { | ||
598 | void *notify_addr; | ||
599 | dma_addr_t notify_pa; | ||
600 | |||
601 | if (vdev->notify || vdev->notify_pa) { | ||
602 | printk(KERN_ERR "notify block %p still allocated", | ||
603 | vdev->notify); | ||
604 | return -EINVAL; | ||
605 | } | ||
606 | |||
607 | notify_addr = pci_alloc_consistent(vdev->pdev, | ||
608 | sizeof(struct vnic_devcmd_notify), | ||
609 | ¬ify_pa); | ||
610 | if (!notify_addr) | ||
611 | return -ENOMEM; | ||
612 | |||
613 | return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr); | ||
614 | } | ||
615 | |||
616 | void vnic_dev_notify_unsetcmd(struct vnic_dev *vdev) | ||
601 | { | 617 | { |
602 | u64 a0, a1; | 618 | u64 a0, a1; |
603 | int wait = 1000; | 619 | int wait = 1000; |
@@ -607,9 +623,23 @@ void vnic_dev_notify_unset(struct vnic_dev *vdev) | |||
607 | a1 += sizeof(struct vnic_devcmd_notify); | 623 | a1 += sizeof(struct vnic_devcmd_notify); |
608 | 624 | ||
609 | vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); | 625 | vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait); |
626 | vdev->notify = NULL; | ||
627 | vdev->notify_pa = 0; | ||
610 | vdev->notify_sz = 0; | 628 | vdev->notify_sz = 0; |
611 | } | 629 | } |
612 | 630 | ||
631 | void vnic_dev_notify_unset(struct vnic_dev *vdev) | ||
632 | { | ||
633 | if (vdev->notify) { | ||
634 | pci_free_consistent(vdev->pdev, | ||
635 | sizeof(struct vnic_devcmd_notify), | ||
636 | vdev->notify, | ||
637 | vdev->notify_pa); | ||
638 | } | ||
639 | |||
640 | vnic_dev_notify_unsetcmd(vdev); | ||
641 | } | ||
642 | |||
613 | static int vnic_dev_notify_ready(struct vnic_dev *vdev) | 643 | static int vnic_dev_notify_ready(struct vnic_dev *vdev) |
614 | { | 644 | { |
615 | u32 *words; | 645 | u32 *words; |