1#ifndef _USB_BEOS_COMPATIBILITY_H_
2#define _USB_BEOS_COMPATIBILITY_H_
3#ifndef HAIKU_TARGET_PLATFORM_HAIKU
4
5// prevent inclusion of original lock.h as it conflicts with what we have here
6#define _KERNEL_LOCK_H
7
8#include <stdarg.h>
9#include <stdio.h>
10#include <OS.h>
11
12#define IS_USER_ADDRESS(x)		(((uint32)x & 0x80000000) > 0)
13#define IS_KERNEL_ADDRESS(x)	(((uint32)x & 0x80000000) == 0)
14#define B_SPINLOCK_INITIALIZER	0
15#define PCI_usb_ehci			0x20
16
17#ifndef HAIKU_TARGET_PLATFORM_DANO
18enum {
19	B_DEV_INVALID_PIPE = B_DEV_DOOR_OPEN + 1,
20	B_DEV_CRC_ERROR,
21	B_DEV_STALLED,
22	B_DEV_BAD_PID,
23	B_DEV_UNEXPECTED_PID,
24	B_DEV_DATA_OVERRUN,
25	B_DEV_DATA_UNDERRUN,
26	B_DEV_FIFO_OVERRUN,
27	B_DEV_FIFO_UNDERRUN,
28	B_DEV_PENDING,
29	B_DEV_MULTIPLE_ERRORS,
30	B_DEV_TOO_LATE,
31};
32#endif
33
34// wrong, but it won't change for BeOS anymore
35typedef uint32 addr_t;
36
37
38typedef struct mutex {
39	sem_id	sem;
40	int32	count;
41} mutex;
42
43
44inline status_t
45mutex_init(mutex *ben, const char *name)
46{
47	if (ben == NULL || name == NULL)
48		return B_BAD_VALUE;
49
50	ben->count = 1;
51	ben->sem = create_sem(0, name);
52	if (ben->sem >= B_OK)
53		return B_OK;
54
55	return ben->sem;
56}
57
58
59#define MUTEX_FLAG_CLONE_NAME 1
60inline status_t
61mutex_init_etc(mutex *ben, const char *name, int32 flags)
62{
63	return mutex_init(ben, name);
64}
65
66
67inline void
68mutex_destroy(mutex *ben)
69{
70	delete_sem(ben->sem);
71	ben->sem = -1;
72}
73
74
75inline status_t
76mutex_lock(mutex *ben)
77{
78	if (atomic_add(&ben->count, -1) <= 0)
79		return acquire_sem(ben->sem);
80	return B_OK;
81}
82
83
84inline status_t
85mutex_unlock(mutex *ben)
86{
87	if (atomic_add(&ben->count, 1) < 0)
88		return release_sem(ben->sem);
89	return B_OK;
90}
91
92
93class ConditionVariableEntry {
94public:
95	ConditionVariableEntry()
96		:	fSem(-1)
97	{
98	}
99
100	~ConditionVariableEntry()
101	{
102		if (fSem >= 0)
103			delete_sem(fSem);
104	}
105
106	sem_id Added()
107	{
108		if (fSem < 0)
109			fSem = create_sem(0, "condvar entry");
110		return fSem;
111	}
112
113	status_t Wait(uint32 flags, bigtime_t timeout)
114	{
115		return acquire_sem_etc(fSem, 1, flags, timeout);
116	}
117
118private:
119	sem_id					fSem;
120};
121
122
123class ConditionVariable {
124public:
125	ConditionVariable()
126		:	fObject(NULL),
127			fName("condvar"),
128			fSemCount(0)
129	{
130	}
131
132	void Init(void *object, const char *name)
133	{
134		fObject = object;
135		fName = name;
136	}
137
138	void Add(ConditionVariableEntry *entry)
139	{
140		fSems[fSemCount++] = entry->Added();
141	}
142
143	void NotifyAll()
144	{
145		int32 semCount = fSemCount;
146		sem_id sems[semCount];
147		memcpy(sems, fSems, sizeof(sem_id) * semCount);
148		fSemCount = 0;
149
150		for (int32 i = 0; i < semCount; i++)
151			release_sem(sems[i]);
152	}
153
154private:
155	void *		fObject;
156	const char *fName;
157	sem_id		fSems[30];
158	int32		fSemCount;
159};
160
161
162inline void
163load_driver_symbols(char *driver)
164{
165	/* nothing */
166}
167
168
169inline int
170snprintf(char *buffer, size_t bufferSize, const char *format, ...)
171{
172	va_list args;
173	va_start(args, format);
174	int result = vsprintf(buffer, format, args);
175	va_end(args);
176	return result;
177}
178
179
180inline int32
181atomic_get(vint32 *value)
182{
183	return atomic_or(value, 0);
184}
185
186
187inline int32
188atomic_set(vint32 *value, int32 setValue)
189{
190	int32 result = atomic_and(value, 0);
191	int32 previous = atomic_add(value, setValue);
192	if (previous != 0)
193		result = previous;
194	return result;
195}
196
197
198inline status_t
199user_memcpy(void *target, void *source, size_t length)
200{
201	memcpy(target, source, length);
202	return B_OK;
203}
204
205
206#undef B_KERNEL_READ_AREA
207#define B_KERNEL_READ_AREA 0
208#undef B_KERNEL_WRITE_AREA
209#define B_KERNEL_WRITE_AREA 0
210
211#endif // !HAIKU_TARGET_PLATFORM_HAIKU
212#endif // !_USB_BEOS_COMPATIBILITY_H_
213