2 * Server-side serial port communications management
4 * Copyright (C) 1998 Alexandre Julliard
5 * Copyright (C) 2000,2001 Mike McCormack
17 #ifdef HAVE_SYS_ERRNO_H
18 #include <sys/errno.h>
21 #include <sys/types.h>
26 #include <sys/ioctl.h>
36 static void serial_dump( struct object
*obj
, int verbose
);
37 static int serial_get_fd( struct object
*obj
);
38 static int serial_get_info( struct object
*obj
, struct get_file_info_reply
*reply
);
39 static int serial_get_poll_events( struct object
*obj
);
40 static struct async_queue
* serial_queue_async(struct object
*obj
, struct async
* async
, int type
, int count
);
41 static void destroy_serial(struct object
*obj
);
42 static void serial_poll_event( struct object
*obj
, int event
);
51 unsigned int readinterval
;
52 unsigned int readconst
;
53 unsigned int readmult
;
54 unsigned int writeconst
;
55 unsigned int writemult
;
57 unsigned int eventmask
;
58 unsigned int commerror
;
60 struct termios original
;
62 struct async_queue read_q
;
63 struct async_queue write_q
;
64 struct async_queue wait_q
;
66 /* FIXME: add dcb, comm status, handler module, sharing */
69 static const struct object_ops serial_ops
=
71 sizeof(struct serial
), /* size */
72 serial_dump
, /* dump */
73 default_poll_add_queue
, /* add_queue */
74 default_poll_remove_queue
, /* remove_queue */
75 default_poll_signaled
, /* signaled */
76 no_satisfied
, /* satisfied */
77 serial_get_poll_events
, /* get_poll_events */
78 serial_poll_event
, /* poll_event */
79 serial_get_fd
, /* get_fd */
81 serial_get_info
, /* get_file_info */
82 serial_queue_async
, /* queue_async */
83 destroy_serial
/* destroy */
86 static struct serial
*create_serial( const char *nameptr
, size_t len
, unsigned int access
, int attributes
)
88 struct serial
*serial
;
93 if (!(name
= mem_alloc( len
+ 1 ))) return NULL
;
94 memcpy( name
, nameptr
, len
);
97 switch(access
& (GENERIC_READ
| GENERIC_WRITE
))
99 case GENERIC_READ
: flags
|= O_RDONLY
; break;
100 case GENERIC_WRITE
: flags
|= O_WRONLY
; break;
101 case GENERIC_READ
|GENERIC_WRITE
: flags
|= O_RDWR
; break;
107 fd
= open( name
, flags
);
115 /* check its really a serial port */
116 if (tcgetattr(fd
,&tios
))
123 /* set the fd back to blocking if necessary */
124 if( ! (attributes
& FILE_FLAG_OVERLAPPED
) )
125 if(0>fcntl(fd
, F_SETFL
, 0))
128 if ((serial
= alloc_object( &serial_ops
, fd
)))
130 serial
->attrib
= attributes
;
131 serial
->access
= access
;
132 serial
->readinterval
= 0;
133 serial
->readmult
= 0;
134 serial
->readconst
= 0;
135 serial
->writemult
= 0;
136 serial
->writeconst
= 0;
137 serial
->eventmask
= 0;
138 serial
->commerror
= 0;
139 init_async_queue(&serial
->read_q
);
140 init_async_queue(&serial
->write_q
);
141 init_async_queue(&serial
->wait_q
);
146 static void destroy_serial( struct object
*obj
)
148 struct serial
*serial
= (struct serial
*)obj
;
150 destroy_async_queue(&serial
->read_q
);
151 destroy_async_queue(&serial
->write_q
);
152 destroy_async_queue(&serial
->wait_q
);
155 static void serial_dump( struct object
*obj
, int verbose
)
157 struct serial
*serial
= (struct serial
*)obj
;
158 assert( obj
->ops
== &serial_ops
);
159 fprintf( stderr
, "Port fd=%d mask=%x\n", serial
->obj
.fd
, serial
->eventmask
);
162 struct serial
*get_serial_obj( struct process
*process
, handle_t handle
, unsigned int access
)
164 return (struct serial
*)get_handle_obj( process
, handle
, access
, &serial_ops
);
167 static int serial_get_poll_events( struct object
*obj
)
169 struct serial
*serial
= (struct serial
*)obj
;
171 assert( obj
->ops
== &serial_ops
);
173 if(IS_READY(serial
->read_q
))
175 if(IS_READY(serial
->write_q
))
177 if(IS_READY(serial
->wait_q
))
180 /* fprintf(stderr,"poll events are %04x\n",events); */
185 static int serial_get_fd( struct object
*obj
)
187 struct serial
*serial
= (struct serial
*)obj
;
188 assert( obj
->ops
== &serial_ops
);
189 return serial
->obj
.fd
;
192 static int serial_get_info( struct object
*obj
, struct get_file_info_reply
*reply
)
194 struct serial
*serial
= (struct serial
*) obj
;
195 assert( obj
->ops
== &serial_ops
);
199 reply
->type
= FILE_TYPE_CHAR
;
201 reply
->access_time
= 0;
202 reply
->write_time
= 0;
203 reply
->size_high
= 0;
206 reply
->index_high
= 0;
207 reply
->index_low
= 0;
211 if(serial
->attrib
& FILE_FLAG_OVERLAPPED
)
212 return FD_TYPE_OVERLAPPED
;
214 return FD_TYPE_TIMEOUT
;
217 static void serial_poll_event(struct object
*obj
, int event
)
219 struct serial
*serial
= (struct serial
*)obj
;
221 /* fprintf(stderr,"Poll event %02x\n",event); */
223 if(IS_READY(serial
->read_q
) && (POLLIN
& event
) )
224 async_notify(serial
->read_q
.head
,STATUS_ALERTED
);
226 if(IS_READY(serial
->write_q
) && (POLLOUT
& event
) )
227 async_notify(serial
->write_q
.head
,STATUS_ALERTED
);
229 if(IS_READY(serial
->wait_q
) && (POLLIN
& event
) )
230 async_notify(serial
->wait_q
.head
,STATUS_ALERTED
);
232 set_select_events(obj
,obj
->ops
->get_poll_events(obj
));
236 * This function is an abuse of overloading that deserves some explanation.
238 * It has three purposes:
240 * 1. get the queue for a type of async operation
241 * 2. requeue an async operation
242 * 3. queue a new async operation
244 * It is overloaded so that these three functions only take one function pointer
245 * in the object operations list.
247 * In all cases, it returns the async queue.
249 static struct async_queue
*serial_queue_async(struct object
*obj
, struct async
*async
, int type
, int count
)
251 struct serial
*serial
= (struct serial
*)obj
;
252 struct async_queue
*q
;
255 assert(obj
->ops
== &serial_ops
);
259 case ASYNC_TYPE_READ
:
261 timeout
= serial
->readconst
+ serial
->readmult
*count
;
263 case ASYNC_TYPE_WAIT
:
267 case ASYNC_TYPE_WRITE
:
268 q
= &serial
->write_q
;
269 timeout
= serial
->writeconst
+ serial
->writemult
*count
;
272 set_error(STATUS_INVALID_PARAMETER
);
280 async_add_timeout(async
,timeout
);
281 async_insert(q
, async
);
288 /* create a serial */
289 DECL_HANDLER(create_serial
)
291 struct serial
*serial
;
294 if ((serial
= create_serial( get_req_data(), get_req_data_size(), req
->access
, req
->attributes
)))
296 reply
->handle
= alloc_handle( current
->process
, serial
, req
->access
, req
->inherit
);
297 release_object( serial
);
301 DECL_HANDLER(get_serial_info
)
303 struct serial
*serial
;
305 if ((serial
= get_serial_obj( current
->process
, req
->handle
, 0 )))
308 reply
->readinterval
= serial
->readinterval
;
309 reply
->readconst
= serial
->readconst
;
310 reply
->readmult
= serial
->readmult
;
311 reply
->writeconst
= serial
->writeconst
;
312 reply
->writemult
= serial
->writemult
;
315 reply
->eventmask
= serial
->eventmask
;
317 /* comm port error status */
318 reply
->commerror
= serial
->commerror
;
320 release_object( serial
);
324 DECL_HANDLER(set_serial_info
)
326 struct serial
*serial
;
328 if ((serial
= get_serial_obj( current
->process
, req
->handle
, 0 )))
331 if(req
->flags
& SERIALINFO_SET_TIMEOUTS
)
333 serial
->readinterval
= req
->readinterval
;
334 serial
->readconst
= req
->readconst
;
335 serial
->readmult
= req
->readmult
;
336 serial
->writeconst
= req
->writeconst
;
337 serial
->writemult
= req
->writemult
;
341 if(req
->flags
& SERIALINFO_SET_MASK
)
343 serial
->eventmask
= req
->eventmask
;
346 /* comm port error status */
347 if(req
->flags
& SERIALINFO_SET_ERROR
)
349 serial
->commerror
= req
->commerror
;
352 release_object( serial
);