Home | History | Annotate | Download | only in hw

Lines Matching refs:Pipe

46 /* Set to 1 to enable the 'zero' pipe type, useful for debugging */
49 /* Set to 1 to enable the 'pingpong' pipe type, useful for debugging */
52 /* Set to 1 to enable the 'throttle' pipe type, useful for debugging */
55 /* Maximum length of pipe service name, in characters (excluding final 0) */
90 APANIC("Too many goldfish pipe services (%d)", count);
94 APANIC("Pipe service name too long: '%s'", pipeName);
129 typedef struct Pipe {
130 struct Pipe* next;
131 struct Pipe* next_waked;
140 } Pipe;
143 static void* pipeConnector_new(Pipe* pipe);
145 static Pipe*
148 Pipe* pipe;
149 ANEW0(pipe);
150 pipe->device = dev;
151 return pipe;
154 static Pipe*
157 Pipe* pipe = pipe_new0(dev);
158 pipe->channel = channel;
159 pipe->opaque = pipeConnector_new(pipe);
160 return pipe;
163 static Pipe**
164 pipe_list_findp_channel( Pipe** list, uint32_t channel )
166 Pipe** pnode = list;
168 Pipe* node = *pnode;
178 static Pipe**
179 pipe_list_findp_opaque( Pipe** list, void* opaque )
181 Pipe** pnode = list;
183 Pipe* node = *pnode;
193 static Pipe**
194 pipe_list_findp_waked( Pipe** list, Pipe* pipe )
196 Pipe** pnode = list;
198 Pipe* node = *pnode;
199 if (node == NULL || node == pipe) {
209 pipe_list_remove_waked( Pipe** list, Pipe* pipe )
211 Pipe** lookup = pipe_list_findp_waked(list, pipe);
212 Pipe* node = *lookup;
221 pipe_save( Pipe* pipe, QEMUFile* file )
223 if (pipe->service == NULL) {
224 /* pipe->service == NULL means we're still using a PipeConnector */
230 qemu_put_string(file, pipe->service->name);
234 qemu_put_be32(file, (unsigned int)pipe->channel);
235 qemu_put_byte(file, (int)pipe->wanted);
236 qemu_put_byte(file, (int)pipe->closed);
239 if (pipe->args != NULL) {
241 qemu_put_string(file, pipe->args);
246 if (pipe->funcs->save) {
247 pipe->funcs->save(pipe->opaque, file);
251 static Pipe*
254 Pipe* pipe;
260 /* Pipe is associated with a service. */
267 D("No QEMU pipe service named '%s'", name);
274 pipe = pipe_new(channel, dev);
275 pipe->wanted = qemu_get_byte(file);
276 pipe->closed = qemu_get_byte(file);
278 pipe->args = qemu_get_string(file);
281 pipe->service = service;
283 pipe->funcs = &service->funcs;
286 if (pipe->funcs->load) {
287 pipe->opaque = pipe->funcs->load(pipe, service ? service->opaque : NULL, pipe->args, file);
288 if (pipe->opaque == NULL) {
289 AFREE(pipe);
293 /* Force-close the pipe on load */
294 pipe->closed = 1;
296 return pipe;
300 pipe_free( Pipe* pipe )
303 if (pipe->funcs->close) {
304 pipe->funcs->close(pipe->opaque);
307 AFREE(pipe->args);
308 AFREE(pipe);
319 * client is going to write the name of the pipe service it wants to
323 Pipe* pipe;
331 pipeConnector_new(Pipe* pipe)
336 pcon->pipe = pipe;
337 pipe->funcs = &pipeConnector_funcs;
356 pcon->pipe->channel,
386 * pipe:<name>
387 * pipe:<name>:<arguments>
394 if (memcmp(pcon->buffer, "pipe:", 5) != 0) {
396 D("%s: Unknown pipe connection: '%s'", __FUNCTION__, pcon->buffer);
409 Pipe* pipe = pcon->pipe;
416 void* peer = svc->funcs.init(pipe, svc->opaque, pipeArgs);
423 pipe->opaque = peer;
424 pipe->service = svc;
425 pipe->funcs = &svc->funcs;
426 pipe->args = ASTRDUP(pipeArgs);
452 pipeConnector_save( void* pipe, QEMUFile* file )
454 PipeConnector* pcon = pipe;
495 /* A simple pipe service that mimics /dev/zero, you can write anything to
598 pingPongPipe_init0( PingPongPipe* pipe, void* hwpipe, void* svcOpaque )
600 pipe->hwpipe = hwpipe;
601 pipe->size = PINGPONG_SIZE;
602 pipe->buffer = malloc(pipe->size);
603 pipe->pos = 0;
604 pipe->count = 0;
632 PingPongPipe* pipe = opaque;
643 while (count > pipe->size - pipe->count) {
644 size_t newsize = pipe->size*2;
645 uint8_t* newbuff = realloc(pipe->buffer, newsize);
646 int wpos = pipe->pos + pipe->count;
650 if (wpos > pipe->size) {
651 wpos -= pipe->size;
652 memcpy(newbuff + pipe->size, newbuff, wpos);
654 pipe->buffer = newbuff;
655 pipe->size = newsize;
660 int avail = pipe->size - pipe->count;
670 int wpos = pipe->pos + pipe->count;
671 if (wpos >= pipe->size) {
672 wpos -= pipe->size;
674 if (wpos + avail <= pipe->size) {
675 memcpy(pipe->buffer + wpos, buff->data, avail);
677 int avail2 = pipe->size - wpos;
678 memcpy(pipe->buffer + wpos, buff->data, avail2);
679 memcpy(pipe->buffer, buff->data + avail2, avail - avail2);
681 pipe->count += avail;
686 if (pipe->count > 0 && (pipe->flags & PIPE_WAKE_READ)) {
687 goldfish_pipe_wake(pipe->hwpipe, PIPE_WAKE_READ);
696 PingPongPipe* pipe = opaque;
700 int avail = pipe->count;
710 int rpos = pipe->pos;
712 if (rpos + avail <= pipe->size) {
713 memcpy(buffers[0].data, pipe->buffer + rpos, avail);
715 int avail2 = pipe->size - rpos;
716 memcpy(buffers[0].data, pipe->buffer + rpos, avail2);
717 memcpy(buffers[0].data + avail2, pipe->buffer, avail - avail2);
719 pipe->count -= avail;
720 pipe->pos += avail;
721 if (pipe->pos >= pipe->size) {
722 pipe->pos -= pipe->size;
730 if (pipe->count < PINGPONG_SIZE && (pipe->flags & PIPE_WAKE_WRITE)) {
731 goldfish_pipe_wake(pipe->hwpipe, PIPE_WAKE_WRITE);
740 PingPongPipe* pipe = opaque;
743 if (pipe->count < pipe->size)
746 if (pipe->count > 0)
755 PingPongPipe* pipe = opaque;
756 pipe->flags |= (unsigned)flags;
798 ThrottlePipe* pipe;
800 ANEW0(pipe);
801 pingPongPipe_init0(&pipe->pingpong, hwpipe, svcOpaque);
802 pipe->timer = qemu_new_timer_ns(vm_clock, throttlePipe_timerFunc, pipe);
804 pipe->sendRate = 1e9 / (500*1024*8);
805 pipe->recvRate = pipe->sendRate;
806 return pipe;
812 ThrottlePipe* pipe = opaque;
814 qemu_del_timer(pipe->timer);
815 qemu_free_timer(pipe->timer);
816 pingPongPipe_close(&pipe->pingpong);
820 throttlePipe_rearm( ThrottlePipe* pipe )
824 DD("%s: sendExpiration=%lld recvExpiration=%lld\n", __FUNCTION__, pipe->sendExpiration, pipe->recvExpiration);
826 if (pipe->sendExpiration) {
827 if (minExpiration == 0 || pipe->sendExpiration < minExpiration)
828 minExpiration = pipe->sendExpiration;
831 if (pipe->recvExpiration) {
832 if (minExpiration == 0 || pipe->recvExpiration < minExpiration)
833 minExpiration = pipe->recvExpiration;
838 qemu_mod_timer(pipe->timer, minExpiration);
845 ThrottlePipe* pipe = opaque;
849 __FUNCTION__, now, pipe->sendExpiration, pipe->recvExpiration);
854 if (pipe->sendExpiration && now > pipe->sendExpiration) {
856 pipe->sendExpiration = 0;
858 if (pipe->recvExpiration && now > pipe->recvExpiration) {
860 pipe->recvExpiration = 0;
862 flags &= pipe->pingpong.flags;
865 goldfish_pipe_wake(pipe->pingpong.hwpipe, flags);
868 throttlePipe_rearm(pipe);
874 ThrottlePipe* pipe = opaque;
877 if (pipe->sendExpiration > 0) {
881 ret = pingPongPipe_sendBuffers(&pipe->pingpong, buffers, numBuffers);
884 pipe->sendExpiration = qemu_get_clock_ns(vm_clock) + ret*pipe->sendRate;
885 throttlePipe_rearm(pipe);
893 ThrottlePipe* pipe = opaque;
896 if (pipe->recvExpiration > 0) {
900 ret = pingPongPipe_recvBuffers(&pipe->pingpong, buffers, numBuffers);
902 pipe->recvExpiration = qemu_get_clock_ns(vm_clock) + ret*pipe->recvRate;
903 throttlePipe_rearm(pipe);
911 ThrottlePipe* pipe = opaque;
912 unsigned ret = pingPongPipe_poll(&pipe->pingpong);
914 if (pipe->sendExpiration > 0)
917 if (pipe->recvExpiration > 0)
926 ThrottlePipe* pipe = opaque;
927 pingPongPipe_wakeOn(&pipe->pingpong, flags);
952 Pipe* pipes;
955 Pipe* signaled_pipes;
969 Pipe** lookup = pipe_list_findp_channel(&dev->pipes, dev->channel);
970 Pipe* pipe = *lookup;
973 /* Check that we're referring a known pipe channel */
974 if (command != PIPE_CMD_OPEN && pipe == NULL) {
979 /* If the pipe is closed by the host, return an error */
980 if (pipe != NULL && pipe->closed && command != PIPE_CMD_CLOSE) {
988 if (pipe != NULL) {
992 pipe = pipe_new(dev->channel, dev);
993 pipe->next = dev->pipes;
994 dev->pipes = pipe;
1001 *lookup = pipe->next;
1002 pipe->next = NULL;
1003 pipe_list_remove_waked(&dev->signaled_pipes, pipe);
1004 pipe_free(pipe);
1008 dev->status = pipe->funcs->poll(pipe->opaque);
1026 dev->status = pipe->funcs->recvBuffers(pipe->opaque, &buffer, 1);
1046 dev->status = pipe->funcs->sendBuffers(pipe->opaque, &buffer, 1);
1054 if ((pipe->wanted & PIPE_WAKE_READ) == 0) {
1055 pipe->wanted |= PIPE_WAKE_READ;
1056 pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
1063 if ((pipe->wanted & PIPE_WAKE_WRITE) == 0) {
1064 pipe->wanted |= PIPE_WAKE_WRITE;
1065 pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
1119 Pipe* pipe = dev->signaled_pipes;
1121 pipe->channel, pipe->wanted);
1122 dev->wakes = pipe->wanted;
1123 pipe->wanted = 0;
1124 dev->signaled_pipes = pipe->next_waked;
1125 pipe->next_waked = NULL;
1130 return pipe->channel;
1161 Pipe* pipe;
1169 /* Count the number of pipe connections */
1171 for ( pipe = dev->pipes; pipe; pipe = pipe->next )
1176 /* Now save each pipe one after the other */
1177 for ( pipe = dev->pipes; pipe; pipe = pipe->next ) {
1178 pipe_save(pipe, file);
1186 Pipe* pipe;
1197 /* Count the number of pipe connections */
1200 /* Load all pipe connections */
1202 pipe = pipe_load(dev, file);
1203 if (pipe == NULL) {
1206 pipe->next = dev->pipes;
1207 dev->pipes = pipe;
1211 for ( pipe = dev->pipes; pipe; pipe = pipe->next ) {
1212 if (pipe->wanted != 0)
1213 goldfish_pipe_wake(pipe, pipe->wanted);
1214 if (pipe->closed != 0)
1215 goldfish_pipe_close(pipe);
1253 Pipe* pipe = hwpipe;
1254 Pipe** lookup;
1255 PipeDevice* dev = pipe->device;
1257 DD("%s: channel=0x%x flags=%d", __FUNCTION__, pipe->channel, flags);
1260 lookup = pipe_list_findp_waked(&dev->signaled_pipes, pipe);
1262 pipe->next_waked = dev->signaled_pipes;
1263 dev->signaled_pipes = pipe;
1265 pipe->wanted |= (unsigned)flags;
1275 Pipe* pipe = hwpipe;
1277 D("%s: channel=0x%x (closed=%d)", __FUNCTION__, pipe->channel, pipe->closed);
1279 if (!pipe->closed) {
1280 pipe->closed = 1;