OSDN Git Service

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs
[uclinux-h8/linux.git] / drivers / staging / dgrp / dgrp_dpa_ops.c
1 /*
2  *
3  * Copyright 1999 Digi International (www.digi.com)
4  *     James Puzzo <jamesp at digi dot com>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED; without even the
13  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14  * PURPOSE.  See the GNU General Public License for more details.
15  *
16  */
17
18 /*
19  *
20  *  Filename:
21  *
22  *     dgrp_dpa_ops.c
23  *
24  *  Description:
25  *
26  *     Handle the file operations required for the "dpa" devices.
27  *     Includes those functions required to register the "dpa" devices
28  *     in "/proc".
29  *
30  *  Author:
31  *
32  *     James A. Puzzo
33  *
34  */
35
36 #include <linux/module.h>
37 #include <linux/proc_fs.h>
38 #include <linux/tty.h>
39 #include <linux/poll.h>
40 #include <linux/cred.h>
41 #include <linux/sched.h>
42 #include <linux/ratelimit.h>
43 #include <linux/slab.h>
44 #include <asm/unaligned.h>
45
46 #include "dgrp_common.h"
47
48 /* File operation declarations */
49 static int dgrp_dpa_open(struct inode *, struct file *);
50 static int dgrp_dpa_release(struct inode *, struct file *);
51 static ssize_t dgrp_dpa_read(struct file *, char __user *, size_t, loff_t *);
52 static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd,
53                            unsigned long arg);
54 static unsigned int dgrp_dpa_select(struct file *, struct poll_table_struct *);
55
56 const struct file_operations dgrp_dpa_ops = {
57         .owner   =  THIS_MODULE,
58         .read    =  dgrp_dpa_read,
59         .poll    =  dgrp_dpa_select,
60         .unlocked_ioctl =  dgrp_dpa_ioctl,
61         .open    =  dgrp_dpa_open,
62         .release =  dgrp_dpa_release,
63 };
64
65 struct digi_node {
66         uint    nd_state;               /* Node state: 1 = up, 0 = down. */
67         uint    nd_chan_count;          /* Number of channels found */
68         uint    nd_tx_byte;             /* Tx data count */
69         uint    nd_rx_byte;             /* RX data count */
70         u8      nd_ps_desc[MAX_DESC_LEN]; /* Description from PS */
71 };
72
73 #define DIGI_GETNODE      (('d'<<8) | 249)      /* get board info */
74
75
76 struct digi_chan {
77         uint    ch_port;        /* Port number to get info on */
78         uint    ch_open;        /* 1 if open, 0 if not */
79         uint    ch_txcount;     /* TX data count  */
80         uint    ch_rxcount;     /* RX data count  */
81         uint    ch_s_brate;     /* Realport BRATE */
82         uint    ch_s_estat;     /* Realport ELAST */
83         uint    ch_s_cflag;     /* Realport CFLAG */
84         uint    ch_s_iflag;     /* Realport IFLAG */
85         uint    ch_s_oflag;     /* Realport OFLAG */
86         uint    ch_s_xflag;     /* Realport XFLAG */
87         uint    ch_s_mstat;     /* Realport MLAST */
88 };
89
90 #define DIGI_GETCHAN      (('d'<<8) | 248)      /* get channel info */
91
92
93 struct digi_vpd {
94         int vpd_len;
95         char vpd_data[VPDSIZE];
96 };
97
98 #define DIGI_GETVPD       (('d'<<8) | 246)      /* get VPD info */
99
100
101 struct digi_debug {
102         int onoff;
103         int port;
104 };
105
106 #define DIGI_SETDEBUG      (('d'<<8) | 247)     /* set debug info */
107
108
109 /*
110  * dgrp_dpa_open -- open the DPA device for a particular PortServer
111  */
112 static int dgrp_dpa_open(struct inode *inode, struct file *file)
113 {
114         struct nd_struct *nd;
115         int rtn = 0;
116
117         rtn = try_module_get(THIS_MODULE);
118         if (!rtn)
119                 return -ENXIO;
120
121         rtn = 0;
122
123         if (!capable(CAP_SYS_ADMIN)) {
124                 rtn = -EPERM;
125                 goto done;
126         }
127
128         /*
129          *  Make sure that the "private_data" field hasn't already been used.
130          */
131         if (file->private_data) {
132                 rtn = -EINVAL;
133                 goto done;
134         }
135
136         /*
137          *  Get the node pointer, and fail if it doesn't exist.
138          */
139         nd = PDE_DATA(inode);
140         if (!nd) {
141                 rtn = -ENXIO;
142                 goto done;
143         }
144
145         file->private_data = (void *) nd;
146
147         /*
148          * Allocate the DPA buffer.
149          */
150
151         if (nd->nd_dpa_buf) {
152                 rtn = -EBUSY;
153         } else {
154                 nd->nd_dpa_buf = kmalloc(DPA_MAX, GFP_KERNEL);
155
156                 if (!nd->nd_dpa_buf) {
157                         rtn = -ENOMEM;
158                 } else {
159                         nd->nd_dpa_out = 0;
160                         nd->nd_dpa_in = 0;
161                         nd->nd_dpa_lbolt = jiffies;
162                 }
163         }
164
165 done:
166
167         if (rtn)
168                 module_put(THIS_MODULE);
169         return rtn;
170 }
171
172 /*
173  * dgrp_dpa_release -- close the DPA device for a particular PortServer
174  */
175 static int dgrp_dpa_release(struct inode *inode, struct file *file)
176 {
177         struct nd_struct *nd;
178         u8 *buf;
179         unsigned long lock_flags;
180
181         /*
182          *  Get the node pointer, and quit if it doesn't exist.
183          */
184         nd = (struct nd_struct *)(file->private_data);
185         if (!nd)
186                 goto done;
187
188         /*
189          *  Free the dpa buffer.
190          */
191
192         spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
193
194         buf = nd->nd_dpa_buf;
195
196         nd->nd_dpa_buf = NULL;
197         nd->nd_dpa_out = nd->nd_dpa_in;
198
199         /*
200          *  Wakeup any thread waiting for buffer space.
201          */
202
203         if (nd->nd_dpa_flag & DPA_WAIT_SPACE) {
204                 nd->nd_dpa_flag &= ~DPA_WAIT_SPACE;
205                 wake_up_interruptible(&nd->nd_dpa_wqueue);
206         }
207
208         spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
209
210         kfree(buf);
211
212 done:
213         module_put(THIS_MODULE);
214         file->private_data = NULL;
215         return 0;
216 }
217
218 /*
219  * dgrp_dpa_read
220  *
221  * Copy data from the monitoring buffer to the user, freeing space
222  * in the monitoring buffer for more messages
223  */
224 static ssize_t dgrp_dpa_read(struct file *file, char __user *buf, size_t count,
225                              loff_t *ppos)
226 {
227         struct nd_struct *nd;
228         int n;
229         int r;
230         int offset = 0;
231         int res = 0;
232         ssize_t rtn;
233         unsigned long lock_flags;
234
235         /*
236          *  Get the node pointer, and quit if it doesn't exist.
237          */
238         nd = (struct nd_struct *)(file->private_data);
239         if (!nd)
240                 return -ENXIO;
241
242         /*
243          *  Wait for some data to appear in the buffer.
244          */
245
246         spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
247
248         for (;;) {
249                 n = (nd->nd_dpa_in - nd->nd_dpa_out) & DPA_MASK;
250
251                 if (n != 0)
252                         break;
253
254                 nd->nd_dpa_flag |= DPA_WAIT_DATA;
255
256                 spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
257
258                 /*
259                  * Go to sleep waiting until the condition becomes true.
260                  */
261                 rtn = wait_event_interruptible(nd->nd_dpa_wqueue,
262                         ((nd->nd_dpa_flag & DPA_WAIT_DATA) == 0));
263
264                 if (rtn)
265                         return rtn;
266
267                 spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
268         }
269
270         /*
271          *  Read whatever is there.
272          */
273
274         if (n > count)
275                 n = count;
276
277         res = n;
278
279         r = DPA_MAX - nd->nd_dpa_out;
280
281         if (r <= n) {
282
283                 spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
284                 rtn = copy_to_user((void __user *)buf,
285                                    nd->nd_dpa_buf + nd->nd_dpa_out, r);
286                 spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
287
288                 if (rtn) {
289                         rtn = -EFAULT;
290                         goto done;
291                 }
292
293                 nd->nd_dpa_out = 0;
294                 n -= r;
295                 offset = r;
296         }
297
298         spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
299         rtn = copy_to_user((void __user *)buf + offset,
300                            nd->nd_dpa_buf + nd->nd_dpa_out, n);
301         spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
302
303         if (rtn) {
304                 rtn = -EFAULT;
305                 goto done;
306         }
307
308         nd->nd_dpa_out += n;
309
310         *ppos += res;
311
312         rtn = res;
313
314         /*
315          *  Wakeup any thread waiting for buffer space.
316          */
317
318         n = (nd->nd_dpa_in - nd->nd_dpa_out) & DPA_MASK;
319
320         if (nd->nd_dpa_flag & DPA_WAIT_SPACE &&
321             (DPA_MAX - n) > DPA_HIGH_WATER) {
322                 nd->nd_dpa_flag &= ~DPA_WAIT_SPACE;
323                 wake_up_interruptible(&nd->nd_dpa_wqueue);
324         }
325
326  done:
327         spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
328         return rtn;
329 }
330
331 static unsigned int dgrp_dpa_select(struct file *file,
332                                     struct poll_table_struct *table)
333 {
334         unsigned int retval = 0;
335         struct nd_struct *nd = file->private_data;
336
337         if (nd->nd_dpa_out != nd->nd_dpa_in)
338                 retval |= POLLIN | POLLRDNORM; /* Conditionally readable */
339
340         retval |= POLLOUT | POLLWRNORM;        /* Always writeable */
341
342         return retval;
343 }
344
345 static long dgrp_dpa_ioctl(struct file *file, unsigned int cmd,
346                            unsigned long arg)
347 {
348
349         struct nd_struct  *nd;
350         struct digi_chan getchan;
351         struct digi_node getnode;
352         struct ch_struct *ch;
353         struct digi_debug setdebug;
354         struct digi_vpd vpd;
355         unsigned int port;
356         void __user *uarg = (void __user *) arg;
357
358         nd = file->private_data;
359
360         switch (cmd) {
361         case DIGI_GETCHAN:
362                 if (copy_from_user(&getchan, uarg, sizeof(struct digi_chan)))
363                         return -EFAULT;
364
365                 port = getchan.ch_port;
366
367                 if (port > nd->nd_chan_count)
368                         return -EINVAL;
369
370                 ch = nd->nd_chan + port;
371
372                 getchan.ch_open = (ch->ch_open_count > 0) ? 1 : 0;
373                 getchan.ch_txcount = ch->ch_txcount;
374                 getchan.ch_rxcount = ch->ch_rxcount;
375                 getchan.ch_s_brate = ch->ch_s_brate;
376                 getchan.ch_s_estat = ch->ch_s_elast;
377                 getchan.ch_s_cflag = ch->ch_s_cflag;
378                 getchan.ch_s_iflag = ch->ch_s_iflag;
379                 getchan.ch_s_oflag = ch->ch_s_oflag;
380                 getchan.ch_s_xflag = ch->ch_s_xflag;
381                 getchan.ch_s_mstat = ch->ch_s_mlast;
382
383                 if (copy_to_user(uarg, &getchan, sizeof(struct digi_chan)))
384                         return -EFAULT;
385                 break;
386
387
388         case DIGI_GETNODE:
389                 getnode.nd_state = (nd->nd_state & NS_READY) ? 1 : 0;
390                 getnode.nd_chan_count = nd->nd_chan_count;
391                 getnode.nd_tx_byte = nd->nd_tx_byte;
392                 getnode.nd_rx_byte = nd->nd_rx_byte;
393
394                 memset(&getnode.nd_ps_desc, 0, MAX_DESC_LEN);
395                 strncpy(getnode.nd_ps_desc, nd->nd_ps_desc, MAX_DESC_LEN);
396
397                 if (copy_to_user(uarg, &getnode, sizeof(struct digi_node)))
398                         return -EFAULT;
399                 break;
400
401
402         case DIGI_SETDEBUG:
403                 if (copy_from_user(&setdebug, uarg, sizeof(struct digi_debug)))
404                         return -EFAULT;
405
406                 nd->nd_dpa_debug = setdebug.onoff;
407                 nd->nd_dpa_port = setdebug.port;
408                 break;
409
410
411         case DIGI_GETVPD:
412                 memset(&vpd, 0, sizeof(vpd));
413                 if (nd->nd_vpd_len > 0) {
414                         vpd.vpd_len = nd->nd_vpd_len;
415                         memcpy(&vpd.vpd_data, &nd->nd_vpd, nd->nd_vpd_len);
416                 } else {
417                         vpd.vpd_len = 0;
418                 }
419
420                 if (copy_to_user(uarg, &vpd, sizeof(struct digi_vpd)))
421                         return -EFAULT;
422                 break;
423         }
424
425         return 0;
426 }
427
428 /**
429  * dgrp_dpa() -- send data to the device monitor queue
430  * @nd: pointer to a node structure
431  * @buf: buffer of data to copy to the monitoring buffer
432  * @len: number of bytes to transfer to the buffer
433  *
434  * Called by the net device routines to send data to the device
435  * monitor queue.  If the device monitor buffer is too full to
436  * accept the data, it waits until the buffer is ready.
437  */
438 static void dgrp_dpa(struct nd_struct *nd, u8 *buf, int nbuf)
439 {
440         int n;
441         int r;
442         unsigned long lock_flags;
443
444         /*
445          *  Grab DPA lock.
446          */
447         spin_lock_irqsave(&nd->nd_dpa_lock, lock_flags);
448
449         /*
450          *  Loop while data remains.
451          */
452         while (nbuf > 0 && nd->nd_dpa_buf != NULL) {
453
454                 n = (nd->nd_dpa_out - nd->nd_dpa_in - 1) & DPA_MASK;
455
456                 /*
457                  * Enforce flow control on the DPA device.
458                  */
459                 if (n < (DPA_MAX - DPA_HIGH_WATER))
460                         nd->nd_dpa_flag |= DPA_WAIT_SPACE;
461
462                 /*
463                  * This should never happen, as the flow control above
464                  * should have stopped things before they got to this point.
465                  */
466                 if (n == 0) {
467                         spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
468                         return;
469                 }
470
471                 /*
472                  * Copy as much data as will fit.
473                  */
474
475                 if (n > nbuf)
476                         n = nbuf;
477
478                 r = DPA_MAX - nd->nd_dpa_in;
479
480                 if (r <= n) {
481                         memcpy(nd->nd_dpa_buf + nd->nd_dpa_in, buf, r);
482
483                         n -= r;
484
485                         nd->nd_dpa_in = 0;
486
487                         buf += r;
488                         nbuf -= r;
489                 }
490
491                 memcpy(nd->nd_dpa_buf + nd->nd_dpa_in, buf, n);
492
493                 nd->nd_dpa_in += n;
494
495                 buf += n;
496                 nbuf -= n;
497
498                 if (nd->nd_dpa_in >= DPA_MAX)
499                         pr_info_ratelimited("%s - nd->nd_dpa_in (%i) >= DPA_MAX\n",
500                                             __func__, nd->nd_dpa_in);
501
502                 /*
503                  *  Wakeup any thread waiting for data
504                  */
505                 if (nd->nd_dpa_flag & DPA_WAIT_DATA) {
506                         nd->nd_dpa_flag &= ~DPA_WAIT_DATA;
507                         wake_up_interruptible(&nd->nd_dpa_wqueue);
508                 }
509         }
510
511         /*
512          *  Release the DPA lock.
513          */
514         spin_unlock_irqrestore(&nd->nd_dpa_lock, lock_flags);
515 }
516
517 /**
518  * dgrp_monitor_data() -- builds a DPA data packet
519  * @nd: pointer to a node structure
520  * @type: type of message to be logged in the DPA buffer
521  * @buf: buffer of data to be logged in the DPA buffer
522  * @size -- number of bytes in the "buf" buffer
523  */
524 void dgrp_dpa_data(struct nd_struct *nd, int type, u8 *buf, int size)
525 {
526         u8 header[5];
527
528         header[0] = type;
529
530         put_unaligned_be32(size, header + 1);
531
532         dgrp_dpa(nd, header, sizeof(header));
533         dgrp_dpa(nd, buf, size);
534 }