Whamcloud - gitweb
b=16098
[fs/lustre-release.git] / libcfs / include / libcfs / winnt / winnt-tcpip.h
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * GPL HEADER START
5  *
6  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License version 2 only,
10  * as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * General Public License version 2 for more details (a copy is included
16  * in the LICENSE file that accompanied this code).
17  *
18  * You should have received a copy of the GNU General Public License
19  * version 2 along with this program; If not, see [sun.com URL with a
20  * copy of GPLv2].
21  *
22  * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
23  * CA 95054 USA or visit www.sun.com if you need additional information or
24  * have any questions.
25  *
26  * GPL HEADER END
27  */
28 /*
29  * Copyright  2008 Sun Microsystems, Inc. All rights reserved
30  * Use is subject to license terms.
31  */
32 /*
33  * This file is part of Lustre, http://www.lustre.org/
34  * Lustre is a trademark of Sun Microsystems, Inc.
35  */
36
37 #ifndef __LIBCFS_WINNT_TCPIP_H__
38 #define __LIBCFS_WINNT_TCPIP_H__
39
40 #ifndef __LIBCFS_LIBCFS_H__
41 #error Do not #include this file directly. #include <libcfs/libcfs.h> instead
42 #endif
43
44
45 #ifdef __KERNEL__
46
47 //
48 //  ks definitions
49 //
50
51 // iovec is defined in libcfs: winnt_prim.h 
52 // lnetkiov_t is defined in lnet/types.h
53
54 typedef struct socket ksock_tconn_t;
55 typedef struct socket cfs_socket_t;
56
57 // completion notification callback routine
58
59 typedef VOID (*ksock_schedule_cb)(struct socket*, int, void *, ulong_ptr);
60
61 /* completion routine to update tx structure for async sending */
62 typedef PVOID (*ksock_update_tx)(struct socket*, PVOID tx, ulong_ptr);
63
64 //
65 // tdinal definitions
66 //
67
68
69 #if TDI_LIBCFS_DBG
70 #define KsPrint(X)     KsPrintf X
71 #else
72 #define KsPrint(X)
73 #endif
74
75
76 //
77 // Socket Addresses Related ...
78 //
79
80 #define     INADDR_ANY              (ULONG)0x00000000
81 #define     INADDR_LOOPBACK     (ULONG)0x7f000001
82 #define     INADDR_BROADCAST    (ULONG)0xffffffff
83 #define     INADDR_NONE             (ULONG)0xffffffff
84
85 /*
86  *  TCP / IP options
87  */
88
89 #define     SOL_TCP             6
90 #define     SOL_UDP                     17
91
92
93 #define TL_INSTANCE             0
94
95 #define TCP_SOCKET_NODELAY      1 //  disabling "Nagle"
96 #define TCP_SOCKET_KEEPALIVE    2
97 #define TCP_SOCKET_OOBINLINE    3
98 #define TCP_SOCKET_BSDURGENT    4
99 #define TCP_SOCKET_ATMARK       5
100 #define TCP_SOCKET_WINDOW       6
101
102
103 /* Flags we can use with send/ and recv. 
104    Added those for 1003.1g not all are supported yet
105  */
106  
107 #define MSG_OOB             1
108 #define MSG_PEEK        2
109 #define MSG_DONTROUTE   4
110 #define MSG_TRYHARD     4       /* Synonym for MSG_DONTROUTE for DECnet */
111 #define MSG_CTRUNC      8
112 #define MSG_PROBE       0x10    /* Do not send. Only probe path f.e. for MTU */
113 #define MSG_TRUNC       0x20
114 #define MSG_DONTWAIT    0x40    /* Nonblocking io                */
115 #define MSG_EOR         0x80    /* End of record */
116 #define MSG_WAITALL     0x100   /* Wait for a full request */
117 #define MSG_FIN         0x200
118 #define MSG_SYN         0x400
119 #define MSG_CONFIRM     0x800   /* Confirm path validity */
120 #define MSG_RST         0x1000
121 #define MSG_ERRQUEUE    0x2000  /* Fetch message from error queue */
122 #define MSG_NOSIGNAL    0x4000  /* Do not generate SIGPIPE */
123 #define MSG_MORE        0x8000  /* Sender will send more */
124
125 #define MSG_EOF         MSG_FIN
126
127
128 //
129 // Maximum TRANSPORT_ADDRESS Length
130 //
131 // it must >= FIELD_OFFSET(TRANSPORT_ADDRESS, Address->Address)
132 //            + TDI_ADDRESS_LENGTH_IP
133 //
134 // I define it a little large and 16 bytes aligned to avoid possible overflow.
135 //
136
137 #define MAX_ADDRESS_LENGTH              (0x30)
138
139
140 //
141 // Maximum Listers Children Sockets
142 //
143
144 #define MAX_CHILD_LISTENERS             (4)
145
146 //
147 // Maximum EA Information Length
148 //
149
150 #define EA_MAX_LENGTH                   ( sizeof(FILE_FULL_EA_INFORMATION) - 1 + \
151                                           TDI_TRANSPORT_ADDRESS_LENGTH + 1 + \
152                                           MAX_ADDRESS_LENGTH )
153
154
155 #define UDP_DEVICE_NAME L"\\Device\\Udp"
156 #define TCP_DEVICE_NAME L"\\Device\\Tcp"
157
158
159 /*
160  * TSDU definitions
161  */
162
163 #define TDINAL_TSDU_DEFAULT_SIZE  (0x10000)
164
165 #define KS_TSDU_MAGIC       'KSTD'
166
167 #define KS_TSDU_ATTACHED    0x00000001  // Attached to the socket receive tsdu list
168
169 typedef struct _KS_TSDU {
170
171     ULONG               Magic;
172     ULONG               Flags;
173
174     struct list_head    Link;
175
176     ULONG               TotalLength;    // Total size of KS_TSDU
177
178     ULONG               StartOffset;    // Start offset of the first Tsdu unit
179     ULONG               LastOffset;     // End offset of the last Tsdu unit
180
181 /*
182     union {
183         KS_TSDU_DAT[];
184         KS_TSDU_BUF[];
185         KS_TSDU_MDL[];
186     }
187 */
188
189 } KS_TSDU, *PKS_TSDU;
190
191 #define TSDU_TYPE_BUF   ((USHORT)0x5401)
192 #define TSDU_TYPE_DAT   ((USHORT)0x5402)
193 #define TSDU_TYPE_MDL   ((USHORT)0x5403)
194
195 #define KS_TSDU_BUF_RECEIVING       0x0001
196 typedef struct _KS_TSDU_BUF {
197
198     USHORT              TsduType;
199     USHORT              TsduFlags;
200
201     ULONG               DataLength;
202     ULONG               StartOffset;
203
204     PVOID               UserBuffer;
205
206 } KS_TSDU_BUF, *PKS_TSDU_BUF;
207
208 #define KS_TSDU_DAT_RECEIVING       0x0001
209
210 typedef struct _KS_TSDU_DAT {
211
212     USHORT              TsduType;
213     USHORT              TsduFlags;
214
215     ULONG               DataLength;
216     ULONG               StartOffset;
217
218     ULONG               TotalLength;
219
220     UCHAR               Data[1];
221
222 } KS_TSDU_DAT, *PKS_TSDU_DAT;
223
224 #define KS_DWORD_ALIGN(x)      (((x) + 0x03) & (~(0x03)))
225 #define KS_TSDU_STRU_SIZE(Len) (KS_DWORD_ALIGN((Len) + FIELD_OFFSET(KS_TSDU_DAT, Data)))
226
227 typedef struct _KS_TSDU_MDL {
228
229     USHORT              TsduType;
230     USHORT              TsduFlags;
231
232     ULONG               DataLength;
233     ULONG               StartOffset;    
234
235     PMDL                Mdl;
236     PVOID               Descriptor;
237
238 } KS_TSDU_MDL, *PKS_TSDU_MDL;
239
240
241 typedef struct _KS_TSDUMGR {
242
243     struct list_head    TsduList;
244     ULONG               NumOfTsdu;
245     ULONG               TotalBytes;
246     KEVENT              Event;
247
248 } KS_TSDUMGR, *PKS_TSDUMGR;
249
250
251 typedef struct _KS_CHAIN {
252
253     KS_TSDUMGR          Normal;
254     KS_TSDUMGR          Expedited;
255
256 } KS_CHAIN, *PKS_CHAIN;
257
258
259 #define TDINAL_SCHED_FACTOR (1)
260 #define CAN_BE_SCHED(Len, Limit) (Len >= ((Limit) >> TDINAL_SCHED_FACTOR))
261
262 //
263 // Handler Settings Indictor 
264 //
265
266 #define TDI_EVENT_MAXIMUM_HANDLER (TDI_EVENT_ERROR_EX + 1)
267
268
269 typedef struct _KS_EVENT_HANDLERS {
270     BOOLEAN     IsActive[TDI_EVENT_MAXIMUM_HANDLER];
271     PVOID       Handler [TDI_EVENT_MAXIMUM_HANDLER];
272 } KS_EVENT_HANDLERS, *PKS_EVENT_HANDLERS;
273
274 #define SetEventHandler(ha, ht, hr) do {        \
275             ha.IsActive[ht] = TRUE;             \
276             ha.Handler[ht] = (PVOID) (hr);      \
277         } while(0)
278
279 //
280 // KSock Internal Structures
281 //
282
283 typedef struct _KS_ADDRESS {
284
285     union {
286         TRANSPORT_ADDRESS   Tdi;
287         UCHAR               Pading[MAX_ADDRESS_LENGTH];
288     };
289
290     HANDLE                  Handle;
291     PFILE_OBJECT            FileObject;
292
293 } KS_ADDRESS, *PKS_ADDRESS;
294
295 //
296 // Structures for Disconnect Workitem
297 //
298
299 typedef struct _KS_DISCONNECT_WORKITEM {
300
301     WORK_QUEUE_ITEM         WorkItem;       // Workitem to perform disconnection
302     ksock_tconn_t *         tconn;          // tdi connecton
303     ULONG                   Flags;          // connection broken/discnnection flags
304     KEVENT                  Event;          // sync event
305
306 } KS_DISCONNECT_WORKITEM, *PKS_DISCONNECT_WORKITEM;
307
308
309 typedef struct _KS_CONNECTION {
310
311     HANDLE                      Handle;     // Handle of the tdi connection
312     PFILE_OBJECT                FileObject; // FileObject if the conn object
313
314     PTRANSPORT_ADDRESS          Remote;     // the ConnectionInfo of this connection
315     PTDI_CONNECTION_INFORMATION ConnectionInfo;
316
317     ULONG                       nagle;      // Tcp options 
318
319 } KS_CONNECTION, *PKS_CONNECTION;
320
321
322 //
323 // type definitions
324 //
325
326 typedef MDL                         ksock_mdl_t;
327 typedef UNICODE_STRING              ksock_unicode_name_t;
328 typedef WORK_QUEUE_ITEM             ksock_workitem_t;
329
330
331 typedef KS_CHAIN                    ksock_chain_t;
332 typedef KS_ADDRESS                  ksock_tdi_addr_t;
333 typedef KS_CONNECTION               ksock_tconn_info_t;
334 typedef KS_DISCONNECT_WORKITEM      ksock_disconnect_workitem_t;
335
336
337 //
338 // Structures for transmission done Workitem
339 //
340
341 typedef struct _KS_TCPX_FINILIZE {
342     ksock_workitem_t        item;
343     void *                  tx;
344 } ksock_tcpx_fini_t;
345
346
347 typedef struct ksock_backlogs {
348
349         struct list_head    list;   /* list to link the backlog connections */
350         int                 num;    /* number of backlogs in the list */
351
352 } ksock_backlogs_t;
353
354
355 typedef struct ksock_daemon {
356
357     ksock_tconn_t *         tconn;         /* the listener connection object */
358     unsigned short          nbacklogs;     /* number of listening backlog conns */
359     unsigned short          port;          /* listening port number */ 
360     int                     shutdown;      /* daemon threads is to exit */
361     struct list_head        list;          /* to be attached into ksock_nal_data_t*/
362
363 } ksock_daemon_t ;
364
365
366 typedef enum {
367
368     kstt_sender = 0,    // normal sending connection type, it's active connection, while
369                         // child tconn is for passive connection.
370
371     kstt_listener,      // listener daemon type, it just acts as a daemon, and it does
372                         // not have real connection. It manages children tcons to accept
373                         // or refuse the connecting request from remote peers.
374
375     kstt_child,         // accepted child connection type, it's parent must be Listener
376     kstt_lasttype
377 } ksock_tconn_type;
378
379 typedef enum {
380
381     ksts_uninited = 0,  // tconn is just allocated (zero values), not initialized yet
382
383     ksts_inited,        // tconn structure initialized: so it now can be identified as
384                         // a sender, listener or a child
385
386     ksts_bind,          // tconn is bound: the local address object (ip/port) is created.
387                         // after being bound, we must call ksocknal_put_tconn to release
388                         // the tconn objects, it's not safe just to free the memory of tconn.
389
390     ksts_associated,    // the connection object is created and associated with the address
391                         // object. so it's ready for connection. only for child and sender.
392
393     ksts_connecting,    // only used by child tconn: in the ConnectEvent handler routine,
394                         // it indicts the child tconn is busy to be connected to the peer.
395
396     ksts_connected,     // the connection is built already: for sender and child
397
398     ksts_listening,     // listener daemon is working, only for listener tconn
399
400     ksts_disconnected,  // disconnected by user
401     ksts_aborted,       // un-exptected broken status
402
403     ksts_last           // total number of tconn statuses
404 } ksock_tconn_state;
405
406 #define KS_TCONN_MAGIC              'KSTM'
407
408 #define KS_TCONN_HANDLERS_SET       0x00000001  // Conection handlers are set.
409 #define KS_TCONN_DISCONNECT_BUSY    0x00010000  // Disconnect Workitem is queued ...
410 #define KS_TCONN_DESTROY_BUSY       0x00020000  // Destory Workitem is queued ...
411
412 #define KS_TCONN_DAEMON_STARTED     0x00100000  // indict the daemon is started,
413                                                 // only valid for listener
414
415 struct socket {
416
417         ulong_ptr                   kstc_magic;      /* Magic & Flags */
418         ulong_ptr                   kstc_flags;
419
420         spinlock_t                  kstc_lock;       /* serialise lock*/
421         void *                      kstc_conn;       /* ksock_conn_t */
422
423         ksock_tconn_type            kstc_type;           /* tdi connection Type */
424         ksock_tconn_state           kstc_state;      /* tdi connection state flag */
425
426         ksock_unicode_name_t        kstc_dev;        /* tcp transport device name */
427
428         ksock_tdi_addr_t            kstc_addr;       /* local address handlers / Objects */
429
430         atomic_t                    kstc_refcount;   /* reference count of ksock_tconn */
431
432         struct list_head            kstc_list;       /* linked to global ksocknal_data */
433
434         union {
435
436             struct {
437                 int                 nbacklog;         /* total number of backlog tdi connections */
438                 ksock_backlogs_t    kstc_listening;   /* listeing backlog child connections */
439                 ksock_backlogs_t    kstc_accepted;    /* connected backlog child connections */
440                 event_t             kstc_accept_event;   /* Signaled by AcceptedHander, 
441                                                             ksocknal_wait_accpeted_conns waits on */
442                 event_t             kstc_destroy_event;  /* Signaled when accepted child is released */
443             } listener; 
444
445             struct  {
446                 ksock_tconn_info_t  kstc_info;      /* Connection Info if Connected */
447                 ksock_chain_t       kstc_recv;      /* tsdu engine for data receiving */
448                 ksock_chain_t       kstc_send;      /* tsdu engine for data sending */
449
450                 int                 kstc_queued;    /* Attached to Parent->ChildList ... */
451                 int                 kstc_queueno;   /* 0: Attached to Listening list 
452                                                        1: Attached to Accepted list */
453
454                 int                 kstc_busy;      /* referred by ConnectEventCallback ? */
455                 int                 kstc_accepted;  /* the connection is built ready ? */
456
457                 struct list_head    kstc_link;      /* linked to parent tdi connection */
458                 ksock_tconn_t   *   kstc_parent;    /* pointers to it's listener parent */
459             } child;
460
461             struct {
462                 ksock_tconn_info_t  kstc_info;      /* Connection Info if Connected */
463                 ksock_chain_t       kstc_recv;      /* tsdu engine for data receiving */
464                 ksock_chain_t       kstc_send;      /* tsdu engine for data sending */
465             } sender; 
466         };
467
468         ulong_ptr                   kstc_snd_wnd;   /* Sending window size */
469         ulong_ptr                   kstc_rcv_wnd;   /* Recving window size */
470
471         ksock_workitem_t            kstc_destroy;    /* tconn destruction workitem */
472         ksock_disconnect_workitem_t kstc_disconnect; /* connection disconnect workitem */
473
474         ksock_schedule_cb           kstc_sched_cb;   /* notification callback routine of completion */
475         ksock_update_tx             kstc_update_tx;  /* aync sending callback to update tx */
476 };
477
478 #define SOCK_WMEM_QUEUED(sock) (0)
479
480 #define TDINAL_WINDOW_DEFAULT_SIZE  (0x100000)
481
482
483 struct _KS_UDP_COMPLETION_CONTEXT;
484 struct _KS_TCP_COMPLETION_CONTEXT;
485
486
487 typedef
488 NTSTATUS
489 (*PKS_UDP_COMPLETION_ROUTINE) (
490     IN PIRP     Irp,
491     IN struct _KS_UDP_COMPLETION_CONTEXT
492                 *UdpContext
493     );
494
495
496 typedef
497 NTSTATUS
498 (*PKS_TCP_COMPLETION_ROUTINE) (
499     IN PIRP     Irp,
500     IN struct _KS_TCP_COMPLETION_CONTEXT
501                 *TcpContext
502     );
503
504 //
505 // Udp Irp Completion Context
506 //
507
508 typedef struct _KS_UDP_COMPLETION_CONTEXT {
509
510     PKEVENT                             Event;
511     union {
512         PFILE_OBJECT                    AddressObject;
513         ksock_tconn_t *                 tconn;
514     };
515
516     PKS_UDP_COMPLETION_ROUTINE          CompletionRoutine;
517     PVOID                               CompletionContext;
518
519 } KS_UDP_COMPLETION_CONTEXT, *PKS_UDP_COMPLETION_CONTEXT;
520
521
522 //
523 // Tcp Irp Completion Context (used by tcp data recv/send)
524 //
525
526 typedef struct _KS_TCP_COMPLETION_CONTEXT {
527
528     PKEVENT                             Event;      // Event to be waited on by Irp caller ...
529
530     ksock_tconn_t *                     tconn;      // the tdi connection
531
532     PKS_TCP_COMPLETION_ROUTINE          CompletionRoutine;
533     PVOID                               CompletionContext;
534     PVOID                               CompletionContext2;
535
536     PKS_TSDUMGR                         KsTsduMgr;  // Tsdu buffer manager
537
538     //
539     // These tow new members are for NON_BLOCKING transmission
540     //
541
542     BOOLEAN                                                         bCounted;    // To indict needing refcount to
543                                                      // execute CompetionRoutine
544     ULONG                               ReferCount;  // Refer count of this structure
545
546 } KS_TCP_COMPLETION_CONTEXT, *PKS_TCP_COMPLETION_CONTEXT;
547
548 typedef KS_TCP_COMPLETION_CONTEXT  ksock_tdi_tx_t, ksock_tdi_rx_t;
549
550
551 /*
552  * tdi extensions
553  */
554
555 #define IOCTL_TCP_QUERY_INFORMATION_EX        \
556                         CTL_CODE(FILE_DEVICE_NETWORK, 0, METHOD_NEITHER, FILE_ANY_ACCESS)
557 #define IOCTL_TCP_SET_INFORMATION_EX        \
558                         CTL_CODE(FILE_DEVICE_NETWORK, 1, METHOD_BUFFERED, FILE_WRITE_ACCESS)
559
560
561 #define TcpBuildSetInformationEx(Irp, DevObj, FileObj, CompRoutine, Contxt, Buffer, BufferLen)\
562     {                                                                        \
563         PIO_STACK_LOCATION _IRPSP;                                           \
564         if ( CompRoutine != NULL) {                                          \
565             IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\
566         } else {                                                             \
567             IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE);   \
568         }                                                                    \
569         _IRPSP = IoGetNextIrpStackLocation (Irp);                            \
570         _IRPSP->MajorFunction = IRP_MJ_DEVICE_CONTROL;                       \
571         _IRPSP->DeviceObject = DevObj;                                       \
572         _IRPSP->FileObject = FileObj;                                        \
573         _IRPSP->Parameters.DeviceIoControl.OutputBufferLength = 0;           \
574         _IRPSP->Parameters.DeviceIoControl.InputBufferLength = BufferLen;    \
575         _IRPSP->Parameters.DeviceIoControl.IoControlCode = IOCTL_TCP_SET_INFORMATION_EX;  \
576         Irp->AssociatedIrp.SystemBuffer = Buffer;                            \
577     }
578
579
580 #define TcpBuildQueryInformationEx(Irp, DevObj, FileObj, CompRoutine, Contxt, InBuffer, InLength, OutBuffer, OutLength)\
581     {                                                                        \
582         PIO_STACK_LOCATION _IRPSP;                                           \
583         if ( CompRoutine != NULL) {                                          \
584             IoSetCompletionRoutine( Irp, CompRoutine, Contxt, TRUE, TRUE, TRUE);\
585         } else {                                                             \
586             IoSetCompletionRoutine( Irp, NULL, NULL, FALSE, FALSE, FALSE);   \
587         }                                                                    \
588         _IRPSP = IoGetNextIrpStackLocation (Irp);                            \
589         _IRPSP->MajorFunction = IRP_MJ_DEVICE_CONTROL;                       \
590         _IRPSP->DeviceObject = DevObj;                                       \
591         _IRPSP->FileObject = FileObj;                                        \
592         _IRPSP->Parameters.DeviceIoControl.OutputBufferLength = OutLength;           \
593         _IRPSP->Parameters.DeviceIoControl.InputBufferLength = InLength;    \
594         _IRPSP->Parameters.DeviceIoControl.IoControlCode = IOCTL_TCP_QUERY_INFORMATION_EX;  \
595         _IRPSP->Parameters.DeviceIoControl.Type3InputBuffer = InBuffer;    \
596         Irp->UserBuffer = OutBuffer;                            \
597     }
598
599
600 typedef struct ks_addr_slot {
601     LIST_ENTRY      link;
602     int             up;
603     char            iface[40];
604     __u32           ip_addr;
605     __u32           netmask;
606     UNICODE_STRING  devname;
607     WCHAR           buffer[1];
608 } ks_addr_slot_t;
609
610 typedef struct {
611
612     /*
613      * Tdi client information
614      */
615
616     UNICODE_STRING    ksnd_client_name; /* tdi client module name */
617     HANDLE            ksnd_pnp_handle;  /* the handle for pnp changes */
618
619     spinlock_t        ksnd_addrs_lock;  /* serialize ip address list access */
620     LIST_ENTRY        ksnd_addrs_list;  /* list of the ip addresses */
621     int               ksnd_naddrs;      /* number of the ip addresses */
622
623     /*
624      *  Tdilnd internal defintions
625      */
626
627     int               ksnd_init;            /* initialisation state */
628
629     TDI_PROVIDER_INFO ksnd_provider;    /* tdi tcp/ip provider's information */
630
631     spinlock_t        ksnd_tconn_lock;      /* tdi connections access serialise */
632
633     int               ksnd_ntconns;         /* number of tconns attached in list */
634     struct list_head  ksnd_tconns;          /* tdi connections list */
635     cfs_mem_cache_t * ksnd_tconn_slab;      /* slabs for ksock_tconn_t allocations */
636     event_t           ksnd_tconn_exit;      /* exit event to be signaled by the last tconn */
637
638     spinlock_t        ksnd_tsdu_lock;       /* tsdu access serialise */
639         
640     int               ksnd_ntsdus;          /* number of tsdu buffers allocated */
641     ulong_ptr     ksnd_tsdu_size;       /* the size of a signel tsdu buffer */
642     cfs_mem_cache_t * ksnd_tsdu_slab;       /* slab cache for tsdu buffer allocation */
643
644     int               ksnd_nfreetsdus;      /* number of tsdu buffers in the freed list */
645     struct list_head  ksnd_freetsdus;          /* List of the freed Tsdu buffer. */
646
647     spinlock_t        ksnd_daemon_lock;     /* stabilize daemon ops */
648     int               ksnd_ndaemons;        /* number of listening daemons */
649     struct list_head  ksnd_daemons;         /* listening daemon list */
650     event_t           ksnd_daemon_exit;     /* the last daemon quiting should singal it */
651
652 } ks_data_t;
653
654 int
655 ks_init_tdi_data();
656
657 void
658 ks_fini_tdi_data();
659
660
661 #endif /* __KERNEL__ */
662 #endif /* __LIBCFS_WINNT_TCPIP_H__ */
663
664 /*
665  * Local variables:
666  * c-indentation-style: "K&R"
667  * c-basic-offset: 8
668  * tab-width: 8
669  * fill-column: 80
670  * scroll-step: 1
671  * End:
672  */