2 * Intel MIC Platform Software Stack (MPSS)
4 * Copyright(c) 2013 Intel Corporation.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License, version 2, as
8 * published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 * The full GNU General Public License is included in this distribution in
16 * the file called "COPYING".
18 * Intel MIC Host driver.
21 #include <linux/poll.h>
22 #include <linux/pci.h>
24 #include <linux/mic_common.h>
25 #include "../common/mic_dev.h"
26 #include "mic_device.h"
28 #include "mic_virtio.h"
30 int mic_open(struct inode
*inode
, struct file
*f
)
32 struct mic_vdev
*mvdev
;
33 struct mic_device
*mdev
= container_of(inode
->i_cdev
,
34 struct mic_device
, cdev
);
36 mvdev
= kzalloc(sizeof(*mvdev
), GFP_KERNEL
);
40 init_waitqueue_head(&mvdev
->waitq
);
41 INIT_LIST_HEAD(&mvdev
->list
);
43 mvdev
->virtio_id
= -1;
45 f
->private_data
= mvdev
;
49 int mic_release(struct inode
*inode
, struct file
*f
)
51 struct mic_vdev
*mvdev
= (struct mic_vdev
*)f
->private_data
;
53 if (-1 != mvdev
->virtio_id
)
54 mic_virtio_del_device(mvdev
);
55 f
->private_data
= NULL
;
60 long mic_ioctl(struct file
*f
, unsigned int cmd
, unsigned long arg
)
62 struct mic_vdev
*mvdev
= (struct mic_vdev
*)f
->private_data
;
63 void __user
*argp
= (void __user
*)arg
;
67 case MIC_VIRTIO_ADD_DEVICE
:
69 ret
= mic_virtio_add_device(mvdev
, argp
);
71 dev_err(mic_dev(mvdev
),
72 "%s %d errno ret %d\n",
73 __func__
, __LINE__
, ret
);
78 case MIC_VIRTIO_COPY_DESC
:
80 struct mic_copy_desc copy
;
82 ret
= mic_vdev_inited(mvdev
);
86 if (copy_from_user(©
, argp
, sizeof(copy
)))
89 dev_dbg(mic_dev(mvdev
),
90 "%s %d === iovcnt 0x%x vr_idx 0x%x update_used %d\n",
91 __func__
, __LINE__
, copy
.iovcnt
, copy
.vr_idx
,
94 ret
= mic_virtio_copy_desc(mvdev
, ©
);
96 dev_err(mic_dev(mvdev
),
97 "%s %d errno ret %d\n",
98 __func__
, __LINE__
, ret
);
102 &((struct mic_copy_desc __user
*)argp
)->out_len
,
103 ©
.out_len
, sizeof(copy
.out_len
))) {
104 dev_err(mic_dev(mvdev
), "%s %d errno ret %d\n",
105 __func__
, __LINE__
, -EFAULT
);
110 case MIC_VIRTIO_CONFIG_CHANGE
:
112 ret
= mic_vdev_inited(mvdev
);
116 ret
= mic_virtio_config_change(mvdev
, argp
);
118 dev_err(mic_dev(mvdev
),
119 "%s %d errno ret %d\n",
120 __func__
, __LINE__
, ret
);
132 * We return POLLIN | POLLOUT from poll when new buffers are enqueued, and
133 * not when previously enqueued buffers may be available. This means that
134 * in the card->host (TX) path, when userspace is unblocked by poll it
135 * must drain all available descriptors or it can stall.
137 unsigned int mic_poll(struct file
*f
, poll_table
*wait
)
139 struct mic_vdev
*mvdev
= (struct mic_vdev
*)f
->private_data
;
142 poll_wait(f
, &mvdev
->waitq
, wait
);
144 if (mic_vdev_inited(mvdev
)) {
146 } else if (mvdev
->poll_wake
) {
147 mvdev
->poll_wake
= 0;
148 mask
= POLLIN
| POLLOUT
;
155 mic_query_offset(struct mic_vdev
*mvdev
, unsigned long offset
,
156 unsigned long *size
, unsigned long *pa
)
158 struct mic_device
*mdev
= mvdev
->mdev
;
159 unsigned long start
= MIC_DP_SIZE
;
163 * MMAP interface is as follows:
165 * 0x0 virtio device_page
167 * 0x1000 + size of 1st vring second vring
171 *pa
= virt_to_phys(mdev
->dp
);
176 for (i
= 0; i
< mvdev
->dd
->num_vq
; i
++) {
177 struct mic_vringh
*mvr
= &mvdev
->mvr
[i
];
178 if (offset
== start
) {
179 *pa
= virt_to_phys(mvr
->vring
.va
);
180 *size
= mvr
->vring
.len
;
183 start
+= mvr
->vring
.len
;
189 * Maps the device page and virtio rings to user space for readonly access.
192 mic_mmap(struct file
*f
, struct vm_area_struct
*vma
)
194 struct mic_vdev
*mvdev
= (struct mic_vdev
*)f
->private_data
;
195 unsigned long offset
= vma
->vm_pgoff
<< PAGE_SHIFT
;
196 unsigned long pa
, size
= vma
->vm_end
- vma
->vm_start
, size_rem
= size
;
199 err
= mic_vdev_inited(mvdev
);
203 if (vma
->vm_flags
& VM_WRITE
)
207 i
= mic_query_offset(mvdev
, offset
, &size
, &pa
);
210 err
= remap_pfn_range(vma
, vma
->vm_start
+ offset
,
211 pa
>> PAGE_SHIFT
, size
, vma
->vm_page_prot
);
214 dev_dbg(mic_dev(mvdev
),
215 "%s %d type %d size 0x%lx off 0x%lx pa 0x%lx vma 0x%lx\n",
216 __func__
, __LINE__
, mvdev
->virtio_id
, size
, offset
,
217 pa
, vma
->vm_start
+ offset
);