1 |
|
/* |
2 |
|
* ether_defs.h - Definitions for DLPI Ethernet Driver |
3 |
|
* |
4 |
< |
* SheepShaver (C) 1997-2002 Marc Hellwig and Christian Bauer |
4 |
> |
* SheepShaver (C) 1997-2005 Marc Hellwig and Christian Bauer |
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 |
22 |
|
#define ETHER_DEFS_H |
23 |
|
|
24 |
|
|
25 |
< |
#if __BEOS__ && __POWERPC__ |
25 |
> |
#if __MWERKS__ && __POWERPC__ |
26 |
|
#define PRAGMA_ALIGN_SUPPORTED 1 |
27 |
|
#define PACKED__ |
28 |
< |
#else |
28 |
> |
#elif defined __GNUC__ |
29 |
|
#define PACKED__ __attribute__ ((packed)) |
30 |
+ |
#elif defined __sgi |
31 |
+ |
#define PRAGMA_PACK_SUPPORTED 1 |
32 |
+ |
#define PACKED__ |
33 |
+ |
#else |
34 |
+ |
#error "Packed attribute or pragma shall be supported" |
35 |
|
#endif |
36 |
|
|
37 |
|
|
194 |
|
|
195 |
|
|
196 |
|
/* |
197 |
+ |
* Data member wrappers |
198 |
+ |
*/ |
199 |
+ |
|
200 |
+ |
// Forward declarations |
201 |
+ |
struct datab; |
202 |
+ |
struct msgb; |
203 |
+ |
struct queue; |
204 |
+ |
struct multicast_node; |
205 |
+ |
struct DLPIStream; |
206 |
+ |
|
207 |
+ |
// Optimize for 32-bit big endian targets |
208 |
+ |
#if defined(WORDS_BIGENDIAN) && (SIZEOF_VOID_P == 4) |
209 |
+ |
|
210 |
+ |
// Predefined member types |
211 |
+ |
typedef int8 nw_int8; |
212 |
+ |
typedef int16 nw_int16; |
213 |
+ |
typedef int32 nw_int32; |
214 |
+ |
typedef uint8 nw_uint8; |
215 |
+ |
typedef uint16 nw_uint16; |
216 |
+ |
typedef uint32 nw_uint32; |
217 |
+ |
typedef int nw_bool; |
218 |
+ |
typedef uint8 * nw_uint8_p; |
219 |
+ |
typedef void * nw_void_p; |
220 |
+ |
typedef datab * nw_datab_p; |
221 |
+ |
typedef msgb * nw_msgb_p; |
222 |
+ |
typedef queue * nw_queue_p; |
223 |
+ |
typedef multicast_node *nw_multicast_node_p; |
224 |
+ |
typedef DLPIStream * nw_DLPIStream_p; |
225 |
+ |
|
226 |
+ |
#else |
227 |
+ |
|
228 |
+ |
// Big-endian memory accessor |
229 |
+ |
template< int nbytes > |
230 |
+ |
struct nw_memory_helper; |
231 |
+ |
|
232 |
+ |
template<> |
233 |
+ |
struct nw_memory_helper<1> { |
234 |
+ |
static inline uint8 load(void *ptr) { return *((uint8 *)ptr); } |
235 |
+ |
static inline void store(void *ptr, uint8 val) { *((uint8 *)ptr) = val; } |
236 |
+ |
}; |
237 |
+ |
|
238 |
+ |
template<> |
239 |
+ |
struct nw_memory_helper<2> { |
240 |
+ |
static inline uint16 load(void *ptr) { return ntohs(*((uint16 *)ptr)); } |
241 |
+ |
static inline void store(void *ptr, uint16 val) { *((uint16 *)ptr) = htons(val); } |
242 |
+ |
}; |
243 |
+ |
|
244 |
+ |
template<> |
245 |
+ |
struct nw_memory_helper<4> { |
246 |
+ |
static inline uint32 load(void *ptr) { return ntohl(*((uint32 *)ptr)); } |
247 |
+ |
static inline void store(void *ptr, uint32 val) { *((uint32 *)ptr) = htonl(val); } |
248 |
+ |
}; |
249 |
+ |
|
250 |
+ |
// Scalar data member wrapper (specialise for pointer member types?) |
251 |
+ |
template< class type, class public_type > |
252 |
+ |
class nw_scalar_member_helper { |
253 |
+ |
uint8 _pad[sizeof(type)]; |
254 |
+ |
public: |
255 |
+ |
operator public_type () const { |
256 |
+ |
return (public_type)(uintptr)nw_memory_helper<sizeof(type)>::load((void *)this); |
257 |
+ |
} |
258 |
+ |
public_type operator -> () const { |
259 |
+ |
return this->operator public_type (); |
260 |
+ |
} |
261 |
+ |
nw_scalar_member_helper<type, public_type> & operator = (public_type val) { |
262 |
+ |
nw_memory_helper<sizeof(type)>::store((void *)this, (type)(uintptr)val); |
263 |
+ |
return *this; |
264 |
+ |
} |
265 |
+ |
nw_scalar_member_helper<type, public_type> & operator += (int val) { |
266 |
+ |
*this = *this + val; |
267 |
+ |
return *this; |
268 |
+ |
} |
269 |
+ |
nw_scalar_member_helper<type, public_type> & operator -= (int val) { |
270 |
+ |
*this = *this - val; |
271 |
+ |
return *this; |
272 |
+ |
} |
273 |
+ |
nw_scalar_member_helper<type, public_type> & operator &= (int val) { |
274 |
+ |
*this = *this & val; |
275 |
+ |
return *this; |
276 |
+ |
} |
277 |
+ |
nw_scalar_member_helper<type, public_type> & operator |= (int val) { |
278 |
+ |
*this = *this | val; |
279 |
+ |
return *this; |
280 |
+ |
} |
281 |
+ |
}; |
282 |
+ |
|
283 |
+ |
// Predefined member types |
284 |
+ |
typedef nw_scalar_member_helper<uint8, int8> nw_int8; |
285 |
+ |
typedef nw_scalar_member_helper<uint16, int16> nw_int16; |
286 |
+ |
typedef nw_scalar_member_helper<uint32, int32> nw_int32; |
287 |
+ |
typedef nw_scalar_member_helper<uint8, uint8> nw_uint8; |
288 |
+ |
typedef nw_scalar_member_helper<uint16, uint16> nw_uint16; |
289 |
+ |
typedef nw_scalar_member_helper<uint32, uint32> nw_uint32; |
290 |
+ |
typedef nw_scalar_member_helper<int, bool> nw_bool; |
291 |
+ |
typedef nw_scalar_member_helper<uint32, uint8 *> nw_uint8_p; |
292 |
+ |
typedef nw_scalar_member_helper<uint32, void *> nw_void_p; |
293 |
+ |
typedef nw_scalar_member_helper<uint32, datab *> nw_datab_p; |
294 |
+ |
typedef nw_scalar_member_helper<uint32, msgb *> nw_msgb_p; |
295 |
+ |
typedef nw_scalar_member_helper<uint32, queue *> nw_queue_p; |
296 |
+ |
typedef nw_scalar_member_helper<uint32, multicast_node *> nw_multicast_node_p; |
297 |
+ |
typedef nw_scalar_member_helper<uint32, DLPIStream *> nw_DLPIStream_p; |
298 |
+ |
|
299 |
+ |
#endif |
300 |
+ |
|
301 |
+ |
|
302 |
+ |
/* |
303 |
|
* Structures |
304 |
|
*/ |
305 |
|
|
306 |
|
// Data block |
307 |
|
struct datab { |
308 |
< |
datab *db_freep; |
309 |
< |
uint8 *db_base; |
310 |
< |
uint8 *db_lim; |
311 |
< |
uint8 db_ref; |
312 |
< |
uint8 db_type; |
308 |
> |
nw_datab_p db_freep; |
309 |
> |
nw_uint8_p db_base; |
310 |
> |
nw_uint8_p db_lim; |
311 |
> |
nw_uint8 db_ref; |
312 |
> |
nw_uint8 db_type; |
313 |
|
// ... |
314 |
|
}; |
315 |
|
|
316 |
|
// Message block |
317 |
|
struct msgb { |
318 |
< |
msgb *b_next; |
319 |
< |
msgb *b_prev; |
320 |
< |
msgb *b_cont; |
321 |
< |
uint8 *b_rptr; |
322 |
< |
uint8 *b_wptr; |
323 |
< |
datab *b_datap; |
318 |
> |
nw_msgb_p b_next; |
319 |
> |
nw_msgb_p b_prev; |
320 |
> |
nw_msgb_p b_cont; |
321 |
> |
nw_uint8_p b_rptr; |
322 |
> |
nw_uint8_p b_wptr; |
323 |
> |
nw_datab_p b_datap; |
324 |
|
// ... |
325 |
|
}; |
326 |
|
|
327 |
|
// Queue (full structure required because of size) |
328 |
|
struct queue { |
329 |
< |
void *q_qinfo; |
330 |
< |
msgb *q_first; |
331 |
< |
msgb *q_last; |
332 |
< |
queue *q_next; |
333 |
< |
queue *q_link; |
334 |
< |
void *q_ptr; |
335 |
< |
uint32 q_count; |
336 |
< |
int32 q_minpsz; |
337 |
< |
int32 q_maxpsz; |
338 |
< |
uint32 q_hiwat; |
339 |
< |
uint32 q_lowat; |
340 |
< |
void *q_bandp; |
341 |
< |
uint16 q_flag; |
342 |
< |
uint8 q_nband; |
343 |
< |
uint8 q_pad1[1]; |
344 |
< |
void *q_osx; |
345 |
< |
queue *q_ffcp; |
346 |
< |
queue *q_bfcp; |
329 |
> |
nw_void_p q_qinfo; |
330 |
> |
nw_msgb_p q_first; |
331 |
> |
nw_msgb_p q_last; |
332 |
> |
nw_queue_p q_next; |
333 |
> |
nw_queue_p q_link; |
334 |
> |
nw_DLPIStream_p q_ptr; |
335 |
> |
nw_uint32 q_count; |
336 |
> |
nw_int32 q_minpsz; |
337 |
> |
nw_int32 q_maxpsz; |
338 |
> |
nw_uint32 q_hiwat; |
339 |
> |
nw_uint32 q_lowat; |
340 |
> |
nw_void_p q_bandp; |
341 |
> |
nw_uint16 q_flag; |
342 |
> |
nw_uint8 q_nband; |
343 |
> |
uint8 _q_pad1[1]; |
344 |
> |
nw_void_p q_osx; |
345 |
> |
nw_queue_p q_ffcp; |
346 |
> |
nw_queue_p q_bfcp; |
347 |
|
}; |
348 |
|
typedef struct queue queue_t; |
349 |
|
|
350 |
|
// M_IOCTL parameters |
351 |
|
struct iocblk { |
352 |
< |
int32 ioc_cmd; |
353 |
< |
void *ioc_cr; |
354 |
< |
uint32 ioc_id; |
355 |
< |
uint32 ioc_count; |
356 |
< |
int32 ioc_error; |
357 |
< |
int32 ioc_rval; |
358 |
< |
int32 ioc_filler[4]; |
352 |
> |
nw_int32 ioc_cmd; |
353 |
> |
nw_void_p ioc_cr; |
354 |
> |
nw_uint32 ioc_id; |
355 |
> |
nw_uint32 ioc_count; |
356 |
> |
nw_int32 ioc_error; |
357 |
> |
nw_int32 ioc_rval; |
358 |
> |
int32 _ioc_filler[4]; |
359 |
|
}; |
360 |
|
|
361 |
|
// Priority specification |
362 |
|
struct dl_priority_t { |
363 |
< |
int32 dl_min, dl_max; |
363 |
> |
nw_int32 dl_min, dl_max; |
364 |
|
}; |
365 |
|
|
366 |
|
// DPLI primitives |
367 |
|
struct dl_info_req_t { |
368 |
< |
uint32 dl_primitive; // DL_INFO_REQ |
368 |
> |
nw_uint32 dl_primitive; // DL_INFO_REQ |
369 |
|
}; |
370 |
|
|
371 |
|
struct dl_info_ack_t { |
372 |
< |
uint32 dl_primitive; // DL_INFO_ACK |
373 |
< |
uint32 dl_max_sdu; |
374 |
< |
uint32 dl_min_sdu; |
375 |
< |
uint32 dl_addr_length; |
376 |
< |
uint32 dl_mac_type; |
377 |
< |
uint32 dl_reserved; |
378 |
< |
uint32 dl_current_state; |
379 |
< |
int32 dl_sap_length; |
380 |
< |
uint32 dl_service_mode; |
381 |
< |
uint32 dl_qos_length; |
382 |
< |
uint32 dl_qos_offset; |
383 |
< |
uint32 dl_qos_range_length; |
384 |
< |
uint32 dl_qos_range_offset; |
385 |
< |
uint32 dl_provider_style; |
386 |
< |
uint32 dl_addr_offset; |
387 |
< |
uint32 dl_version; |
388 |
< |
uint32 dl_brdcst_addr_length; |
389 |
< |
uint32 dl_brdcst_addr_offset; |
390 |
< |
uint32 dl_growth; |
372 |
> |
nw_uint32 dl_primitive; // DL_INFO_ACK |
373 |
> |
nw_uint32 dl_max_sdu; |
374 |
> |
nw_uint32 dl_min_sdu; |
375 |
> |
nw_uint32 dl_addr_length; |
376 |
> |
nw_uint32 dl_mac_type; |
377 |
> |
nw_uint32 dl_reserved; |
378 |
> |
nw_uint32 dl_current_state; |
379 |
> |
nw_int32 dl_sap_length; |
380 |
> |
nw_uint32 dl_service_mode; |
381 |
> |
nw_uint32 dl_qos_length; |
382 |
> |
nw_uint32 dl_qos_offset; |
383 |
> |
nw_uint32 dl_qos_range_length; |
384 |
> |
nw_uint32 dl_qos_range_offset; |
385 |
> |
nw_uint32 dl_provider_style; |
386 |
> |
nw_uint32 dl_addr_offset; |
387 |
> |
nw_uint32 dl_version; |
388 |
> |
nw_uint32 dl_brdcst_addr_length; |
389 |
> |
nw_uint32 dl_brdcst_addr_offset; |
390 |
> |
nw_uint32 dl_growth; |
391 |
|
}; |
392 |
|
|
393 |
|
struct dl_bind_req_t { |
394 |
< |
uint32 dl_primitive; // DL_BIND_REQ |
395 |
< |
uint32 dl_sap; |
396 |
< |
uint32 dl_max_conind; |
397 |
< |
uint16 dl_service_mode; |
398 |
< |
uint16 dl_conn_mgmt; |
399 |
< |
uint32 dl_xidtest_flg; |
394 |
> |
nw_uint32 dl_primitive; // DL_BIND_REQ |
395 |
> |
nw_uint32 dl_sap; |
396 |
> |
nw_uint32 dl_max_conind; |
397 |
> |
nw_uint16 dl_service_mode; |
398 |
> |
nw_uint16 dl_conn_mgmt; |
399 |
> |
nw_uint32 dl_xidtest_flg; |
400 |
|
}; |
401 |
|
|
402 |
|
struct dl_bind_ack_t { |
403 |
< |
uint32 dl_primitive; // DL_BIND_ACK |
404 |
< |
uint32 dl_sap; |
405 |
< |
uint32 dl_addr_length; |
406 |
< |
uint32 dl_addr_offset; |
407 |
< |
uint32 dl_max_conind; |
408 |
< |
uint32 dl_xidtest_flg; |
403 |
> |
nw_uint32 dl_primitive; // DL_BIND_ACK |
404 |
> |
nw_uint32 dl_sap; |
405 |
> |
nw_uint32 dl_addr_length; |
406 |
> |
nw_uint32 dl_addr_offset; |
407 |
> |
nw_uint32 dl_max_conind; |
408 |
> |
nw_uint32 dl_xidtest_flg; |
409 |
|
}; |
410 |
|
|
411 |
|
struct dl_error_ack_t { |
412 |
< |
uint32 dl_primitive; // DL_ERROR_ACK |
413 |
< |
uint32 dl_error_primitive; |
414 |
< |
uint32 dl_errno; |
415 |
< |
uint32 dl_unix_errno; |
412 |
> |
nw_uint32 dl_primitive; // DL_ERROR_ACK |
413 |
> |
nw_uint32 dl_error_primitive; |
414 |
> |
nw_uint32 dl_errno; |
415 |
> |
nw_uint32 dl_unix_errno; |
416 |
|
}; |
417 |
|
|
418 |
|
struct dl_ok_ack_t { |
419 |
< |
uint32 dl_primitive; // DL_ERROR_ACK |
420 |
< |
uint32 dl_correct_primitive; |
419 |
> |
nw_uint32 dl_primitive; // DL_ERROR_ACK |
420 |
> |
nw_uint32 dl_correct_primitive; |
421 |
|
}; |
422 |
|
|
423 |
|
struct dl_unitdata_req_t { |
424 |
< |
uint32 dl_primitive; // DL_UNITDATA_REQ |
425 |
< |
uint32 dl_dest_addr_length; |
426 |
< |
uint32 dl_dest_addr_offset; |
424 |
> |
nw_uint32 dl_primitive; // DL_UNITDATA_REQ |
425 |
> |
nw_uint32 dl_dest_addr_length; |
426 |
> |
nw_uint32 dl_dest_addr_offset; |
427 |
|
dl_priority_t dl_priority; |
428 |
|
}; |
429 |
|
|
430 |
|
struct dl_unitdata_ind_t { |
431 |
< |
uint32 dl_primitive; // DL_UNITDATA_IND |
432 |
< |
uint32 dl_dest_addr_length; |
433 |
< |
uint32 dl_dest_addr_offset; |
434 |
< |
uint32 dl_src_addr_length; |
435 |
< |
uint32 dl_src_addr_offset; |
436 |
< |
uint32 dl_group_address; |
431 |
> |
nw_uint32 dl_primitive; // DL_UNITDATA_IND |
432 |
> |
nw_uint32 dl_dest_addr_length; |
433 |
> |
nw_uint32 dl_dest_addr_offset; |
434 |
> |
nw_uint32 dl_src_addr_length; |
435 |
> |
nw_uint32 dl_src_addr_offset; |
436 |
> |
nw_uint32 dl_group_address; |
437 |
|
}; |
438 |
|
|
439 |
|
struct dl_uderror_ind_t { |
440 |
< |
uint32 dl_primitive; // DL_UDERROR_IND |
441 |
< |
uint32 dl_dest_addr_length; |
442 |
< |
uint32 dl_dest_addr_offset; |
443 |
< |
uint32 dl_unix_errno; |
444 |
< |
uint32 dl_errno; |
440 |
> |
nw_uint32 dl_primitive; // DL_UDERROR_IND |
441 |
> |
nw_uint32 dl_dest_addr_length; |
442 |
> |
nw_uint32 dl_dest_addr_offset; |
443 |
> |
nw_uint32 dl_unix_errno; |
444 |
> |
nw_uint32 dl_errno; |
445 |
|
}; |
446 |
|
|
447 |
|
struct dl_subs_bind_req_t { |
448 |
< |
uint32 dl_primitive; // DL_SUBS_BIND_REQ |
449 |
< |
uint32 dl_subs_sap_offset; |
450 |
< |
uint32 dl_subs_sap_length; |
451 |
< |
uint32 dl_subs_bind_class; |
448 |
> |
nw_uint32 dl_primitive; // DL_SUBS_BIND_REQ |
449 |
> |
nw_uint32 dl_subs_sap_offset; |
450 |
> |
nw_uint32 dl_subs_sap_length; |
451 |
> |
nw_uint32 dl_subs_bind_class; |
452 |
|
}; |
453 |
|
|
454 |
|
struct dl_subs_bind_ack_t { |
455 |
< |
uint32 dl_primitive; // DL_SUBS_BIND_ACK |
456 |
< |
uint32 dl_subs_sap_offset; |
457 |
< |
uint32 dl_subs_sap_length; |
455 |
> |
nw_uint32 dl_primitive; // DL_SUBS_BIND_ACK |
456 |
> |
nw_uint32 dl_subs_sap_offset; |
457 |
> |
nw_uint32 dl_subs_sap_length; |
458 |
|
}; |
459 |
|
|
460 |
|
struct dl_subs_unbind_req_t { |
461 |
< |
uint32 dl_primitive; // DL_SUBS_UNBIND_REQ |
462 |
< |
uint32 dl_subs_sap_offset; |
463 |
< |
uint32 dl_subs_sap_length; |
461 |
> |
nw_uint32 dl_primitive; // DL_SUBS_UNBIND_REQ |
462 |
> |
nw_uint32 dl_subs_sap_offset; |
463 |
> |
nw_uint32 dl_subs_sap_length; |
464 |
|
}; |
465 |
|
|
466 |
|
struct dl_enabmulti_req_t { |
467 |
< |
uint32 dl_primitive; // DL_ENABMULTI_REQ |
468 |
< |
uint32 dl_addr_length; |
469 |
< |
uint32 dl_addr_offset; |
467 |
> |
nw_uint32 dl_primitive; // DL_ENABMULTI_REQ |
468 |
> |
nw_uint32 dl_addr_length; |
469 |
> |
nw_uint32 dl_addr_offset; |
470 |
|
}; |
471 |
|
|
472 |
|
struct dl_disabmulti_req_t { |
473 |
< |
uint32 dl_primitive; // DL_DISABMULTI_REQ |
474 |
< |
uint32 dl_addr_length; |
475 |
< |
uint32 dl_addr_offset; |
473 |
> |
nw_uint32 dl_primitive; // DL_DISABMULTI_REQ |
474 |
> |
nw_uint32 dl_addr_length; |
475 |
> |
nw_uint32 dl_addr_offset; |
476 |
|
}; |
477 |
|
|
478 |
|
struct dl_phys_addr_req_t { |
479 |
< |
uint32 dl_primitive; // DL_PHYS_ADDR_REQ |
480 |
< |
uint32 dl_addr_type; |
479 |
> |
nw_uint32 dl_primitive; // DL_PHYS_ADDR_REQ |
480 |
> |
nw_uint32 dl_addr_type; |
481 |
|
}; |
482 |
|
|
483 |
|
struct dl_phys_addr_ack_t { |
484 |
< |
uint32 dl_primitive; // DL_PHYS_ADDR_ACK |
485 |
< |
uint32 dl_addr_length; |
486 |
< |
uint32 dl_addr_offset; |
484 |
> |
nw_uint32 dl_primitive; // DL_PHYS_ADDR_ACK |
485 |
> |
nw_uint32 dl_addr_length; |
486 |
> |
nw_uint32 dl_addr_offset; |
487 |
|
}; |
488 |
|
|
489 |
|
// Parameters for I_OTSetRawMode/kOTSetRecvMode ioctl() |
490 |
|
struct dl_recv_control_t { |
491 |
< |
uint32 dl_primitive; |
492 |
< |
uint32 dl_flags; |
493 |
< |
uint32 dl_truncation_length; |
491 |
> |
nw_uint32 dl_primitive; |
492 |
> |
nw_uint32 dl_flags; |
493 |
> |
nw_uint32 dl_truncation_length; |
494 |
|
}; |
495 |
|
|
496 |
|
union DL_primitives { |
497 |
< |
uint32 dl_primitive; |
497 |
> |
nw_uint32 dl_primitive; |
498 |
|
dl_info_req_t info_req; |
499 |
|
dl_info_ack_t info_ack; |
500 |
|
dl_bind_req_t bind_req; |
517 |
|
#pragma options align=mac68k |
518 |
|
#endif |
519 |
|
|
520 |
+ |
#ifdef PRAGMA_PACK_SUPPORTED |
521 |
+ |
#pragma pack(1) |
522 |
+ |
#endif |
523 |
+ |
|
524 |
|
// Packet headers |
525 |
|
struct EnetPacketHeader { |
526 |
|
uint8 fDestAddr[6]; |
527 |
|
uint8 fSourceAddr[6]; |
528 |
< |
uint16 fProto; |
528 |
> |
nw_uint16 fProto; |
529 |
|
} PACKED__; |
530 |
|
|
531 |
|
struct T8022Header { |
548 |
|
|
549 |
|
struct T8022AddressStruct { |
550 |
|
uint8 fHWAddr[6]; |
551 |
< |
uint16 fSAP; |
551 |
> |
nw_uint16 fSAP; |
552 |
|
uint8 fSNAP[k8022SNAPLength]; |
553 |
|
} PACKED__; |
554 |
|
|
555 |
+ |
#ifdef PRAGMA_PACK_SUPPORTED |
556 |
+ |
#pragma pack(0) |
557 |
+ |
#endif |
558 |
+ |
|
559 |
|
#ifdef PRAGMA_ALIGN_SUPPORTED |
560 |
|
#pragma options align=reset |
561 |
|
#endif |