Lines Matching +full:device +full:- +full:unique

1 // SPDX-License-Identifier: GPL-2.0-or-later
8 * Adapted to become the Linux 2.0 Coda pseudo device
13 * Copyright (c) 1997 Carnegie-Mellon University
35 #include <linux/device.h>
55 * Device operations
60 struct venus_comm *vcp = (struct venus_comm *) file->private_data; in coda_psdev_poll()
63 poll_wait(file, &vcp->vc_waitq, wait); in coda_psdev_poll()
64 mutex_lock(&vcp->vc_mutex); in coda_psdev_poll()
65 if (!list_empty(&vcp->vc_pending)) in coda_psdev_poll()
67 mutex_unlock(&vcp->vc_mutex); in coda_psdev_poll()
81 return -ENOTTY; in coda_psdev_ioctl()
94 struct venus_comm *vcp = (struct venus_comm *) file->private_data; in coda_psdev_write()
102 /* make sure there is enough to copy out the (opcode, unique) values */ in coda_psdev_write()
104 return -EINVAL; in coda_psdev_write()
108 return -EFAULT; in coda_psdev_write()
116 hdr.opcode, hdr.unique); in coda_psdev_write()
122 hdr.opcode, hdr.unique); in coda_psdev_write()
147 mutex_lock(&vcp->vc_mutex); in coda_psdev_write()
148 list_for_each(lh, &vcp->vc_processing) { in coda_psdev_write()
150 if (tmp->uc_unique == hdr.unique) { in coda_psdev_write()
152 list_del(&req->uc_chain); in coda_psdev_write()
156 mutex_unlock(&vcp->vc_mutex); in coda_psdev_write()
160 __func__, hdr.opcode, hdr.unique); in coda_psdev_write()
161 retval = -ESRCH; in coda_psdev_write()
166 if (req->uc_outSize < nbytes) { in coda_psdev_write()
168 __func__, req->uc_outSize, (long)nbytes, in coda_psdev_write()
169 hdr.opcode, hdr.unique); in coda_psdev_write()
170 nbytes = req->uc_outSize; /* don't have more space! */ in coda_psdev_write()
172 if (copy_from_user(req->uc_data, buf, nbytes)) { in coda_psdev_write()
173 req->uc_flags |= CODA_REQ_ABORT; in coda_psdev_write()
174 wake_up(&req->uc_sleep); in coda_psdev_write()
175 retval = -EFAULT; in coda_psdev_write()
180 req->uc_outSize = nbytes; in coda_psdev_write()
181 req->uc_flags |= CODA_REQ_WRITE; in coda_psdev_write()
185 if (req->uc_opcode == CODA_OPEN_BY_FD) { in coda_psdev_write()
187 (struct coda_open_by_fd_out *)req->uc_data; in coda_psdev_write()
188 if (!outp->oh.result) { in coda_psdev_write()
189 outp->fh = fget(outp->fd); in coda_psdev_write()
190 if (!outp->fh) in coda_psdev_write()
191 return -EBADF; in coda_psdev_write()
195 wake_up(&req->uc_sleep); in coda_psdev_write()
208 struct venus_comm *vcp = (struct venus_comm *) file->private_data; in coda_psdev_read()
215 mutex_lock(&vcp->vc_mutex); in coda_psdev_read()
217 add_wait_queue(&vcp->vc_waitq, &wait); in coda_psdev_read()
220 while (list_empty(&vcp->vc_pending)) { in coda_psdev_read()
221 if (file->f_flags & O_NONBLOCK) { in coda_psdev_read()
222 retval = -EAGAIN; in coda_psdev_read()
226 retval = -ERESTARTSYS; in coda_psdev_read()
229 mutex_unlock(&vcp->vc_mutex); in coda_psdev_read()
231 mutex_lock(&vcp->vc_mutex); in coda_psdev_read()
235 remove_wait_queue(&vcp->vc_waitq, &wait); in coda_psdev_read()
240 req = list_entry(vcp->vc_pending.next, struct upc_req,uc_chain); in coda_psdev_read()
241 list_del(&req->uc_chain); in coda_psdev_read()
244 count = req->uc_inSize; in coda_psdev_read()
245 if (nbytes < req->uc_inSize) { in coda_psdev_read()
247 __func__, (long)nbytes, req->uc_inSize); in coda_psdev_read()
251 if (copy_to_user(buf, req->uc_data, count)) in coda_psdev_read()
252 retval = -EFAULT; in coda_psdev_read()
255 if (!(req->uc_flags & CODA_REQ_ASYNC)) { in coda_psdev_read()
256 req->uc_flags |= CODA_REQ_READ; in coda_psdev_read()
257 list_add_tail(&(req->uc_chain), &vcp->vc_processing); in coda_psdev_read()
261 kvfree(req->uc_data); in coda_psdev_read()
264 mutex_unlock(&vcp->vc_mutex); in coda_psdev_read()
274 return -EINVAL; in coda_psdev_open()
277 return -EINVAL; in coda_psdev_open()
281 return -ENODEV; in coda_psdev_open()
283 err = -EBUSY; in coda_psdev_open()
285 mutex_lock(&vcp->vc_mutex); in coda_psdev_open()
287 if (!vcp->vc_inuse) { in coda_psdev_open()
288 vcp->vc_inuse++; in coda_psdev_open()
290 INIT_LIST_HEAD(&vcp->vc_pending); in coda_psdev_open()
291 INIT_LIST_HEAD(&vcp->vc_processing); in coda_psdev_open()
292 init_waitqueue_head(&vcp->vc_waitq); in coda_psdev_open()
293 vcp->vc_sb = NULL; in coda_psdev_open()
294 vcp->vc_seq = 0; in coda_psdev_open()
296 file->private_data = vcp; in coda_psdev_open()
300 mutex_unlock(&vcp->vc_mutex); in coda_psdev_open()
307 struct venus_comm *vcp = (struct venus_comm *) file->private_data; in coda_psdev_release()
310 if (!vcp || !vcp->vc_inuse ) { in coda_psdev_release()
312 return -1; in coda_psdev_release()
315 mutex_lock(&vcp->vc_mutex); in coda_psdev_release()
318 list_for_each_entry_safe(req, tmp, &vcp->vc_pending, uc_chain) { in coda_psdev_release()
319 list_del(&req->uc_chain); in coda_psdev_release()
322 if (req->uc_flags & CODA_REQ_ASYNC) { in coda_psdev_release()
323 kvfree(req->uc_data); in coda_psdev_release()
327 req->uc_flags |= CODA_REQ_ABORT; in coda_psdev_release()
328 wake_up(&req->uc_sleep); in coda_psdev_release()
331 list_for_each_entry_safe(req, tmp, &vcp->vc_processing, uc_chain) { in coda_psdev_release()
332 list_del(&req->uc_chain); in coda_psdev_release()
334 req->uc_flags |= CODA_REQ_ABORT; in coda_psdev_release()
335 wake_up(&req->uc_sleep); in coda_psdev_release()
338 file->private_data = NULL; in coda_psdev_release()
339 vcp->vc_inuse--; in coda_psdev_release()
340 mutex_unlock(&vcp->vc_mutex); in coda_psdev_release()
362 return -EIO; in init_coda_psdev()
370 mutex_init(&(&coda_comms[i])->vc_mutex); in init_coda_psdev()