|
@@ -573,22 +573,18 @@ int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr)
|
|
|
return err;
|
|
|
}
|
|
|
|
|
|
-int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
|
|
|
+int vnic_dev_notify_setcmd(struct vnic_dev *vdev,
|
|
|
+ void *notify_addr, dma_addr_t notify_pa, u16 intr)
|
|
|
{
|
|
|
u64 a0, a1;
|
|
|
int wait = 1000;
|
|
|
int r;
|
|
|
|
|
|
- if (!vdev->notify) {
|
|
|
- vdev->notify = pci_alloc_consistent(vdev->pdev,
|
|
|
- sizeof(struct vnic_devcmd_notify),
|
|
|
- &vdev->notify_pa);
|
|
|
- if (!vdev->notify)
|
|
|
- return -ENOMEM;
|
|
|
- memset(vdev->notify, 0, sizeof(struct vnic_devcmd_notify));
|
|
|
- }
|
|
|
+ memset(notify_addr, 0, sizeof(struct vnic_devcmd_notify));
|
|
|
+ vdev->notify = notify_addr;
|
|
|
+ vdev->notify_pa = notify_pa;
|
|
|
|
|
|
- a0 = vdev->notify_pa;
|
|
|
+ a0 = (u64)notify_pa;
|
|
|
a1 = ((u64)intr << 32) & 0x0000ffff00000000ULL;
|
|
|
a1 += sizeof(struct vnic_devcmd_notify);
|
|
|
|
|
@@ -597,7 +593,27 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
|
|
|
return r;
|
|
|
}
|
|
|
|
|
|
-void vnic_dev_notify_unset(struct vnic_dev *vdev)
|
|
|
+int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
|
|
|
+{
|
|
|
+ void *notify_addr;
|
|
|
+ dma_addr_t notify_pa;
|
|
|
+
|
|
|
+ if (vdev->notify || vdev->notify_pa) {
|
|
|
+ printk(KERN_ERR "notify block %p still allocated",
|
|
|
+ vdev->notify);
|
|
|
+ return -EINVAL;
|
|
|
+ }
|
|
|
+
|
|
|
+ notify_addr = pci_alloc_consistent(vdev->pdev,
|
|
|
+ sizeof(struct vnic_devcmd_notify),
|
|
|
+ ¬ify_pa);
|
|
|
+ if (!notify_addr)
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr);
|
|
|
+}
|
|
|
+
|
|
|
+void vnic_dev_notify_unsetcmd(struct vnic_dev *vdev)
|
|
|
{
|
|
|
u64 a0, a1;
|
|
|
int wait = 1000;
|
|
@@ -607,9 +623,23 @@ void vnic_dev_notify_unset(struct vnic_dev *vdev)
|
|
|
a1 += sizeof(struct vnic_devcmd_notify);
|
|
|
|
|
|
vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
|
|
|
+ vdev->notify = NULL;
|
|
|
+ vdev->notify_pa = 0;
|
|
|
vdev->notify_sz = 0;
|
|
|
}
|
|
|
|
|
|
+void vnic_dev_notify_unset(struct vnic_dev *vdev)
|
|
|
+{
|
|
|
+ if (vdev->notify) {
|
|
|
+ pci_free_consistent(vdev->pdev,
|
|
|
+ sizeof(struct vnic_devcmd_notify),
|
|
|
+ vdev->notify,
|
|
|
+ vdev->notify_pa);
|
|
|
+ }
|
|
|
+
|
|
|
+ vnic_dev_notify_unsetcmd(vdev);
|
|
|
+}
|
|
|
+
|
|
|
static int vnic_dev_notify_ready(struct vnic_dev *vdev)
|
|
|
{
|
|
|
u32 *words;
|