Home | History | Annotate | Download | only in hw

Lines Matching refs:pipe

44 /* Set to 1 to enable the 'zero' pipe type, useful for debugging */
47 /* Set to 1 to enable the 'pingpong' pipe type, useful for debugging */
50 /* Set to 1 to enable the 'throttle' pipe type, useful for debugging */
53 /* Maximum length of pipe service name, in characters (excluding final 0) */
88 APANIC("Too many goldfish pipe services (%d)", count);
92 APANIC("Pipe service name too long: '%s'", pipeName);
127 typedef struct Pipe {
128 struct Pipe* next;
129 struct Pipe* next_waked;
138 } Pipe;
141 static void* pipeConnector_new(Pipe* pipe);
143 static Pipe*
146 Pipe* pipe;
147 ANEW0(pipe);
148 pipe->device = dev;
149 return pipe;
152 static Pipe*
155 Pipe* pipe = pipe_new0(dev);
156 pipe->channel = channel;
157 pipe->opaque = pipeConnector_new(pipe);
158 return pipe;
161 static Pipe**
162 pipe_list_findp_channel( Pipe** list, uint32_t channel )
164 Pipe** pnode = list;
166 Pipe* node = *pnode;
176 static Pipe**
177 pipe_list_findp_opaque( Pipe** list, void* opaque )
179 Pipe** pnode = list;
181 Pipe* node = *pnode;
191 static Pipe**
192 pipe_list_findp_waked( Pipe** list, Pipe* pipe )
194 Pipe** pnode = list;
196 Pipe* node = *pnode;
197 if (node == NULL || node == pipe) {
207 pipe_list_remove_waked( Pipe** list, Pipe* pipe )
209 Pipe** lookup = pipe_list_findp_waked(list, pipe);
210 Pipe* node = *lookup;
219 pipe_save( Pipe* pipe, QEMUFile* file )
221 if (pipe->service == NULL) {
222 /* pipe->service == NULL means we're still using a PipeConnector */
228 qemu_put_string(file, pipe->service->name);
232 qemu_put_be32(file, (unsigned int)pipe->channel);
233 qemu_put_byte(file, (int)pipe->wanted);
234 qemu_put_byte(file, (int)pipe->closed);
237 if (pipe->args != NULL) {
239 qemu_put_string(file, pipe->args);
244 if (pipe->funcs->save) {
245 pipe->funcs->save(pipe->opaque, file);
249 static Pipe*
252 Pipe* pipe;
258 /* Pipe is associated with a service. */
265 D("No QEMU pipe service named '%s'", name);
272 pipe = pipe_new(channel, dev);
273 pipe->wanted = qemu_get_byte(file);
274 pipe->closed = qemu_get_byte(file);
276 pipe->args = qemu_get_string(file);
279 pipe->service = service;
281 pipe->funcs = &service->funcs;
284 if (pipe->funcs->load) {
285 pipe->opaque = pipe->funcs->load(pipe, service ? service->opaque : NULL, pipe->args, file);
286 if (pipe->opaque == NULL) {
287 AFREE(pipe);
291 /* Force-close the pipe on load */
292 pipe->closed = 1;
294 return pipe;
298 pipe_free( Pipe* pipe )
301 if (pipe->funcs->close) {
302 pipe->funcs->close(pipe->opaque);
305 AFREE(pipe->args);
306 AFREE(pipe);
317 * client is going to write the name of the pipe service it wants to
321 Pipe* pipe;
329 pipeConnector_new(Pipe* pipe)
334 pcon->pipe = pipe;
335 pipe->funcs = &pipeConnector_funcs;
354 pcon->pipe->channel,
384 * pipe:<name>
385 * pipe:<name>:<arguments>
392 if (memcmp(pcon->buffer, "pipe:", 5) != 0) {
394 D("%s: Unknown pipe connection: '%s'", __FUNCTION__, pcon->buffer);
407 Pipe* pipe = pcon->pipe;
414 void* peer = svc->funcs.init(pipe, svc->opaque, pipeArgs);
421 pipe->opaque = peer;
422 pipe->service = svc;
423 pipe->funcs = &svc->funcs;
424 pipe->args = ASTRDUP(pipeArgs);
450 pipeConnector_save( void* pipe, QEMUFile* file )
452 PipeConnector* pcon = pipe;
493 /* A simple pipe service that mimics /dev/zero, you can write anything to
596 pingPongPipe_init0( PingPongPipe* pipe, void* hwpipe, void* svcOpaque )
598 pipe->hwpipe = hwpipe;
599 pipe->size = PINGPONG_SIZE;
600 pipe->buffer = malloc(pipe->size);
601 pipe->pos = 0;
602 pipe->count = 0;
630 PingPongPipe* pipe = opaque;
641 while (count > pipe->size - pipe->count) {
642 size_t newsize = pipe->size*2;
643 uint8_t* newbuff = realloc(pipe->buffer, newsize);
644 int wpos = pipe->pos + pipe->count;
648 if (wpos > pipe->size) {
649 wpos -= pipe->size;
650 memcpy(newbuff + pipe->size, newbuff, wpos);
652 pipe->buffer = newbuff;
653 pipe->size = newsize;
658 pipe->size - pipe->count;
668 int wpos = pipe->pos + pipe->count;
669 if (wpos >= pipe->size) {
670 wpos -= pipe->size;
672 if (wpos + avail <= pipe->size) {
673 memcpy(pipe->buffer + wpos, buff->data, avail);
675 int avail2 = pipe->size - wpos;
676 memcpy(pipe->buffer + wpos, buff->data, avail2);
677 memcpy(pipe->buffer, buff->data + avail2, avail - avail2);
679 pipe->count += avail;
684 if (pipe->count > 0 && (pipe->flags & PIPE_WAKE_READ)) {
685 goldfish_pipe_wake(pipe->hwpipe, PIPE_WAKE_READ);
694 PingPongPipe* pipe = opaque;
698 int avail = pipe->count;
708 int rpos = pipe->pos;
710 if (rpos + avail <= pipe->size) {
711 memcpy(buffers[0].data, pipe->buffer + rpos, avail);
713 int avail2 = pipe->size - rpos;
714 memcpy(buffers[0].data, pipe->buffer + rpos, avail2);
715 memcpy(buffers[0].data + avail2, pipe->buffer, avail - avail2);
717 pipe->count -= avail;
718 pipe->pos += avail;
719 if (pipe->pos >= pipe->size) {
720 pipe->pos -= pipe->size;
728 if (pipe->count < PINGPONG_SIZE && (pipe->flags & PIPE_WAKE_WRITE)) {
729 goldfish_pipe_wake(pipe->hwpipe, PIPE_WAKE_WRITE);
738 PingPongPipe* pipe = opaque;
741 if (pipe->count < pipe->size)
744 if (pipe->count > 0)
753 PingPongPipe* pipe = opaque;
754 pipe->flags |= (unsigned)flags;
796 ThrottlePipe* pipe;
798 ANEW0(pipe);
799 pingPongPipe_init0(&pipe->pingpong, hwpipe, svcOpaque);
800 pipe->timer = qemu_new_timer_ns(vm_clock, throttlePipe_timerFunc, pipe);
802 pipe->sendRate = 1e9 / (500*1024*8);
803 pipe->recvRate = pipe->sendRate;
804 return pipe;
810 ThrottlePipe* pipe = opaque;
812 qemu_del_timer(pipe->timer);
813 qemu_free_timer(pipe->timer);
814 pingPongPipe_close(&pipe->pingpong);
818 throttlePipe_rearm( ThrottlePipe* pipe )
822 DD("%s: sendExpiration=%lld recvExpiration=%lld\n", __FUNCTION__, pipe->sendExpiration, pipe->recvExpiration);
824 if (pipe->sendExpiration) {
825 if (minExpiration == 0 || pipe->sendExpiration < minExpiration)
826 minExpiration = pipe->sendExpiration;
829 if (pipe->recvExpiration) {
830 if (minExpiration == 0 || pipe->recvExpiration < minExpiration)
831 minExpiration = pipe->recvExpiration;
836 qemu_mod_timer(pipe->timer, minExpiration);
843 ThrottlePipe* pipe = opaque;
847 __FUNCTION__, now, pipe->sendExpiration, pipe->recvExpiration);
852 if (pipe->sendExpiration && now > pipe->sendExpiration) {
854 pipe->sendExpiration = 0;
856 if (pipe->recvExpiration && now > pipe->recvExpiration) {
858 pipe->recvExpiration = 0;
860 flags &= pipe->pingpong.flags;
863 goldfish_pipe_wake(pipe->pingpong.hwpipe, flags);
866 throttlePipe_rearm(pipe);
872 ThrottlePipe* pipe = opaque;
875 if (pipe->sendExpiration > 0) {
879 ret = pingPongPipe_sendBuffers(&pipe->pingpong, buffers, numBuffers);
882 pipe->sendExpiration = qemu_get_clock_ns(vm_clock) + ret*pipe->sendRate;
883 throttlePipe_rearm(pipe);
891 ThrottlePipe* pipe = opaque;
894 if (pipe->recvExpiration > 0) {
898 ret = pingPongPipe_recvBuffers(&pipe->pingpong, buffers, numBuffers);
900 pipe->recvExpiration = qemu_get_clock_ns(vm_clock) + ret*pipe->recvRate;
901 throttlePipe_rearm(pipe);
909 ThrottlePipe* pipe = opaque;
910 unsigned ret = pingPongPipe_poll(&pipe->pingpong);
912 if (pipe->sendExpiration > 0)
915 if (pipe->recvExpiration > 0)
924 ThrottlePipe* pipe = opaque;
925 pingPongPipe_wakeOn(&pipe->pingpong, flags);
950 Pipe* pipes;
953 Pipe* signaled_pipes;
967 Pipe** lookup = pipe_list_findp_channel(&dev->pipes, dev->channel);
968 Pipe* pipe = *lookup;
971 /* Check that we're referring a known pipe channel */
972 if (command != PIPE_CMD_OPEN && pipe == NULL) {
977 /* If the pipe is closed by the host, return an error */
978 if (pipe != NULL && pipe->closed && command != PIPE_CMD_CLOSE) {
986 if (pipe != NULL) {
990 pipe = pipe_new(dev->channel, dev);
991 pipe->next = dev->pipes;
992 dev->pipes = pipe;
999 *lookup = pipe->next;
1000 pipe->next = NULL;
1001 pipe_list_remove_waked(&dev->signaled_pipes, pipe);
1002 pipe_free(pipe);
1006 dev->status = pipe->funcs->poll(pipe->opaque);
1019 dev->status = pipe->funcs->recvBuffers(pipe->opaque, &buffer, 1);
1034 dev->status = pipe->funcs->sendBuffers(pipe->opaque, &buffer, 1);
1042 if ((pipe->wanted & PIPE_WAKE_READ) == 0) {
1043 pipe->wanted |= PIPE_WAKE_READ;
1044 pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
1051 if ((pipe->wanted & PIPE_WAKE_WRITE) == 0) {
1052 pipe->wanted |= PIPE_WAKE_WRITE;
1053 pipe->funcs->wakeOn(pipe->opaque, pipe->wanted);
1109 /* sync pipe device state from batch buffer */
1143 Pipe* pipe = dev->signaled_pipes;
1145 pipe->channel, pipe->wanted);
1146 dev->wakes = pipe->wanted;
1147 pipe->wanted = 0;
1148 dev->signaled_pipes = pipe->next_waked;
1149 pipe->next_waked = NULL;
1154 return pipe->channel;
1191 Pipe* pipe;
1200 /* Count the number of pipe connections */
1202 for ( pipe = dev->pipes; pipe; pipe = pipe->next )
1207 /* Now save each pipe one after the other */
1208 for ( pipe = dev->pipes; pipe; pipe = pipe->next ) {
1209 pipe_save(pipe, file);
1217 Pipe* pipe;
1229 /* Count the number of pipe connections */
1232 /* Load all pipe connections */
1234 pipe = pipe_load(dev, file);
1235 if (pipe == NULL) {
1238 pipe->next = dev->pipes;
1239 dev->pipes = pipe;
1243 for ( pipe = dev->pipes; pipe; pipe = pipe->next ) {
1244 if (pipe->wanted != 0)
1245 pipe, pipe->wanted);
1246 if (pipe->closed != 0)
1247 goldfish_pipe_close(pipe);
1285 Pipe* pipe = hwpipe;
1286 Pipe** lookup;
1287 PipeDevice* dev = pipe->device;
1289 DD("%s: channel=0x%x flags=%d", __FUNCTION__, pipe->channel, flags);
1292 lookup = pipe_list_findp_waked(&dev->signaled_pipes, pipe);
1294 pipe->next_waked = dev->signaled_pipes;
1295 dev->signaled_pipes = pipe;
1297 pipe->wanted |= (unsigned)flags;
1307 Pipe* pipe = hwpipe;
1309 D("%s: channel=0x%x (closed=%d)", __FUNCTION__, pipe->channel, pipe->closed);
1311 if (!pipe->closed) {
1312 pipe->closed = 1;