1 /*
2  * Copyright (c) 2006-2023, RT-Thread Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  *
6  * Change Logs:
7  * Date           Author       Notes
8  * 2023-11-13     Shell        Add compatible layer for FreeBSD
9  */
10 
11 #ifndef __LWP_TTY_BSD_PORTING_H__
12 #define __LWP_TTY_BSD_PORTING_H__
13 
14 #include <rtthread.h>
15 #include <lwp_internal.h>
16 #define _KERNEL
17 
18 #ifndef __unused
19 #define __unused __attribute__((__unused__))
20 #endif
21 
22 /* functionability of bsd tty layer */
23 #if 0
24 #define USING_BSD_HOOK
25 #endif
26 
27 /* Only for devfs d_close() flags. */
28 #define FLASTCLOSE O_DIRECTORY
29 #define FREVOKE    0x00200000
30 
31 /*
32  * Output flags - software output processing
33  */
34 #if !((OPOST | OLCUC | ONLCR) & 0x8)
35 #define ONOEOT 0x0008 /* discard EOT's (^D) on output) */
36 #endif
37 
38 /*
39  * Kernel encoding of open mode; separate read and write bits that are
40  * independently testable: 1 greater than the above.
41  *
42  * XXX
43  * FREAD and FWRITE are excluded from the #ifdef _KERNEL so that TIOCFLUSH,
44  * which was documented to use FREAD/FWRITE, continues to work.
45  */
46 #define FREAD  0x0001
47 #define FWRITE 0x0002
48 
49 /*
50  * Flags to memory allocation functions.
51  */
52 #define M_NOWAIT      0x0001 /* do not block */
53 #define M_WAITOK      0x0002 /* ok to block */
54 #define M_NORECLAIM   0x0080 /* do not reclaim after failure */
55 #define M_ZERO        0x0100 /* bzero the allocation */
56 #define M_NOVM        0x0200 /* don't ask VM for pages */
57 #define M_USE_RESERVE 0x0400 /* can alloc out of reserve memory */
58 #define M_NODUMP      0x0800 /* don't dump pages in this allocation */
59 #define M_FIRSTFIT    0x1000 /* only for vmem, fast fit */
60 #define M_BESTFIT     0x2000 /* only for vmem, low fragmentation */
61 #define M_EXEC        0x4000 /* allocate executable space */
62 #define M_NEXTFIT     0x8000 /* only for vmem, follow cursor */
63 
64 #define M_VERSION 2020110501
65 
66 /*
67  * The INVARIANTS-enabled mtx_assert() functionality.
68  *
69  * The constants need to be defined for INVARIANT_SUPPORT infrastructure
70  * support as _mtx_assert() itself uses them and the latter implies that
71  * _mtx_assert() must build.
72  */
73 #define MA_OWNED       (1)
74 #define MA_NOTOWNED    (2)
75 #define MA_RECURSED    (4)
76 #define MA_NOTRECURSED (8)
77 
78 /*
79  * Indentification of modem control signals.  These definitions match
80  * the TIOCMGET definitions in <sys/ttycom.h> shifted a bit down, and
81  * that identity is enforced with CTASSERT at the bottom of kern/tty.c
82  * Both the modem bits and delta bits must fit in 16 bit.
83  */
84 #define SER_DTR 0x0001 /* data terminal ready */
85 #define SER_RTS 0x0002 /* request to send */
86 #define SER_STX 0x0004 /* secondary transmit */
87 #define SER_SRX 0x0008 /* secondary receive */
88 #define SER_CTS 0x0010 /* clear to send */
89 #define SER_DCD 0x0020 /* data carrier detect */
90 #define SER_RI  0x0040 /* ring indicate */
91 #define SER_DSR 0x0080 /* data set ready */
92 
93 #define SER_MASK_STATE 0x00ff
94 
95 /*
96  * Flags for ioflag. (high 16 bits used to ask for read-ahead and
97  * help with write clustering)
98  * NB: IO_NDELAY and IO_DIRECT are linked to fcntl.h
99  */
100 #if 0
101 #define IO_UNIT   0x0001 /* do I/O as atomic unit */
102 #define IO_APPEND 0x0002 /* append write to end */
103 #endif                   /* not porting */
104 
105 #define IO_NDELAY 0x0004 /* FNDELAY flag set in file table */
106 #if 0
107 #define IO_NODELOCKED  0x0008 /* underlying node already locked */
108 #define IO_ASYNC       0x0010 /* bawrite rather then bdwrite */
109 #define IO_VMIO        0x0020 /* data already in VMIO space */
110 #define IO_INVAL       0x0040 /* invalidate after I/O */
111 #define IO_SYNC        0x0080 /* do I/O synchronously */
112 #define IO_DIRECT      0x0100 /* attempt to bypass buffer cache */
113 #define IO_NOREUSE     0x0200 /* VMIO data won't be reused */
114 #define IO_EXT         0x0400 /* operate on external attributes */
115 #define IO_NORMAL      0x0800 /* operate on regular data */
116 #define IO_NOMACCHECK  0x1000 /* MAC checks unnecessary */
117 #define IO_BUFLOCKED   0x2000 /* ffs flag; indir buf is locked */
118 #define IO_RANGELOCKED 0x4000 /* range locked */
119 #define IO_DATASYNC    0x8000 /* do only data I/O synchronously */
120 
121 #define IO_SEQMAX   0x7F /* seq heuristic max value */
122 #define IO_SEQSHIFT 16   /* seq heuristic in upper 16 bits */
123 #endif                   /* not porting */
124 
125 /** Used to distinguish between normal, callout, lock and init devices.
126  * Note: this is not used in smart system.
127  */
128 #define TTYUNIT_INIT    0x1
129 #define TTYUNIT_LOCK    0x2
130 #define TTYUNIT_CALLOUT 0x4
131 
132 /*
133  * TTY privileges.
134  */
135 #define PRIV_TTY_CONSOLE   250 /* Set console to tty. */
136 #define PRIV_TTY_DRAINWAIT 251 /* Set tty drain wait time. */
137 #define PRIV_TTY_DTRWAIT   252 /* Set DTR wait on tty. */
138 #define PRIV_TTY_EXCLUSIVE 253 /* Override tty exclusive flag. */
139 #define _PRIV_TTY_PRISON   254 /* Removed. */
140 #define PRIV_TTY_STI       255 /* Simulate input on another tty. */
141 #define PRIV_TTY_SETA      256 /* Set tty termios structure. */
142 
143 #define MPASS(ex) RT_ASSERT(ex)
144 
145 #if !defined(MIN)
146 #define MIN(a, b) ((a) < (b) ? (a) : (b))
147 #endif
148 
149 #if !defined(MAX)
150 #define MAX(a, b) ((a) > (b) ? (a) : (b))
151 #endif
152 
153 #define curthread rt_thread_self()
154 
155 #ifdef USING_BSD_HOOK
156 #define ttyhook_hashook(tp, hook) \
157     ((tp)->t_hook != NULL && (tp)->t_hook->th_##hook != NULL)
158 #else
159 #define ttyhook_hashook(tp, hook) (RT_FALSE)
160 #endif
161 
162 /* condvar API */
163 #include <rtdevice.h>
164 
165 #define cv_init(cvp, name) rt_condvar_init(cvp, name)
166 #define cv_destroy(cvp)    rt_condvar_detach(cvp)
167 #define cv_wait(cvp, mp) \
168     rt_condvar_timedwait(cvp, mp, RT_KILLABLE, RT_WAITING_FOREVER)
169 #define cv_wait_sig(cvp, mp) \
170     rt_condvar_timedwait(cvp, mp, RT_INTERRUPTIBLE, RT_WAITING_FOREVER)
171 #define cv_signal(cvp)           rt_condvar_signal(cvp)
172 #define cv_broadcast(cvp)        rt_condvar_broadcast(cvp)
173 #define cv_timedwait(cvp, mp, t) rt_condvar_timedwait(cvp, mp, RT_KILLABLE, t)
174 #define cv_timedwait_sig(cvp, mp, t) \
175     rt_condvar_timedwait(cvp, mp, RT_INTERRUPTIBLE, t)
176 
177 struct lwp_tty;
178 struct uio;
179 
180 /* TODO: just a place holder since devfs is not capable of doing this currently
181  */
182 struct file
183 {
184 };
185 
186 typedef rt_base_t sbintime_t;
187 typedef rt_ubase_t vm_offset_t;
188 typedef rt_base_t vm_ooffset_t;
189 typedef rt_ubase_t vm_paddr_t;
190 typedef rt_ubase_t vm_pindex_t;
191 typedef rt_ubase_t vm_size_t;
192 typedef char *rt_caddr_t;
193 
194 /*
195  * The exact set of memory attributes is machine dependent.  However,
196  * every machine is required to define VM_MEMATTR_DEFAULT and
197  * VM_MEMATTR_UNCACHEABLE.
198  */
199 typedef char vm_memattr_t; /* memory attribute codes */
200 
201 typedef int d_open_t(struct lwp_tty *tp, int oflags, int devtype,
202                      struct rt_thread *td);
203 typedef int d_fdopen_t(struct lwp_tty *tp, int oflags, struct rt_thread *td,
204                        struct file *fp);
205 typedef int d_close_t(struct lwp_tty *tp, int fflag, int devtype,
206                       struct rt_thread *td);
207 
208 #ifdef USING_BSD_DEVICE_STRATEGY
209 typedef void d_strategy_t(struct bio *bp);
210 #endif
211 
212 typedef int d_ioctl_t(struct lwp_tty *tp, rt_ubase_t cmd, rt_caddr_t data,
213                       int fflag, struct rt_thread *td);
214 
215 typedef int d_read_t(struct lwp_tty *tp, struct uio *uio, int ioflag);
216 typedef int d_write_t(struct lwp_tty *tp, struct uio *uio, int ioflag);
217 typedef int d_poll_t(struct lwp_tty *tp, rt_pollreq_t *req,
218                      struct rt_thread *td);
219 
220 #ifdef USING_BSD_KNOTE
221 typedef int d_kqfilter_t(struct lwp_tty *tp, struct knote *kn);
222 #endif /* USING_BSD_KNOTE */
223 
224 typedef int d_mmap_t(struct lwp_tty *tp, vm_ooffset_t offset, vm_paddr_t *paddr,
225                      int nprot, vm_memattr_t *memattr);
226 
227 #ifdef USING_BSD_MMAP_SINGLE
228 typedef int d_mmap_single_t(struct cdev *cdev, vm_ooffset_t *offset,
229                             vm_size_t size, struct vm_object **object,
230                             int nprot);
231 #endif /* USING_BSD_MMAP_SINGLE */
232 
233 typedef void d_purge_t(struct lwp_tty *tp);
234 
235 /*
236  * Character device switch table
237  */
238 struct cdevsw
239 {
240 #ifdef USING_BSD_RAW_CDEVSW
241     int d_version;
242     u_int d_flags;
243     const char *d_name;
244 #endif /* USING_BSD_RAW_CDEVSW */
245 
246     d_open_t *d_open;
247     d_fdopen_t *d_fdopen;
248     d_close_t *d_close;
249     d_read_t *d_read;
250     d_write_t *d_write;
251     d_ioctl_t *d_ioctl;
252     d_poll_t *d_poll;
253     d_mmap_t *d_mmap;
254 #ifdef USING_BSD_DEVICE_STRATEGY
255     d_strategy_t *d_strategy;
256 #endif /* USING_BSD_DEVICE_STRATEGY */
257 
258 #ifdef USING_BSD_RAW_CDEVSW
259     void *d_spare0;
260     d_kqfilter_t *d_kqfilter;
261     d_purge_t *d_purge;
262     d_mmap_single_t *d_mmap_single;
263 
264     int32_t d_spare1[3];
265     void *d_spare2[3];
266 
267     /* These fields should not be messed with by drivers */
268     LIST_HEAD(, cdev) d_devs;
269     int d_spare3;
270     union
271     {
272         struct cdevsw *gianttrick;
273         SLIST_ENTRY(cdevsw) postfree_list;
274     } __d_giant;
275 #endif
276 };
277 
278 struct iovec
279 {
280     void *iov_base; /* Base address. */
281     size_t iov_len; /* Length. */
282 };
283 
284 enum uio_rw
285 {
286     UIO_READ,
287     UIO_WRITE
288 };
289 
290 struct uio
291 {
292     struct iovec *uio_iov; /* scatter/gather list */
293     int uio_iovcnt;        /* length of scatter/gather list */
294     off_t uio_offset;      /* offset in target object */
295     ssize_t uio_resid;     /* remaining bytes to process */
296 #ifdef USING_BSD_UIO
297     enum uio_seg uio_segflg; /* address space */
298 #endif
299     enum uio_rw uio_rw; /* operation */
300 #ifdef USING_BSD_UIO
301     struct rt_thread *uio_td; /* owner */
302 
303 #endif /* USING_BSD_UIO */
304 };
305 
306 #include <lwp_user_mm.h>
uiomove(void * operand,int n,struct uio * uio)307 rt_inline int uiomove(void *operand, int n, struct uio *uio)
308 {
309     switch (uio->uio_rw)
310     {
311         case UIO_READ:
312             memcpy(uio->uio_iov->iov_base, operand, n);
313             break;
314         case UIO_WRITE:
315             memcpy(operand, uio->uio_iov->iov_base, n);
316             break;
317         default:
318             return -1;
319     }
320 
321     uio->uio_iov->iov_base += n;
322     uio->uio_iov->iov_len--;
323     uio->uio_offset += n;
324     uio->uio_resid -= n;
325     return 0;
326 }
327 
328 /* privileges checking: 0 if okay */
priv_check(struct rt_thread * td,int priv)329 rt_inline int priv_check(struct rt_thread *td, int priv)
330 {
331     return 0;
332 }
333 
334 /* Disable console redirection to a tty. */
constty_clear(struct lwp_tty * tp)335 rt_inline int constty_clear(struct lwp_tty *tp)
336 {
337     // rt_kprintf("\nTODO: %s unimplemented!\n", __func__);
338     return 0;
339 }
340 
constty_set(struct lwp_tty * tp)341 rt_inline int constty_set(struct lwp_tty *tp)
342 {
343     // rt_kprintf("\nTODO: %s unimplemented!\n", __func__);
344     return 0;
345 }
346 
347 /**
348  * UMA (Universal Memory Allocator)
349  */
350 #define UMA_ALIGN_PTR (sizeof(void *) - 1) /* Alignment fit for ptr */
351 
352 typedef int (*uma_ctor)(void *mem, int size, void *arg, int flags);
353 typedef void (*uma_dtor)(void *mem, int size, void *arg);
354 typedef int (*uma_init)(void *mem, int size, int flags);
355 typedef void (*uma_fini)(void *mem, int size);
356 
357 struct uma_zone
358 {
359     char *name;
360     int align;
361     int size;
362 };
363 
364 /* Opaque type used as a handle to the zone */
365 typedef struct uma_zone *uma_zone_t;
366 
uma_zcreate(char * name,int size,uma_ctor ctor,uma_dtor dtor,uma_init zinit,uma_fini zfini,int align,uint16_t flags)367 rt_inline uma_zone_t uma_zcreate(char *name, int size, uma_ctor ctor,
368                                  uma_dtor dtor, uma_init zinit, uma_fini zfini,
369                                  int align, uint16_t flags)
370 {
371     uma_zone_t zone = rt_malloc(sizeof(struct uma_zone));
372     if (zone)
373     {
374         RT_ASSERT(ctor == RT_NULL);
375         RT_ASSERT(dtor == RT_NULL);
376         RT_ASSERT(zinit == RT_NULL);
377         RT_ASSERT(zfini == RT_NULL);
378 
379         zone->size = size;
380         zone->name = name;
381         zone->align = align;
382     }
383     return zone;
384 }
385 
uma_zalloc(uma_zone_t zone,int flags)386 rt_inline void *uma_zalloc(uma_zone_t zone, int flags)
387 {
388     void *buf = rt_malloc_align(zone->size, zone->align + 1);
389     if (buf)
390         rt_memset(buf, 0, sizeof(zone->size));
391     return buf;
392 }
393 
uma_zfree(uma_zone_t zone,void * item)394 rt_inline void uma_zfree(uma_zone_t zone, void *item)
395 {
396     rt_free_align(item);
397 }
398 
399 /**
400  * bsd type of speed to linux type.
401  * Note: with switch blocks, compiler can generate the optimized version for us
402  */
403 #include <termios.h>
bsd_speed_to_integer(speed_t speed)404 rt_inline long bsd_speed_to_integer(speed_t speed)
405 {
406     long speed_value;
407     switch (speed)
408     {
409         case B0:
410             speed_value = 0;
411             break;
412         case B50:
413             speed_value = 50;
414             break;
415         case B75:
416             speed_value = 75;
417             break;
418         case B110:
419             speed_value = 110;
420             break;
421         case B134:
422             speed_value = 134;
423             break;
424         case B150:
425             speed_value = 150;
426             break;
427         case B200:
428             speed_value = 200;
429             break;
430         case B300:
431             speed_value = 300;
432             break;
433         case B600:
434             speed_value = 600;
435             break;
436         case B1200:
437             speed_value = 1200;
438             break;
439         case B1800:
440             speed_value = 1800;
441             break;
442         case B2400:
443             speed_value = 2400;
444             break;
445         case B4800:
446             speed_value = 4800;
447             break;
448         case B9600:
449             speed_value = 9600;
450             break;
451         case B19200:
452             speed_value = 19200;
453             break;
454         case B38400:
455             speed_value = 38400;
456             break;
457         case B57600:
458             speed_value = 57600;
459             break;
460         case B115200:
461             speed_value = 115200;
462             break;
463         case B230400:
464             speed_value = 230400;
465             break;
466         case B460800:
467             speed_value = 460800;
468             break;
469         case B500000:
470             speed_value = 500000;
471             break;
472         case B576000:
473             speed_value = 576000;
474             break;
475         case B921600:
476             speed_value = 921600;
477             break;
478         case B1000000:
479             speed_value = 1000000;
480             break;
481         case B1152000:
482             speed_value = 1152000;
483             break;
484         case B1500000:
485             speed_value = 1500000;
486             break;
487         case B2000000:
488             speed_value = 2000000;
489             break;
490         case B2500000:
491             speed_value = 2500000;
492             break;
493         case B3000000:
494             speed_value = 3000000;
495             break;
496         case B3500000:
497             speed_value = 3500000;
498             break;
499         case B4000000:
500             speed_value = 4000000;
501             break;
502         default:
503             speed_value = -1; // invalid speed
504             break;
505     }
506     return speed_value;
507 }
508 
509 /* time.h */
510 
511 /* Operations on timevals. */
512 
513 #define timevalclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0)
514 #define timevalisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec)
515 #define timevalcmp(tvp, uvp, cmp)                                          \
516     (((tvp)->tv_sec == (uvp)->tv_sec) ? ((tvp)->tv_usec cmp(uvp)->tv_usec) \
517                                       : ((tvp)->tv_sec cmp(uvp)->tv_sec))
518 
getmicrotime(struct timeval * now)519 rt_inline void getmicrotime(struct timeval *now)
520 {
521     gettimeofday(now, RT_NULL);
522 }
523 
timevalfix(struct timeval * tv)524 rt_inline void timevalfix(struct timeval *tv)
525 {
526     if (tv->tv_usec < 0)
527     {
528         tv->tv_sec--;
529         tv->tv_usec += 1000000;
530     }
531     if (tv->tv_usec >= 1000000)
532     {
533         tv->tv_sec++;
534         tv->tv_usec -= 1000000;
535     }
536 }
537 
timevaladd(struct timeval * op1,const struct timeval * op2)538 rt_inline void timevaladd(struct timeval *op1, const struct timeval *op2)
539 {
540     op1->tv_sec += op2->tv_sec;
541     op1->tv_usec += op2->tv_usec;
542     timevalfix(op1);
543 }
544 
timevalsub(struct timeval * op1,const struct timeval * op2)545 rt_inline void timevalsub(struct timeval *op1, const struct timeval *op2)
546 {
547     op1->tv_sec -= op2->tv_sec;
548     op1->tv_usec -= op2->tv_usec;
549     timevalfix(op1);
550 }
551 
tvtohz(struct timeval * tv)552 rt_inline rt_tick_t tvtohz(struct timeval *tv)
553 {
554     rt_tick_t rc;
555     rc = tv->tv_sec * RT_TICK_PER_SECOND;
556     rc += tv->tv_usec * RT_TICK_PER_SECOND / MICROSECOND_PER_SECOND;
557     return rc;
558 }
559 
560 /* ioctl */
561 #define _BSD_TIOCTL(val) ((val) << 16)
562 enum bsd_ioctl_cmd
563 {
564     BSD_TIOCDRAIN = 1,
565     BSD_TIOCFLUSH,
566     BSD_TIOCSTART,
567     BSD_TIOCSTOP,
568     BSD_TIOCSTAT,
569     BSD_TIOCGDRAINWAIT,
570     BSD_TIOCSDRAINWAIT,
571     BSD_TIOCSDTR,
572     BSD_TIOCCDTR,
573 };
574 
575 #ifndef TIOCGETA /* get termios struct */
576 #define TIOCGETA TCGETS
577 #endif
578 #ifndef TIOCSETA /* set termios struct */
579 #define TIOCSETA TCSETS
580 #endif
581 #ifndef TIOCSETAW /* drain output, set */
582 #define TIOCSETAW TCSETSW
583 #endif
584 #ifndef TIOCSETAF /* drn out, fls in, set */
585 #define TIOCSETAF TCSETSF
586 #endif
587 #ifndef TIOCDRAIN /* wait till output drained */
588 #define TIOCDRAIN _BSD_TIOCTL(BSD_TIOCDRAIN)
589 #endif
590 #ifndef TIOCFLUSH /* flush buffers */
591 #define TIOCFLUSH _BSD_TIOCTL(BSD_TIOCFLUSH)
592 #endif
593 #ifndef TIOCSTART /* start output, like ^Q */
594 #define TIOCSTART _BSD_TIOCTL(BSD_TIOCSTART)
595 #endif
596 #ifndef TIOCSTOP /* stop output, like ^S */
597 #define TIOCSTOP _BSD_TIOCTL(BSD_TIOCSTOP)
598 #endif
599 #ifndef TIOCSTAT /* simulate ^T status message */
600 #define TIOCSTAT _BSD_TIOCTL(BSD_TIOCSTAT)
601 #endif
602 #ifndef TIOCGDRAINWAIT /* get ttywait timeout */
603 #define TIOCGDRAINWAIT _BSD_TIOCTL(BSD_TIOCGDRAINWAIT)
604 #endif
605 #ifndef TIOCSDRAINWAIT /* set ttywait timeout */
606 #define TIOCSDRAINWAIT _BSD_TIOCTL(BSD_TIOCSDRAINWAIT)
607 #endif
608 #ifndef TIOCSDTR /* set data terminal ready */
609 #define TIOCSDTR _BSD_TIOCTL(BSD_TIOCSDTR)
610 #endif
611 #ifndef TIOCCDTR /* clear data terminal ready */
612 #define TIOCCDTR _BSD_TIOCTL(BSD_TIOCCDTR)
613 #endif
614 
615 #define ENOIOCTL ENOSYS
616 #define NO_PID   -1
617 
618 /* line discipline */
619 #define TTYDISC      0 /* termios tty line discipline */
620 #define SLIPDISC     4 /* serial IP discipline */
621 #define PPPDISC      5 /* PPP discipline */
622 #define NETGRAPHDISC 6 /* Netgraph tty node discipline */
623 #define H4DISC       7 /* Netgraph Bluetooth H4 discipline */
624 
625 /*
626  * Control flags - hardware control of terminal
627  */
628 #if __BSD_VISIBLE
629 #define CIGNORE    0x00000001 /* ignore control flags */
630 #define CCTS_OFLOW 0x00010000 /* CTS flow control of output */
631 #define CRTSCTS    (CCTS_OFLOW | CRTS_IFLOW)
632 #define CRTS_IFLOW 0x00020000 /* RTS flow control of input */
633 #define CDTR_IFLOW 0x00040000 /* DTR flow control of input */
634 #define CDSR_OFLOW 0x00080000 /* DSR flow control of output */
635 #define CCAR_OFLOW 0x00100000 /* DCD flow control of output */
636 #define CNO_RTSDTR 0x00200000 /* Do not assert RTS or DTR automatically */
637 #else
638 #define CIGNORE    0 /* ignore control flags */
639 #define CCTS_OFLOW 0 /* CTS flow control of output */
640 #define CRTS_IFLOW 0 /* RTS flow control of input */
641 #define CDTR_IFLOW 0 /* DTR flow control of input */
642 #define CDSR_OFLOW 0 /* DSR flow control of output */
643 #define CCAR_OFLOW 0 /* DCD flow control of output */
644 #define CNO_RTSDTR 0 /* Do not assert RTS or DTR automatically */
645 #endif
646 
647 #ifndef CRTSCTS
648 #define CRTSCTS (CCTS_OFLOW | CRTS_IFLOW)
649 #endif
650 
651 #ifndef howmany
652 #define howmany(x, y) (((x) + ((y)-1)) / (y))
653 #endif
654 
655 struct ucred
656 {
657 };
658 #define NOCRED ((struct ucred *)0)  /* no credential available */
659 #define FSCRED ((struct ucred *)-1) /* filesystem credential */
660 
661 /* convert from open() flags to/from fflags; convert O_RD/WR to FREAD/FWRITE */
662 #include <fcntl.h>
663 #define FFLAGS(oflags) ((oflags)&O_EXEC ? (oflags) : (oflags) + 1)
664 #define OFLAGS(fflags) \
665     (((fflags) & (O_EXEC | O_PATH)) != 0 ? (fflags) : (fflags)-1)
666 
667 typedef int fo_rdwr_t(struct lwp_tty *tp, struct uio *uio,
668                       struct ucred *active_cred, int flags,
669                       struct rt_thread *td);
670 typedef int fo_truncate_t(struct lwp_tty *tp, off_t length,
671                           struct ucred *active_cred, struct rt_thread *td);
672 typedef int fo_ioctl_t(struct lwp_tty *tp, rt_ubase_t com, void *data,
673                        struct ucred *active_cred, int fflags, struct rt_thread *td);
674 typedef int fo_poll_t(struct lwp_tty *tp, struct rt_pollreq *rq, struct ucred *active_cred,
675                       struct rt_thread *td);
676 typedef int fo_stat_t(struct lwp_tty *tp, struct stat *sb,
677                       struct ucred *active_cred);
678 typedef int fo_close_t(struct lwp_tty *tp, struct rt_thread *td);
679 
680 #ifdef USING_BSD_FO_EXT
681 typedef int fo_chmod_t(struct file *fp, mode_t mode, struct ucred *active_cred,
682                        struct rt_thread *td);
683 typedef int fo_chown_t(struct file *fp, uid_t uid, gid_t gid,
684                        struct ucred *active_cred, struct rt_thread *td);
685 typedef int fo_sendfile_t(struct file *fp, int sockfd, struct uio *hdr_uio,
686                           struct uio *trl_uio, off_t offset, size_t nbytes,
687                           off_t *sent, int flags, struct rt_thread *td);
688 typedef int fo_seek_t(struct file *fp, off_t offset, int whence,
689                       struct rt_thread *td);
690 
691 typedef int fo_kqfilter_t(struct file *fp, struct knote *kn);
692 typedef int fo_fill_kinfo_t(struct file *fp, struct kinfo_file *kif,
693                             struct filedesc *fdp);
694 typedef int fo_mmap_t(struct file *fp, vm_map_t map, vm_offset_t *addr,
695                       vm_size_t size, vm_prot_t prot, vm_prot_t cap_maxprot,
696                       int flags, vm_ooffset_t foff, struct rt_thread *td);
697 typedef int fo_aio_queue_t(struct file *fp, struct kaiocb *job);
698 
699 typedef int fo_add_seals_t(struct file *fp, int flags);
700 typedef int fo_get_seals_t(struct file *fp, int *flags);
701 typedef int fo_fallocate_t(struct file *fp, off_t offset, off_t len,
702                            struct rt_thread *td);
703 typedef int fo_fspacectl_t(struct file *fp, int cmd, off_t *offset,
704                            off_t *length, int flags, struct ucred *active_cred,
705                            struct rt_thread *td);
706 typedef int fo_spare_t(struct file *fp);
707 #endif /* USING_BSD_FO_EXT */
708 
709 typedef int fo_flags_t;
710 
711 struct bsd_fileops
712 {
713     fo_rdwr_t *fo_read;
714     fo_rdwr_t *fo_write;
715     fo_truncate_t *fo_truncate;
716     fo_ioctl_t *fo_ioctl;
717     fo_poll_t *fo_poll;
718     fo_stat_t *fo_stat;
719     fo_close_t *fo_close;
720 #ifdef USING_BSD_FO_EXT
721     fo_chmod_t *fo_chmod;
722     fo_chown_t *fo_chown;
723     fo_sendfile_t *fo_sendfile;
724     fo_seek_t *fo_seek;
725     fo_kqfilter_t *fo_kqfilter;
726     fo_fill_kinfo_t *fo_fill_kinfo;
727     fo_mmap_t *fo_mmap;
728     fo_aio_queue_t *fo_aio_queue;
729     fo_add_seals_t *fo_add_seals;
730     fo_get_seals_t *fo_get_seals;
731     fo_fallocate_t *fo_fallocate;
732     fo_fspacectl_t *fo_fspacectl;
733     fo_spare_t *fo_spares[8]; /* Spare slots */
734 #endif
735     fo_flags_t fo_flags; /* DFLAG_* below */
736 };
737 
738 #define DFLAG_PASSABLE	0x01	/* may be passed via unix sockets. */
739 #define DFLAG_SEEKABLE	0x02	/* seekable / nonsequential */
740 
741 #endif /* __LWP_TTY_BSD_PORTING_H__ */
742