1/*
2 * Copyright (c) 2001 - 2012 Apple Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
12 *
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23#ifdef KERNEL
24#define _KERNEL
25
26#include <sys/buf.h>
27#include <sys/kpi_mbuf.h>
28#include <sys/mount.h>
29#include <sys/namei.h>
30#include <sys/ubc.h>
31#include <miscfs/specfs/specdev.h>
32#include <miscfs/devfs/devfs.h>
33#include <machine/spl.h>
34#include <kern/thread.h>
35#include <kern/thread_call.h>
36#include <string.h>
37
38#define M_SMBFSMNT M_TEMP /* HACK XXX CSM */
39#define M_SMBNODE M_TEMP /* HACK XXX CSM */
40#define M_SMBNODENAME M_TEMP /* HACK XXX CSM */
41#define M_SMBFSDATA M_TEMP /* HACK XXX CSM */
42#define M_SMBFSHASH M_TEMP /* HACK XXX CSM */
43#define M_SMBFSFID M_TEMP /* HACK XXX CSM */
44#define M_SMBCONN M_TEMP /* HACK CSM XXX */
45#define M_NSMBDEV M_TEMP /* HACK CSM XXX */
46#define M_SMBIOD M_TEMP /* HACK CSM XXX */
47#define M_SMBRQ M_TEMP /* HACK CSM XXX */
48#define M_SMBDATA M_TEMP /* HACK CSM XXX */
49#define M_SMBSTR M_TEMP /* HACK CSM XXX */
50#define M_SMBTEMP M_TEMP /* HACK CSM XXX */
51
52#define SMB_MALLOC(addr, cast, size, type, flags) do { MALLOC((addr), cast, (size), (type), (flags)); } while(0)
53
54#ifndef SMB_DEBUG
55#define SMB_FREE(addr, type)	do { if (addr) FREE(addr, type); addr = NULL; } while(0)
56#else   // SMB_DEBUG
57#define SMB_FREE(addr, type) do { \
58    if (addr) {\
59        FREE(addr, type); \
60    } \
61    else { \
62        SMBERROR("%s: attempt to free NULL pointer, line %d\n", __FUNCTION__, __LINE__); \
63    } \
64    addr = NULL; \
65} while(0)
66#endif  // SMB_DEBUG
67
68#undef FB_CURRENT
69
70/* Max number of times we will attempt to open in a reconnect */
71#define SMB_MAX_REOPEN_CNT	25
72
73typedef enum modeventtype {
74	MOD_LOAD,
75	MOD_UNLOAD,
76	MOD_SHUTDOWN
77} modeventtype_t;
78
79typedef struct kmod_info *module_t;
80
81typedef int (*modeventhand_t)(module_t mod, int what, void *arg);
82
83typedef struct moduledata {
84	const char		*name;  /* module name */
85	modeventhand_t  evhand; /* event handler */
86	void		*priv;  /* extra data */
87} moduledata_t;
88
89#define DECLARE_MODULE(name, data, sub, order)				\
90	moduledata_t * _smb_md_##name = &data;
91#define SEND_EVENT(name, event)						\
92	{								\
93		extern moduledata_t * _smb_md_##name; 		\
94		if (_smb_md_##name) \
95		_smb_md_##name->evhand(smbfs_kmod_infop,		\
96					 event,				\
97					 _smb_md_##name->priv);		\
98	}
99#define DEV_MODULE(name, evh, arg) \
100	static moduledata_t name##_mod = {	\
101		#name,				\
102		evh,				\
103		arg				\
104	};					\
105	DECLARE_MODULE(name, name##_mod, SI_SUB_DRIVERS, SI_ORDER_ANY);
106
107struct smbnode;
108extern int	smb_smb_flush __P((struct smbnode *, vfs_context_t));
109
110typedef int	 vnop_t __P((void *));
111
112#define vn_todev(vp) (vnode_vtype(vp) == VBLK || vnode_vtype(vp) == VCHR ? \
113		      vnode_specrdev(vp) : NODEV)
114
115void timevaladd(struct timeval *, struct timeval *);
116void timevalsub(struct timeval *, struct timeval *);
117#define timevalcmp(l, r, cmp)	timercmp(l, r, cmp)
118#define timespeccmp(tvp, uvp, cmp)				  \
119	(((tvp)->tv_sec == (uvp)->tv_sec) ?			 \
120	    ((tvp)->tv_nsec cmp (uvp)->tv_nsec) :		   \
121	    ((tvp)->tv_sec cmp (uvp)->tv_sec))
122#define timespecadd(vvp, uvp)					   \
123	do {							\
124		(vvp)->tv_sec += (uvp)->tv_sec;			 \
125		(vvp)->tv_nsec += (uvp)->tv_nsec;		   \
126		if ((vvp)->tv_nsec >= 1000000000) {		 \
127			(vvp)->tv_sec++;				\
128			(vvp)->tv_nsec -= 1000000000;		   \
129		}						   \
130	} while (0)
131#define timespecsub(vvp, uvp)					   \
132	do {							\
133		(vvp)->tv_sec -= (uvp)->tv_sec;			 \
134		(vvp)->tv_nsec -= (uvp)->tv_nsec;		   \
135		if ((vvp)->tv_nsec < 0) {			   \
136			(vvp)->tv_sec--;				\
137			(vvp)->tv_nsec += 1000000000;		   \
138		}						   \
139	} while (0)
140
141#endif /* KERNEL */
142