int lifepoll::inner_poll() { // AKT: bailIfCalculating() ; if (isCalculating()) { // AKT: better to simply ignore user event??? // lifefatal("recursive poll called.") ; return interrupted ; } countdown = POLLINTERVAL ; calculating++ ; if (!interrupted) interrupted = checkevents() ; calculating-- ; return interrupted ; }
static int dev_do_io_2 (struct s2devstruct *dev, uaecptr request, int quick) { uae_u8 flags = get_byte (request + 30); uae_u32 command = get_word (request + 28); uae_u32 packettype = get_long (request + 32 + 4); uaecptr data = get_long (request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4); uae_u32 datalength = get_long (request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2); uaecptr srcaddr = request + 32 + 4 + 4; uaecptr dstaddr = request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES; uaecptr statdata = get_long (request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4 + 4); uaecptr buffermgmt = get_long (request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4 + 4 + 4); uae_u32 io_error = 0; uae_u32 wire_error = 0; int i; int async = 0; struct priv_s2devstruct *pdev = getps2devstruct (request); if (log_net) write_log (_T("S2: C=%02d T=%04X S=%02X%02X%02X%02X%02X%02X D=%02X%02X%02X%02X%02X%02X L=%d D=%08X SD=%08X BM=%08X\n"), command, packettype, get_byte (srcaddr + 0), get_byte (srcaddr + 1), get_byte (srcaddr + 2), get_byte (srcaddr + 3), get_byte (srcaddr + 4), get_byte (srcaddr + 5), get_byte (dstaddr + 0), get_byte (dstaddr + 1), get_byte (dstaddr + 2), get_byte (dstaddr + 3), get_byte (dstaddr + 4), get_byte (dstaddr + 5), datalength, data, statdata, buffermgmt); if (command == CMD_READ || command == S2_READORPHAN || command == CMD_WRITE || command == S2_BROADCAST || command == S2_MULTICAST) { if (!pdev->copyfrombuff || !pdev->copytobuff) { io_error = S2ERR_BAD_ARGUMENT; wire_error = S2WERR_BUFF_ERROR; goto end; } } switch (command) { case CMD_READ: if (!dev->online) goto offline; async = 1; break; case S2_READORPHAN: if (!dev->online) goto offline; async = 1; break; case S2_BROADCAST: case CMD_WRITE: if (!dev->online) goto offline; if (!checksize (request, dev)) goto toobig; async = 1; break; case S2_MULTICAST: if (!dev->online) goto offline; if ((get_byte (dstaddr + 0) & 1) == 0) { io_error = S2ERR_BAD_ADDRESS; wire_error = S2WERR_BAD_MULTICAST; goto end; } if (!checksize (request, dev)) goto toobig; async = 1; break; case CMD_FLUSH: dev->flush_timeout_cnt = 0; dev->flush_timeout = FLUSH_TIMEOUT; if (log_net) write_log (_T("CMD_FLUSH started %08x\n"), request); uae_sem_wait (&async_sem); flush (pdev); uae_sem_post (&async_sem); async = 1; uaenet_vsync_requested++; break; case S2_ADDMULTICASTADDRESS: addmulticastaddresses (dev, amigaaddrto64 (srcaddr), 0); break; case S2_DELMULTICASTADDRESS: if (!delmulticastaddresses (dev, amigaaddrto64 (srcaddr), 0)) { io_error = S2ERR_BAD_STATE; wire_error = S2WERR_BAD_MULTICAST; } break; case S2_ADDMULTICASTADDRESSES: addmulticastaddresses (dev, amigaaddrto64 (srcaddr), amigaaddrto64 (dstaddr)); break; case S2_DELMULTICASTADDRESSES: if (!delmulticastaddresses (dev, amigaaddrto64 (srcaddr), amigaaddrto64 (dstaddr))) { io_error = S2ERR_BAD_STATE; wire_error = S2WERR_BAD_MULTICAST; } break; case S2_DEVICEQUERY: { int size = get_long (statdata); if (size > 30) size = 30; put_long (statdata + 4, size); if (size >= 12) put_long (statdata + 8, 0); if (size >= 16) put_long (statdata + 12, 0); if (size >= 18) put_word (statdata + 16, ADDR_SIZE * 8); if (size >= 22) put_long (statdata + 18, dev->td->mtu); if (size >= 26) put_long (statdata + 22, 10000000); if (size >= 30) put_long (statdata + 26, S2WireType_Ethernet); } break; case S2_GETTYPESTATS: if (pdev->trackcnt) { put_long (statdata + 0, pdev->packetssent); put_long (statdata + 4, pdev->packetsreceived); put_long (statdata + 8, pdev->bytessent); put_long (statdata + 12, pdev->bytesreceived); put_long (statdata + 16, pdev->packetsdropped); } else { io_error = S2ERR_BAD_STATE; wire_error = S2WERR_NOT_TRACKED; } break; case S2_GETGLOBALSTATS: put_long (statdata + 0, dev->packetsreceived); put_long (statdata + 4, dev->packetssent); put_long (statdata + 8, dev->baddata); put_long (statdata + 12, dev->overruns); put_long (statdata + 16, 0); put_long (statdata + 20, dev->unknowntypesreceived); put_long (statdata + 24, dev->reconfigurations); put_long (statdata + 28, dev->online_secs); put_long (statdata + 32, dev->online_micro); break; case S2_GETSPECIALSTATS: put_long (statdata + 1, 0); break; case S2_GETSTATIONADDRESS: for (i = 0; i < ADDR_SIZE; i++) { put_byte (srcaddr + i, dev->td->mac[i]); put_byte (dstaddr + i, dev->td->mac[i]); } break; case S2_CONFIGINTERFACE: if (dev->configured) { io_error = S2ERR_BAD_STATE; wire_error = S2WERR_IS_CONFIGURED; } else { dev->configured = TRUE; } break; case S2_ONLINE: if (!dev->configured) { io_error = S2ERR_BAD_STATE; wire_error = S2WERR_NOT_CONFIGURED; } if (!dev->adapter) { io_error = S2ERR_OUTOFSERVICE; wire_error = S2WERR_RCVREL_HDW_ERR; } if (!io_error) { uaenet_vsync_requested++; async = 1; } break; case S2_TRACKTYPE: if (packettype <= 65535) { if (pdev->tracks[packettype]) { io_error = S2ERR_BAD_STATE; wire_error = S2WERR_ALREADY_TRACKED; } else { pdev->tracks[packettype] = 1; pdev->trackcnt++; } } else { io_error = S2ERR_BAD_ARGUMENT; } break; case S2_UNTRACKTYPE: if (packettype <= 65535) { if (!pdev->tracks[packettype]) { io_error = S2ERR_BAD_STATE; wire_error = S2WERR_NOT_TRACKED; } else { pdev->tracks[packettype] = 0; pdev->trackcnt--; } } else { io_error = S2ERR_BAD_ARGUMENT; } break; case S2_OFFLINE: if (dev->online) { dev->online = 0; checkevents (dev, S2EVENT_OFFLINE, 1); } break; case S2_ONEVENT: { uae_u32 events; uae_u32 wanted_events = get_long (request + 32); if (wanted_events & ~KNOWN_EVENTS) { io_error = S2ERR_NOT_SUPPORTED; events = S2WERR_BAD_EVENT; } else { if (dev->online) events = S2EVENT_ONLINE; else events = S2EVENT_OFFLINE; events &= wanted_events; if (events) { wire_error = events; } else { async = 1; } } } break; default: io_error = IOERR_NOCMD; break; offline: io_error = S2ERR_OUTOFSERVICE; wire_error = S2WERR_UNIT_OFFLINE; break; toobig: io_error = S2ERR_MTU_EXCEEDED; wire_error = S2WERR_GENERIC_ERROR; break; } end: if (log_net && (io_error || wire_error)) write_log (_T("-> %d (%d)\n"), io_error, wire_error); put_long (request + 32, wire_error); put_byte (request + 31, io_error); return async; }
static uae_u32 REGPARAM2 uaenet_int_handler (TrapContext *ctx) { int i, j; int gotit; struct asyncreq *ar; if (uae_sem_trywait (&async_sem)) { uaenet_int_requested = 0; uaenet_int_late = 1; return 0; } for (i = 0; i < MAX_OPEN_DEVICES; i++) pdevst[i].tmp = 0; for (i = 0; i < MAX_TOTAL_NET_DEVICES; i++) { struct s2devstruct *dev = &devst[i]; struct s2packet *p; if (dev->online) { while (dev->readqueue) { uae_u16 type; p = dev->readqueue; type = (p->data[2 * ADDR_SIZE] << 8) | p->data[2 * ADDR_SIZE + 1]; ar = dev->ar; gotit = 0; while (ar) { if (!ar->ready) { uaecptr request = ar->request; int command = get_word (request + 28); uae_u32 packettype = get_long (request + 32 + 4); if (command == CMD_READ && (packettype == type || (packettype <= 1500 && type <= 1500))) { struct priv_s2devstruct *pdev = getps2devstruct (request); if (pdev && pdev->tmp == 0) { if (handleread (ctx, pdev, request, p->data, p->len, command)) { if (log_net) write_log (_T("-> %p Accepted, CMD_READ, REQ=%08X LEN=%d\n"), p, request, p->len); ar->ready = 1; write_comm_pipe_u32 (&dev->requests, request, 1); dev->packetsreceived++; gotit = 1; pdev->tmp = 1; } else { if (log_net) write_log (_T("-> %p PacketFilter() rejected, CMD_READ, REQ=%08X LEN=%d\n"), p, request, p->len); pdev->tmp = -1; } } } } ar = ar->next; } ar = dev->ar; while (ar) { if (!ar->ready) { uaecptr request = ar->request; int command = get_word (request + 28); if (command == S2_READORPHAN) { struct priv_s2devstruct *pdev = getps2devstruct (request); if (pdev && pdev->tmp <= 0) { if (log_net) write_log (_T("-> %p Accepted, S2_READORPHAN, REQ=%08X LEN=%d\n"), p, request, p->len); handleread (ctx, pdev, request, p->data, p->len, command); ar->ready = 1; write_comm_pipe_u32 (&dev->requests, request, 1); dev->packetsreceived++; dev->unknowntypesreceived++; gotit = 1; pdev->tmp = 1; } } } ar = ar->next; } if (!gotit) { if (log_net) write_log (_T("-> %p packet dropped, LEN=%d\n"), p, p->len); for (j = 0; j < MAX_OPEN_DEVICES; j++) { if (pdevst[j].unit == dev->unit) { if (pdevst[j].tracks[type]) pdevst[j].packetsdropped++; } } } dev->readqueue = dev->readqueue->next; freepacket (p); } } else { while (dev->readqueue) { p = dev->readqueue; dev->readqueue = dev->readqueue->next; freepacket (p); } } ar = dev->ar; while (ar) { if (!ar->ready) { uaecptr request = ar->request; int command = get_word (request + 28); if (command == S2_ONLINE) { struct priv_s2devstruct *pdev = getps2devstruct (request); dev->packetsreceived = 0; dev->packetssent = 0; dev->baddata = 0; dev->overruns = 0; dev->unknowntypesreceived = 0; dev->reconfigurations = 0; if (pdev && pdev->timerbase) { m68k_areg (regs, 0) = pdev->tempbuf; CallLib (ctx, pdev->timerbase, -0x42); /* GetSysTime() */ } else { put_long (pdev->tempbuf + 0, 0); put_long (pdev->tempbuf + 4, 0); } dev->online_secs = get_long (pdev->tempbuf + 0); dev->online_micro = get_long (pdev->tempbuf + 4); checkevents (dev, S2EVENT_ONLINE, 0); dev->online = 1; ar->ready = 1; write_comm_pipe_u32 (&dev->requests, request, 1); uaenet_vsync_requested--; } else if (command == CMD_FLUSH) { /* do not reply CMD_FLUSH until all other requests are gone */ if (dev->ar->next == NULL) { if (log_net) write_log (_T("CMD_FLUSH replied %08x\n"), request); ar->ready = 1; write_comm_pipe_u32 (&dev->requests, request, 1); uaenet_vsync_requested--; } else { struct priv_s2devstruct *pdev = getps2devstruct (request); if (pdev) { dev->flush_timeout--; if (dev->flush_timeout <= 0) { dev->flush_timeout = FLUSH_TIMEOUT; if (dev->flush_timeout_cnt > 1) write_log (_T("WARNING: %s:%d CMD_FLUSH possibly frozen..\n"), getdevname(), pdev->unit); dev->flush_timeout_cnt++; flush (pdev); } } } } } ar = ar->next; } } if (uaenet_int_late) uaenet_int_requested = 1; else uaenet_int_requested = 0; uaenet_int_late = 0; uae_sem_post (&async_sem); return 0; }