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>
23 #include <linux/mic_common.h>
24 #include "../common/mic_dev.h"
25 #include "mic_device.h"
27 #include "mic_virtio.h"
29 int mic_open(struct inode
*inode
, struct file
*f
)
31 struct mic_vdev
*mvdev
;
32 struct mic_device
*mdev
= container_of(inode
->i_cdev
,
33 struct mic_device
, cdev
);
35 mvdev
= kzalloc(sizeof(*mvdev
), GFP_KERNEL
);
39 init_waitqueue_head(&mvdev
->waitq
);
40 INIT_LIST_HEAD(&mvdev
->list
);
42 mvdev
->virtio_id
= -1;
44 f
->private_data
= mvdev
;
48 int mic_release(struct inode
*inode
, struct file
*f
)
50 struct mic_vdev
*mvdev
= (struct mic_vdev
*)f
->private_data
;
52 if (-1 != mvdev
->virtio_id
)
53 mic_virtio_del_device(mvdev
);
54 f
->private_data
= NULL
;
59 long mic_ioctl(struct file
*f
, unsigned int cmd
, unsigned long arg
)
61 struct mic_vdev
*mvdev
= (struct mic_vdev
*)f
->private_data
;
62 void __user
*argp
= (void __user
*)arg
;
66 case MIC_VIRTIO_ADD_DEVICE
:
68 ret
= mic_virtio_add_device(mvdev
, argp
);
70 dev_err(mic_dev(mvdev
),
71 "%s %d errno ret %d\n",
72 __func__
, __LINE__
, ret
);
77 case MIC_VIRTIO_COPY_DESC
:
79 struct mic_copy_desc copy
;
81 ret
= mic_vdev_inited(mvdev
);
85 if (copy_from_user(©
, argp
, sizeof(copy
)))
88 dev_dbg(mic_dev(mvdev
),
89 "%s %d === iovcnt 0x%x vr_idx 0x%x update_used %d\n",
90 __func__
, __LINE__
, copy
.iovcnt
, copy
.vr_idx
,
93 ret
= mic_virtio_copy_desc(mvdev
, ©
);
95 dev_err(mic_dev(mvdev
),
96 "%s %d errno ret %d\n",
97 __func__
, __LINE__
, ret
);
101 &((struct mic_copy_desc __user
*)argp
)->out_len
,
102 ©
.out_len
, sizeof(copy
.out_len
))) {
103 dev_err(mic_dev(mvdev
), "%s %d errno ret %d\n",
104 __func__
, __LINE__
, -EFAULT
);
109 case MIC_VIRTIO_CONFIG_CHANGE
:
111 ret
= mic_vdev_inited(mvdev
);
115 ret
= mic_virtio_config_change(mvdev
, argp
);
117 dev_err(mic_dev(mvdev
),
118 "%s %d errno ret %d\n",
119 __func__
, __LINE__
, ret
);
131 * We return POLLIN | POLLOUT from poll when new buffers are enqueued, and
132 * not when previously enqueued buffers may be available. This means that
133 * in the card->host (TX) path, when userspace is unblocked by poll it
134 * must drain all available descriptors or it can stall.
136 unsigned int mic_poll(struct file
*f
, poll_table
*wait
)
138 struct mic_vdev
*mvdev
= (struct mic_vdev
*)f
->private_data
;
141 poll_wait(f
, &mvdev
->waitq
, wait
);
143 if (mic_vdev_inited(mvdev
)) {
145 } else if (mvdev
->poll_wake
) {
146 mvdev
->poll_wake
= 0;
147 mask
= POLLIN
| POLLOUT
;
154 mic_query_offset(struct mic_vdev
*mvdev
, unsigned long offset
,
155 unsigned long *size
, unsigned long *pa
)
157 struct mic_device
*mdev
= mvdev
->mdev
;
158 unsigned long start
= MIC_DP_SIZE
;
162 * MMAP interface is as follows:
164 * 0x0 virtio device_page
166 * 0x1000 + size of 1st vring second vring
170 *pa
= virt_to_phys(mdev
->dp
);
175 for (i
= 0; i
< mvdev
->dd
->num_vq
; i
++) {
176 struct mic_vringh
*mvr
= &mvdev
->mvr
[i
];
177 if (offset
== start
) {
178 *pa
= virt_to_phys(mvr
->vring
.va
);
179 *size
= mvr
->vring
.len
;
182 start
+= mvr
->vring
.len
;
188 * Maps the device page and virtio rings to user space for readonly access.
191 mic_mmap(struct file
*f
, struct vm_area_struct
*vma
)
193 struct mic_vdev
*mvdev
= (struct mic_vdev
*)f
->private_data
;
194 unsigned long offset
= vma
->vm_pgoff
<< PAGE_SHIFT
;
195 unsigned long pa
, size
= vma
->vm_end
- vma
->vm_start
, size_rem
= size
;
198 err
= mic_vdev_inited(mvdev
);
202 if (vma
->vm_flags
& VM_WRITE
)
206 i
= mic_query_offset(mvdev
, offset
, &size
, &pa
);
209 err
= remap_pfn_range(vma
, vma
->vm_start
+ offset
,
210 pa
>> PAGE_SHIFT
, size
, vma
->vm_page_prot
);
213 dev_dbg(mic_dev(mvdev
),
214 "%s %d type %d size 0x%lx off 0x%lx pa 0x%lx vma 0x%lx\n",
215 __func__
, __LINE__
, mvdev
->virtio_id
, size
, offset
,
216 pa
, vma
->vm_start
+ offset
);
This page took 0.040804 seconds and 5 git commands to generate.