-/*\r
- * mainloop_evhandle.c\r
- *\r
- * Copyright (C) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
- *\r
- * Contact:\r
- * DoHyung Hong <don.hong@samsung.com>\r
- *\r
- * This program is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU General Public License\r
- * as published by the Free Software Foundation; either version 2\r
- * of the License, or (at your option) any later version.\r
- *\r
- * This program is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
- * GNU General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU General Public License\r
- * along with this program; if not, write to the Free Software\r
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
- * Contributors:\r
- * - S-Core Co., Ltd\r
- *\r
- */\r
-\r
-\r
-#ifdef _WIN32\r
-#include <winsock.h>\r
-#define socklen_t int\r
-#else\r
-#include <netinet/in.h>\r
-#include <sys/ioctl.h>\r
-#endif\r
-\r
-#include "qobject.h"\r
-#include "qemu-common.h"\r
-#include "hw/usb.h"\r
-#include "hw/irq.h"\r
-#include "mloop_event.h"\r
-\r
-#define error_report(x, ...)\r
-\r
-struct mloop_evsock {\r
- int sockno;\r
- unsigned short portno;\r
- unsigned char status;\r
-};\r
-\r
-#define MLOOP_EVSOCK_NULL 0\r
-#define MLOOP_EVSOCK_CREATED 1\r
-#define MLOOP_EVSOCK_NOTBOUND 2\r
-#define MLOOP_EVSOCK_BOUND 3\r
-#define MLOOP_EVSOCK_CONNECTED 4\r
-\r
-#define PACKET_LEN 512\r
-struct mloop_evpack {\r
- short type;\r
- short size;\r
- char data[PACKET_LEN-4];\r
-};\r
-\r
-#define MLOOP_EVTYPE_USB_ADD 1\r
-#define MLOOP_EVTYPE_USB_DEL 2\r
-#define MLOOP_EVTYPE_INTR_UP 3\r
-#define MLOOP_EVTYPE_INTR_DOWN 4\r
-\r
-static struct mloop_evsock mloop = {-1,0,0};\r
-\r
-static int mloop_evsock_create(struct mloop_evsock *ev)\r
-{\r
- struct sockaddr sa;\r
- socklen_t sa_size;\r
- int ret;\r
- unsigned long nonblock = 1;\r
-\r
- if (ev == NULL) {\r
- error_report("mloop_evsock: null point");\r
- return -1;\r
- }\r
-\r
- ev->sockno = socket(AF_INET, SOCK_DGRAM, 0);\r
- if( ev->sockno == -1 ) {\r
- error_report("mloop_evsock: socket() failed");\r
- return -1;\r
- }\r
-\r
-#ifdef _WIN32\r
- ioctlsocket(ev->sockno, FIONBIO, &nonblock );\r
-#else\r
- ioctl(ev->sockno, FIONBIO, &nonblock);\r
-#endif // _WIN32\r
-\r
- nonblock = 1 ;\r
- setsockopt( ev->sockno, SOL_SOCKET, SO_REUSEADDR, (char *)&nonblock, sizeof(nonblock) ) ;\r
-\r
- memset(&sa, '\0', sizeof(sa));\r
- ((struct sockaddr_in *) &sa)->sin_family = AF_INET;\r
- memcpy(&((struct sockaddr_in *) &sa)->sin_addr, "\177\000\000\001", 4); // 127.0.0.1\r
- ((struct sockaddr_in *) &sa)->sin_port = htons(ev->portno);\r
- sa_size = sizeof(struct sockaddr_in);\r
-\r
- ret = bind(ev->sockno, &sa, sa_size);\r
- if (ret) {\r
- error_report("mloop_evsock: bind() failed");\r
- goto mloop_evsock_init_cleanup;\r
- }\r
-\r
- if (ev->portno == 0) {\r
- memset(&sa, '\0', sizeof(sa));\r
- getsockname(ev->sockno, (struct sockaddr *) &sa, &sa_size);\r
- ev->portno = ntohs(((struct sockaddr_in *) &sa)->sin_port);\r
- }\r
-\r
- ret = connect(ev->sockno, (struct sockaddr *) &sa, sa_size);\r
- if (ret) {\r
- error_report("mloop_evsock: connect() failed");\r
- goto mloop_evsock_init_cleanup;\r
- }\r
-\r
- ev->status = MLOOP_EVSOCK_CONNECTED;\r
- return 0;\r
-\r
-mloop_evsock_init_cleanup:\r
-#ifdef _WIN32\r
- closesocket(ev->sockno);\r
-#else\r
- close(ev->sockno);\r
-#endif\r
- ev->sockno = -1;\r
- ev->status = 0;\r
- return ret;\r
-}\r
-\r
-static void mloop_evsock_remove(struct mloop_evsock *ev)\r
-{\r
- if (!ev) {\r
- return ;\r
- }\r
-\r
- if (ev->sockno > 0) {\r
-#ifdef _WIN32\r
- shutdown(ev->sockno, SD_BOTH);\r
- closesocket(ev->sockno);\r
-#else\r
- shutdown(ev->sockno, SHUT_RDWR);\r
- close(ev->sockno);\r
-#endif\r
- ev->sockno = -1;\r
- ev->status = 0;\r
- }\r
-}\r
-\r
-static int mloop_evsock_send(struct mloop_evsock *ev, struct mloop_evpack *p)\r
-{\r
- int ret;\r
-\r
- if (ev == NULL || ev->sockno == -1) {\r
- error_report("invalid mloop_evsock");\r
- return -1;\r
- }\r
-\r
- if (p == NULL || p->size <= 0) {\r
- error_report("invalid mloop_evpack");\r
- return -1;\r
- }\r
-\r
- do {\r
- ret = send(ev->sockno, p, ntohs(p->size), 0);\r
-#ifdef _WIN32\r
- } while (ret == -1 && (WSAGetLastError() == WSAEWOULDBLOCK));\r
-#else\r
- } while (ret == -1 && (errno == EWOULDBLOCK || errno == EINTR));\r
-#endif // _WIN32\r
-\r
- return ret;\r
-}\r
-\r
-static USBDevice *usbkbd = NULL;\r
-static USBDevice *usbdisk = NULL;\r
-static void mloop_evhandle_usb_add(char *name)\r
-{\r
- if (name == NULL) {\r
- return;\r
- }\r
-\r
- if (strcmp(name, "keyboard") == 0) {\r
- if (usbkbd == NULL) {\r
- usbkbd = usbdevice_create(name);\r
- }\r
- else if (usbkbd->attached == 0) {\r
- usb_device_attach(usbkbd);\r
- }\r
- }\r
- else if (strncmp(name, "disk:", 5) == 0) {\r
- if (usbdisk == NULL) {\r
- usbdisk = usbdevice_create(name);\r
- }\r
- }\r
-}\r
-\r
-static void mloop_evhandle_usb_del(char *name)\r
-{\r
- if (name == NULL) {\r
- return;\r
- }\r
-\r
- if (strcmp(name, "keyboard") == 0) {\r
- if (usbkbd && usbkbd->attached != 0) {\r
- usb_device_detach(usbkbd);\r
- }\r
- }\r
- else if (strncmp(name, "disk:", 5) == 0) {\r
- if (usbdisk) {\r
- qdev_free(&usbdisk->qdev);\r
- }\r
- }\r
-}\r
-\r
-static void mloop_evhandle_intr_up(long data)\r
-{\r
- if (data == 0) {\r
- return;\r
- }\r
-\r
- qemu_irq_raise((qemu_irq)data);\r
-}\r
-\r
-static void mloop_evhandle_intr_down(long data)\r
-{\r
- if (data == 0) {\r
- return;\r
- }\r
-\r
- qemu_irq_lower((qemu_irq)data);\r
-}\r
-\r
-static void mloop_evcb_recv(struct mloop_evsock *ev)\r
-{\r
- struct mloop_evpack pack;\r
- int ret;\r
-\r
- do {\r
- ret = recv(ev->sockno, (void *)&pack, sizeof(pack), 0);\r
-#ifdef _WIN32\r
- } while (ret == -1 && WSAGetLastError() == WSAEINTR);\r
-#else\r
- } while (ret == -1 && errno == EINTR);\r
-#endif // _WIN32\r
-\r
- if (ret == -1 ) {\r
- return;\r
- }\r
-\r
- if (ret == 0 ) {\r
- return;\r
- }\r
-\r
- pack.type = ntohs(pack.type);\r
- pack.size = ntohs(pack.size);\r
-\r
- switch (pack.type) {\r
- case MLOOP_EVTYPE_USB_ADD:\r
- mloop_evhandle_usb_add(pack.data);\r
- break;\r
- case MLOOP_EVTYPE_USB_DEL:\r
- mloop_evhandle_usb_del(pack.data);\r
- break;\r
- case MLOOP_EVTYPE_INTR_UP:\r
- mloop_evhandle_intr_up(ntohl(*(long*)&pack.data[0]));\r
- break;\r
- case MLOOP_EVTYPE_INTR_DOWN:\r
- mloop_evhandle_intr_down(ntohl(*(long*)&pack.data[0]));\r
- break;\r
- default:\r
- break;\r
- }\r
-}\r
-\r
-void mloop_ev_init(void)\r
-{\r
- int ret = mloop_evsock_create(&mloop);\r
- if (ret == 0) {\r
- qemu_set_fd_handler(mloop.sockno, (IOHandler *)mloop_evcb_recv, NULL, &mloop);\r
- }\r
-}\r
-\r
-void mloop_ev_stop(void)\r
-{\r
- qemu_set_fd_handler(mloop.sockno, NULL, NULL, NULL);\r
- mloop_evsock_remove(&mloop);\r
-}\r
-\r
-void mloop_evcmd_usbkbd(int on)\r
-{\r
- struct mloop_evpack pack = { htons(MLOOP_EVTYPE_USB_ADD), htons(13), "keyboard" };\r
- if (on == 0)\r
- pack.type = htons(MLOOP_EVTYPE_USB_DEL);\r
- mloop_evsock_send(&mloop, &pack);\r
-}\r
-\r
-void mloop_evcmd_usbdisk(char *img)\r
-{\r
- struct mloop_evpack pack;\r
-\r
- if (img) {\r
- if (strlen(img) > PACKET_LEN-5) {\r
- // Need log\r
- return;\r
- }\r
-\r
- pack.type = htons(MLOOP_EVTYPE_USB_ADD);\r
- pack.size = htons(5 + sprintf(pack.data, "disk:%s", img));\r
- }\r
- else {\r
- pack.type = htons(MLOOP_EVTYPE_USB_DEL);\r
- pack.size = htons(5 + sprintf(pack.data, "disk:"));\r
- }\r
-\r
- mloop_evsock_send(&mloop, &pack);\r
-}\r
-\r
-int mloop_evcmd_get_usbkbd_status(void)\r
-{\r
- return (usbkbd && usbkbd->attached ? 1 : 0);\r
-}\r
-\r
-void mloop_evcmd_set_usbkbd(void *dev)\r
-{\r
- usbkbd = (USBDevice *)dev;\r
-}\r
-\r
-void mloop_evcmd_set_usbdisk(void *dev)\r
-{\r
- usbdisk = (USBDevice *)dev;\r
-}\r
-\r
-void mloop_evcmd_raise_intr(void *irq)\r
-{\r
- struct mloop_evpack pack;\r
- memset((void*)&pack, 0, sizeof(struct mloop_evpack));\r
- pack.type = htons(MLOOP_EVTYPE_INTR_UP);\r
- pack.size = htons(8);\r
- *(long*)&pack.data[0] = htonl((long)irq);\r
- mloop_evsock_send(&mloop, &pack);\r
-}\r
-\r
-void mloop_evcmd_lower_intr(void *irq)\r
-{\r
- struct mloop_evpack pack;\r
- memset((void*)&pack, 0, sizeof(struct mloop_evpack));\r
- pack.type = htons(MLOOP_EVTYPE_INTR_DOWN);\r
- pack.size = htons(8);\r
- *(long*)&pack.data[0] = htonl((long)irq);\r
- mloop_evsock_send(&mloop, &pack);\r
-}\r
+/*
+ * mainloop_evhandle.c
+ *
+ * Copyright (C) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact:
+ * DoHyung Hong <don.hong@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributors:
+ * - S-Core Co., Ltd
+ *
+ */
+
+
+#ifdef _WIN32
+#include <winsock.h>
+#define socklen_t int
+#else
+#include <netinet/in.h>
+#include <sys/ioctl.h>
+#endif
+
+#include "qobject.h"
+#include "qemu-common.h"
+#include "hw/usb.h"
+#include "hw/irq.h"
+#include "mloop_event.h"
+
+#define error_report(x, ...)
+
+struct mloop_evsock {
+ int sockno;
+ unsigned short portno;
+ unsigned char status;
+};
+
+#define MLOOP_EVSOCK_NULL 0
+#define MLOOP_EVSOCK_CREATED 1
+#define MLOOP_EVSOCK_NOTBOUND 2
+#define MLOOP_EVSOCK_BOUND 3
+#define MLOOP_EVSOCK_CONNECTED 4
+
+#define PACKET_LEN 512
+struct mloop_evpack {
+ short type;
+ short size;
+ char data[PACKET_LEN-4];
+};
+
+#define MLOOP_EVTYPE_USB_ADD 1
+#define MLOOP_EVTYPE_USB_DEL 2
+#define MLOOP_EVTYPE_INTR_UP 3
+#define MLOOP_EVTYPE_INTR_DOWN 4
+
+static struct mloop_evsock mloop = {-1,0,0};
+
+static int mloop_evsock_create(struct mloop_evsock *ev)
+{
+ struct sockaddr sa;
+ socklen_t sa_size;
+ int ret;
+ unsigned long nonblock = 1;
+
+ if (ev == NULL) {
+ error_report("mloop_evsock: null point");
+ return -1;
+ }
+
+ ev->sockno = socket(AF_INET, SOCK_DGRAM, 0);
+ if( ev->sockno == -1 ) {
+ error_report("mloop_evsock: socket() failed");
+ return -1;
+ }
+
+#ifdef _WIN32
+ ioctlsocket(ev->sockno, FIONBIO, &nonblock );
+#else
+ ioctl(ev->sockno, FIONBIO, &nonblock);
+#endif // _WIN32
+
+ nonblock = 1 ;
+ setsockopt( ev->sockno, SOL_SOCKET, SO_REUSEADDR, (char *)&nonblock, sizeof(nonblock) ) ;
+
+ memset(&sa, '\0', sizeof(sa));
+ ((struct sockaddr_in *) &sa)->sin_family = AF_INET;
+ memcpy(&((struct sockaddr_in *) &sa)->sin_addr, "\177\000\000\001", 4); // 127.0.0.1
+ ((struct sockaddr_in *) &sa)->sin_port = htons(ev->portno);
+ sa_size = sizeof(struct sockaddr_in);
+
+ ret = bind(ev->sockno, &sa, sa_size);
+ if (ret) {
+ error_report("mloop_evsock: bind() failed");
+ goto mloop_evsock_init_cleanup;
+ }
+
+ if (ev->portno == 0) {
+ memset(&sa, '\0', sizeof(sa));
+ getsockname(ev->sockno, (struct sockaddr *) &sa, &sa_size);
+ ev->portno = ntohs(((struct sockaddr_in *) &sa)->sin_port);
+ }
+
+ ret = connect(ev->sockno, (struct sockaddr *) &sa, sa_size);
+ if (ret) {
+ error_report("mloop_evsock: connect() failed");
+ goto mloop_evsock_init_cleanup;
+ }
+
+ ev->status = MLOOP_EVSOCK_CONNECTED;
+ return 0;
+
+mloop_evsock_init_cleanup:
+#ifdef _WIN32
+ closesocket(ev->sockno);
+#else
+ close(ev->sockno);
+#endif
+ ev->sockno = -1;
+ ev->status = 0;
+ return ret;
+}
+
+static void mloop_evsock_remove(struct mloop_evsock *ev)
+{
+ if (!ev) {
+ return ;
+ }
+
+ if (ev->sockno > 0) {
+#ifdef _WIN32
+ shutdown(ev->sockno, SD_BOTH);
+ closesocket(ev->sockno);
+#else
+ shutdown(ev->sockno, SHUT_RDWR);
+ close(ev->sockno);
+#endif
+ ev->sockno = -1;
+ ev->status = 0;
+ }
+}
+
+static int mloop_evsock_send(struct mloop_evsock *ev, struct mloop_evpack *p)
+{
+ int ret;
+
+ if (ev == NULL || ev->sockno == -1) {
+ error_report("invalid mloop_evsock");
+ return -1;
+ }
+
+ if (p == NULL || p->size <= 0) {
+ error_report("invalid mloop_evpack");
+ return -1;
+ }
+
+ do {
+ ret = send(ev->sockno, p, ntohs(p->size), 0);
+#ifdef _WIN32
+ } while (ret == -1 && (WSAGetLastError() == WSAEWOULDBLOCK));
+#else
+ } while (ret == -1 && (errno == EWOULDBLOCK || errno == EINTR));
+#endif // _WIN32
+
+ return ret;
+}
+
+static USBDevice *usbkbd = NULL;
+static USBDevice *usbdisk = NULL;
+static void mloop_evhandle_usb_add(char *name)
+{
+ if (name == NULL) {
+ return;
+ }
+
+ if (strcmp(name, "keyboard") == 0) {
+ if (usbkbd == NULL) {
+ usbkbd = usbdevice_create(name);
+ }
+ else if (usbkbd->attached == 0) {
+ usb_device_attach(usbkbd);
+ }
+ }
+ else if (strncmp(name, "disk:", 5) == 0) {
+ if (usbdisk == NULL) {
+ usbdisk = usbdevice_create(name);
+ }
+ }
+}
+
+static void mloop_evhandle_usb_del(char *name)
+{
+ if (name == NULL) {
+ return;
+ }
+
+ if (strcmp(name, "keyboard") == 0) {
+ if (usbkbd && usbkbd->attached != 0) {
+ usb_device_detach(usbkbd);
+ }
+ }
+ else if (strncmp(name, "disk:", 5) == 0) {
+ if (usbdisk) {
+ qdev_free(&usbdisk->qdev);
+ }
+ }
+}
+
+static void mloop_evhandle_intr_up(long data)
+{
+ if (data == 0) {
+ return;
+ }
+
+ qemu_irq_raise((qemu_irq)data);
+}
+
+static void mloop_evhandle_intr_down(long data)
+{
+ if (data == 0) {
+ return;
+ }
+
+ qemu_irq_lower((qemu_irq)data);
+}
+
+static void mloop_evcb_recv(struct mloop_evsock *ev)
+{
+ struct mloop_evpack pack;
+ int ret;
+
+ do {
+ ret = recv(ev->sockno, (void *)&pack, sizeof(pack), 0);
+#ifdef _WIN32
+ } while (ret == -1 && WSAGetLastError() == WSAEINTR);
+#else
+ } while (ret == -1 && errno == EINTR);
+#endif // _WIN32
+
+ if (ret == -1 ) {
+ return;
+ }
+
+ if (ret == 0 ) {
+ return;
+ }
+
+ pack.type = ntohs(pack.type);
+ pack.size = ntohs(pack.size);
+
+ switch (pack.type) {
+ case MLOOP_EVTYPE_USB_ADD:
+ mloop_evhandle_usb_add(pack.data);
+ break;
+ case MLOOP_EVTYPE_USB_DEL:
+ mloop_evhandle_usb_del(pack.data);
+ break;
+ case MLOOP_EVTYPE_INTR_UP:
+ mloop_evhandle_intr_up(ntohl(*(long*)&pack.data[0]));
+ break;
+ case MLOOP_EVTYPE_INTR_DOWN:
+ mloop_evhandle_intr_down(ntohl(*(long*)&pack.data[0]));
+ break;
+ default:
+ break;
+ }
+}
+
+void mloop_ev_init(void)
+{
+ int ret = mloop_evsock_create(&mloop);
+ if (ret == 0) {
+ qemu_set_fd_handler(mloop.sockno, (IOHandler *)mloop_evcb_recv, NULL, &mloop);
+ }
+}
+
+void mloop_ev_stop(void)
+{
+ qemu_set_fd_handler(mloop.sockno, NULL, NULL, NULL);
+ mloop_evsock_remove(&mloop);
+}
+
+void mloop_evcmd_usbkbd(int on)
+{
+ struct mloop_evpack pack = { htons(MLOOP_EVTYPE_USB_ADD), htons(13), "keyboard" };
+ if (on == 0)
+ pack.type = htons(MLOOP_EVTYPE_USB_DEL);
+ mloop_evsock_send(&mloop, &pack);
+}
+
+void mloop_evcmd_usbdisk(char *img)
+{
+ struct mloop_evpack pack;
+
+ if (img) {
+ if (strlen(img) > PACKET_LEN-5) {
+ // Need log
+ return;
+ }
+
+ pack.type = htons(MLOOP_EVTYPE_USB_ADD);
+ pack.size = htons(5 + sprintf(pack.data, "disk:%s", img));
+ }
+ else {
+ pack.type = htons(MLOOP_EVTYPE_USB_DEL);
+ pack.size = htons(5 + sprintf(pack.data, "disk:"));
+ }
+
+ mloop_evsock_send(&mloop, &pack);
+}
+
+int mloop_evcmd_get_usbkbd_status(void)
+{
+ return (usbkbd && usbkbd->attached ? 1 : 0);
+}
+
+void mloop_evcmd_set_usbkbd(void *dev)
+{
+ usbkbd = (USBDevice *)dev;
+}
+
+void mloop_evcmd_set_usbdisk(void *dev)
+{
+ usbdisk = (USBDevice *)dev;
+}
+
+void mloop_evcmd_raise_intr(void *irq)
+{
+ struct mloop_evpack pack;
+ memset((void*)&pack, 0, sizeof(struct mloop_evpack));
+ pack.type = htons(MLOOP_EVTYPE_INTR_UP);
+ pack.size = htons(8);
+ *(long*)&pack.data[0] = htonl((long)irq);
+ mloop_evsock_send(&mloop, &pack);
+}
+
+void mloop_evcmd_lower_intr(void *irq)
+{
+ struct mloop_evpack pack;
+ memset((void*)&pack, 0, sizeof(struct mloop_evpack));
+ pack.type = htons(MLOOP_EVTYPE_INTR_DOWN);
+ pack.size = htons(8);
+ *(long*)&pack.data[0] = htonl((long)irq);
+ mloop_evsock_send(&mloop, &pack);
+}