예제 #1
0
파일: uaeserial.c 프로젝트: Yamakuzure/PUAE
static int32_t release_async_request (struct devstruct *dev, uaecptr request)
{
	struct asyncreq *ar, *prevar;

	uae_sem_wait (&async_sem);
	ar = dev->ar;
	prevar = NULL;
	while (ar) {
		if (ar->request == request) {
			if (prevar == NULL)
				dev->ar = ar->next;
			else
				prevar->next = ar->next;
			uae_sem_post (&async_sem);
			xfree (ar);
			if (log_uaeserial)
				write_log (_T("%s:%d async request %x removed\n"), getdevname(), dev->unit, request);
			return 1;
		}
		prevar = ar;
		ar = ar->next;
	}
	uae_sem_post (&async_sem);
	write_log (_T("%s:%d async request %x not found for removal!\n"), getdevname(), dev->unit, request);
	return 0;
}
예제 #2
0
파일: sana2.cpp 프로젝트: sunfirefox/WinUAE
static uae_u32 REGPARAM2 dev_beginio (TrapContext *context)
{
	uae_u32 request = m68k_areg (regs, 1);
	uae_u8 flags = get_byte (request + 30);
	int command = get_word (request + 28);
	struct priv_s2devstruct *pdev = getps2devstruct (request);
	struct s2devstruct *dev;

	put_byte (request + 8, NT_MESSAGE);
	if (!pdev) {
		write_log (_T("%s unknown iorequest (1) %08x\n"), getdevname (), request);
		put_byte (request + 31, 32);
		return get_byte (request + 31);
	}
	dev = gets2devstruct (pdev->unit);
	if (!dev) {
		write_log (_T("%s unknown iorequest (2) %08x\n"), getdevname (), request);
		put_byte (request + 31, 32);
		return get_byte (request + 31);
	}
	put_byte (request + 31, 0);
	if ((flags & 1) && dev_canquick (dev, request)) {
		if (dev_do_io (dev, request, 1))
			write_log (_T("%s: command %d bug with IO_QUICK\n"), SANA2NAME, command);
		return get_byte (request + 31);
	} else {
		if (command == CMD_WRITE || command == S2_BROADCAST || command == S2_MULTICAST) {
			struct s2packet *s2p;
			if (!pdev->copyfrombuff || !pdev->copytobuff) {
				put_long (request + 32, S2ERR_BAD_ARGUMENT);
				put_byte (request + 31, S2WERR_BUFF_ERROR);
			} else {
				if (command == S2_BROADCAST) {
					uaecptr dstaddr = request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES;
					put_byte (dstaddr +  0, 0xff);
					put_byte (dstaddr +  1, 0xff);
					put_byte (dstaddr +  2, 0xff);
					put_byte (dstaddr +  3, 0xff);
					put_byte (dstaddr +  4, 0xff);
					put_byte (dstaddr +  5, 0xff);
				}
				s2p = createwritepacket (context, request);
				if (s2p) {
					uae_sem_wait (&async_sem);
					add_async_packet (dev, s2p, request);
					uae_sem_post (&async_sem);
				}
				if (!s2p) {
					put_long (request + 32, S2WERR_BUFF_ERROR);
					put_byte (request + 31, S2ERR_NO_RESOURCES);
				}
			}
		}
		put_byte (request + 30, get_byte (request + 30) & ~1);
		write_comm_pipe_u32 (&dev->requests, request, 1);
		return 0;
	}
}
예제 #3
0
파일: sana2.cpp 프로젝트: sunfirefox/WinUAE
static void abort_async (struct s2devstruct *dev, uaecptr request)
{
	struct asyncreq *ar = get_async_request (dev, request, 1);
	if (!ar) {
		write_log (_T("%s:%d: abort async but no request %x found!\n"), getdevname(), dev->unit, request);
		return;
	}
	if (log_net)
		write_log (_T("%s:%d asyncronous request=%08X aborted\n"), getdevname(), dev->unit, request);
	do_abort_async (dev, request);
}
예제 #4
0
파일: uaeserial.c 프로젝트: Yamakuzure/PUAE
static void abort_async (struct devstruct *dev, uaecptr request)
{
	struct asyncreq *ar = get_async_request (dev, request, 1);
	if (!ar) {
		write_log (_T("%s:%d: abort async but no request %x found!\n"), getdevname(), dev->unit, request);
		return;
	}
	if (log_uaeserial)
		write_log (_T("%s:%d asyncronous request=%08X aborted\n"), getdevname(), dev->unit, request);
	put_byte (request + 31, IOERR_ABORTED);
	put_byte (request + 30, get_byte (request + 30) | 0x20);
	write_comm_pipe_u32 (&dev->requests, request, 1);
}
예제 #5
0
파일: uaeserial.c 프로젝트: Yamakuzure/PUAE
static uint32_t REGPARAM2 dev_init (TrapContext *context)
{
	uint32_t base = m68k_dreg (regs, 0);
	if (log_uaeserial)
		write_log (_T("%s init\n"), getdevname ());
	return base;
}
예제 #6
0
파일: sana2.cpp 프로젝트: sunfirefox/WinUAE
static void dev_reset (void)
{
	int i;
	struct s2devstruct *dev;
	int unitnum = 0;

	write_log (_T("%s reset\n"), getdevname());
	for (i = 0; i < MAX_TOTAL_NET_DEVICES; i++) {
		dev = &devst[i];
		if (dev->opencnt) {
			struct asyncreq *ar = dev->ar;
			while (ar) {
				if (!ar->ready) {
					dev->ar->ready = 1;
					do_abort_async (dev, ar->request);
				}
				ar = ar->next;
			}
			write_comm_pipe_u32 (&dev->requests, 0, 1);
			uae_sem_wait (&dev->sync_sem);
		}
		while (dev->mc)
			delmulticastaddresses (dev, dev->mc->start, dev->mc->end);
		memset (dev, 0, sizeof (struct s2devstruct));
	}
	for (i = 0; i < MAX_OPEN_DEVICES; i++)
		memset (&pdevst[i], 0, sizeof (struct priv_s2devstruct));
	uaenet_vsync_requested = 0;
	uaenet_int_requested = 0;
	irq_init = 0;

}
예제 #7
0
파일: sana2.cpp 프로젝트: sunfirefox/WinUAE
static void *dev_thread (void *devs)
{
	struct s2devstruct *dev = (struct s2devstruct*)devs;

	uae_set_thread_priority (NULL, 1);
	dev->thread_running = 1;
	uae_sem_post (&dev->sync_sem);
	for (;;) {
		uaecptr request = (uaecptr)read_comm_pipe_u32_blocking (&dev->requests);
		uae_sem_wait (&change_sem);
		if (!request) {
			dev->thread_running = 0;
			uae_sem_post (&dev->sync_sem);
			uae_sem_post (&change_sem);
			write_log (_T("%s: dev_thread killed\n"), getdevname ());
			return 0;
		} else if (get_async_request (dev, request, 1)) {
			uae_ReplyMsg (request);
			release_async_request (dev, request);
			rem_async_packet (dev, request);
		} else if (dev_do_io (dev, request, 0) == 0) {
			uae_ReplyMsg (request);
			rem_async_packet (dev, request);
		} else {
			add_async_request (dev, request);
			ethernet_trigger (dev->sysdata);
		}
		uae_sem_post (&change_sem);
	}
	return 0;
}
예제 #8
0
파일: sana2.cpp 프로젝트: sunfirefox/WinUAE
static int dev_do_io (struct s2devstruct *dev, uaecptr request, int quick)
{
	uae_u32 command = get_word (request + 28);
	struct priv_s2devstruct *pdev = getps2devstruct (request);
	uaecptr data = get_long (request + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4);

	put_byte (request + 31, 0);
	if (!pdev) {
		write_log (_T("%s unknown iorequest %08x\n"), getdevname (), request);
		return 0;
	}
	if (command == NSCMD_DEVICEQUERY) {
		uae_u32 data = get_long (request + 40); /* io_data */
		put_long (data + 0, 0);
		put_long (data + 4, 16); /* size */
		put_word (data + 8, 7); /* NSDEVTYPE_SANA2 */
		put_word (data + 10, 0);
		put_long (data + 12, nscmd_cmd);
		put_long (request + 32, 16); /* io_actual */
		return 0;
	} else if (get_word (request + 0x12) < SANA2_IOREQSIZE) {
		put_byte (request + 31, IOERR_BADLENGTH);
		return 0;
	}
	return dev_do_io_2 (dev, request, quick);
}
예제 #9
0
static uae_u32 REGPARAM2 dev_init_2 (TrapContext *context, int type)
{
    uae_u32 base = m68k_dreg (&context->regs,0);
    if (log_scsi)
	write_log ("%s init\n", getdevname (type));
    return base;
}
예제 #10
0
static uae_u32 REGPARAM2 dev_beginio (TrapContext *context)
{
    uae_u32 request = m68k_areg (&context->regs, 1);
    uae_u8 flags = get_byte (request + 30);
    int command = get_word (request + 28);
    struct priv_devstruct *pdev = getpdevstruct (request);
    struct devstruct *dev = getdevstruct (pdev->unit);

    put_byte (request+8, NT_MESSAGE);
    if (!dev || !pdev) {
	put_byte (request + 31, 32);
	return get_byte (request + 31);
    }
    put_byte (request+31, 0);
    if ((flags & 1) && dev_canquick (dev, request)) {
	if (dev_do_io (dev, request))
	    write_log ("device %s command %d bug with IO_QUICK\n", getdevname (pdev->type), command);
	return get_byte (request + 31);
    } else {
	add_async_request (dev, request, ASYNC_REQUEST_TEMP, 0);
	put_byte (request+30, get_byte (request + 30) & ~1);
	write_comm_pipe_u32 (&dev->requests, request, 1);
	return 0;
    }
}
예제 #11
0
파일: sana2.cpp 프로젝트: sunfirefox/WinUAE
static void signalasync (struct s2devstruct *dev, struct asyncreq *ar, int actual, int err)
{
	uaecptr request = ar->request;
	int command = get_word (request + 28);
	if (log_net)
		write_log (_T("%s:%d CMD=%d async request %x completed\n"), getdevname(), dev->unit, command, request);
	put_long (request + 32, actual);
	put_byte (request + 31, err);
	ar->ready = 1;
	write_comm_pipe_u32 (&dev->requests, request, 1);
}
예제 #12
0
파일: sana2.cpp 프로젝트: sunfirefox/WinUAE
static uae_u32 REGPARAM2 dev_abortio (TrapContext *context)
{
	uae_u32 request = m68k_areg (regs, 1);
	struct priv_s2devstruct *pdev = getps2devstruct (request);
	struct s2devstruct *dev;

	if (!pdev) {
		write_log (_T("%s abortio but no request %08x found!\n"), getdevname(), request);
		put_byte (request + 31, 32);
		return get_byte (request + 31);
	}
	dev = gets2devstruct (pdev->unit);
	if (!dev) {
		write_log (_T("%s (%d) abortio but no request %08x found!\n"), getdevname(), pdev->unit, request);
		put_byte (request + 31, 32);
		return get_byte (request + 31);
	}
	if (log_net)
		write_log (_T("%s:%d abortio %08x\n"), getdevname(), dev->unit, request);
	abort_async (dev, request);
	return 0;
}
예제 #13
0
static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context, int type)
{
    uaecptr ioreq = m68k_areg (&context->regs, 1);
    uae_u32 unit = m68k_dreg (&context->regs, 0);
    uae_u32 flags = m68k_dreg (&context->regs, 1);
    struct devstruct *dev = getdevstruct (unit);
    struct priv_devstruct *pdev = 0;
    int i;

    if (log_scsi)
	write_log ("opening %s:%d ioreq=%08.8X\n", getdevname (type), unit, ioreq);
    if (!dev)
	return openfail (ioreq, 32); /* badunitnum */
    if (!dev->opencnt) {
	for (i = 0; i < MAX_OPEN_DEVICES; i++) {
	    pdev = &pdevst[i];
	    if (pdev->inuse == 0) break;
	}
	if (type == UAEDEV_SCSI_ID && sys_command_open (DF_SCSI, dev->unitnum)) {
	    pdev->scsi = 1;
	    pdev->mode = DF_SCSI;
	}
	if (type == UAEDEV_DISK_ID && sys_command_open (DF_IOCTL, dev->unitnum)) {
	    pdev->ioctl = 1;
	    pdev->mode = DF_IOCTL;
	}
	if (!pdev->scsi && !pdev->ioctl)
	    return openfail (ioreq, -1);
	pdev->type = type;
	pdev->unit = unit;
	pdev->flags = flags;
	pdev->inuse = 1;
	put_long (ioreq + 24, pdev - pdevst);
	start_thread (dev);
    } else {
	for (i = 0; i < MAX_OPEN_DEVICES; i++) {
	    pdev = &pdevst[i];
	    if (pdev->inuse && pdev->unit == (int)unit) break;
	}
	if (i == MAX_OPEN_DEVICES)
	    return openfail (ioreq, -1);
	put_long (ioreq + 24, pdev - pdevst);
    }
    dev->opencnt++;

    put_word (m68k_areg (&context->regs, 6) + 32, get_word (m68k_areg (&context->regs, 6) + 32) + 1);
    put_byte (ioreq + 31, 0);
    put_byte (ioreq + 8, 7);
    return 0;
}
예제 #14
0
파일: uaeserial.c 프로젝트: Yamakuzure/PUAE
static uint32_t REGPARAM2 dev_close (TrapContext *context)
{
	uint32_t request = m68k_areg (regs, 1);
	struct devstruct *dev;

	dev = getdevstruct (get_long (request + 24));
	if (!dev)
		return 0;
	if (log_uaeserial)
		write_log (_T("%s:%d close, req=%x\n"), getdevname(), dev->unit, request);
	dev_close_3 (dev);
	put_long (request + 24, 0);
	put_word (m68k_areg (regs, 6) + 32, get_word (m68k_areg (regs, 6) + 32) - 1);
	return 0;
}
예제 #15
0
파일: uaeserial.c 프로젝트: Yamakuzure/PUAE
static uint32_t REGPARAM2 dev_open (TrapContext *context)
{
	uaecptr ioreq = m68k_areg (regs, 1);
	uint32_t unit = m68k_dreg (regs, 0);
	uint32_t flags = m68k_dreg (regs, 1);
	struct devstruct *dev;
	int32_t i, err;

	if (get_word (ioreq + 0x12) < IOSTDREQ_SIZE)
		return openfail (ioreq, IOERR_BADLENGTH);
	for (i = 0; i < MAX_TOTAL_DEVICES; i++) {
		if (devst[i].open && devst[i].unit == (int32_t)unit && devst[i].exclusive)
			return openfail (ioreq, IOERR_UNITBUSY);
	}
	for (i = 0; i < MAX_TOTAL_DEVICES; i++) {
		if (!devst[i].open)
			break;
	}
	if (i == MAX_TOTAL_DEVICES)
		return openfail (ioreq, IOERR_OPENFAIL);
	dev = &devst[i];
	dev->sysdata = xcalloc (uint8_t, uaeser_getdatalength ());
	if (!uaeser_open (dev->sysdata, dev, unit)) {
		xfree (dev->sysdata);
		return openfail (ioreq, IOERR_OPENFAIL);
	}
	dev->unit = unit;
	dev->open = 1;
	dev->uniq = ++uniq;
	dev->exclusive = (get_word (ioreq + io_SerFlags) & SERF_SHARED) ? 0 : 1;
	put_long (ioreq + 24, dev->uniq);
	resetparams (dev, ioreq);
	err = setparams (dev, ioreq);
	if (err) {
		uaeser_close (dev->sysdata);
		dev->open = 0;
		xfree (dev->sysdata);
		return openfail (ioreq, err);
	}
	if (log_uaeserial)
		write_log (_T("%s:%d open ioreq=%08X\n"), getdevname(), unit, ioreq);
	start_thread (dev);

	put_word (m68k_areg (regs, 6) + 32, get_word (m68k_areg (regs, 6) + 32) + 1);
	put_byte (ioreq + 31, 0);
	put_byte (ioreq + 8, 7);
	return 0;
}
예제 #16
0
static uae_u32 REGPARAM2 dev_close_2 (TrapContext *context)
{
    uae_u32 request = m68k_areg (&context->regs, 1);
    struct priv_devstruct *pdev = getpdevstruct (request);
    struct devstruct *dev;

    if (!pdev)
	return 0;
    dev = getdevstruct (pdev->unit);
    if (log_scsi)
	write_log ("%s:%d close, req=%08.8X\n", getdevname (pdev->type), pdev->unit, request);
    if (!dev)
	return 0;
    dev_close_3 (dev, pdev);
    put_long (request + 24, 0);
    put_word (m68k_areg (&context->regs, 6) + 32, get_word (m68k_areg (&context->regs, 6) + 32) - 1);
    return 0;
}
예제 #17
0
파일: uaeserial.c 프로젝트: Yamakuzure/PUAE
static int32_t setparams (struct devstruct *dev, uaecptr req)
{
	int32_t v;
	int32_t rbuffer, baud, rbits, wbits, sbits, rtscts, parity, xonxoff;

	rbuffer = get_long (req + io_RBufLen);
	v = get_long (req + io_ExtFlags);
	if (v) {
		write_log (_T("UAESER: io_ExtFlags=%08x, not supported\n"), v);
		return 5;
	}
	baud = get_long (req + io_Baud);
	v = get_byte (req + io_SerFlags);
	if (v & SERF_EOFMODE) {
		write_log (_T("UAESER: SERF_EOFMODE not supported\n"));
		return 5;
	}
	xonxoff = (v & SERF_XDISABLED) ? 0 : 1;
	if (xonxoff) {
		xonxoff |= (get_long (req + io_CtlChar) << 8) & 0x00ffff00;
	}
	rtscts = (v & SERF_7WIRE) ? 1 : 0;
	parity = 0;
	if (v & SERF_PARTY_ON)
		parity = (v & SERF_PARTY_ODD) ? 1 : 2;
	rbits = get_byte (req + io_ReadLen);
	wbits = get_byte (req + io_WriteLen);
	sbits = get_byte (req + io_StopBits);
	if ((rbits != 7 && rbits != 8) || (wbits != 7 && wbits != 8) || (sbits != 1 && sbits != 2) || rbits != wbits) {
		write_log (_T("UAESER: Read=%d, Write=%d, Stop=%d, not supported\n"), rbits, wbits, sbits);
		return 5;
	}
	write_log (_T("%s:%d BAUD=%d BUF=%d BITS=%d+%d RTSCTS=%d PAR=%d XO=%06X\n"),
		getdevname(), dev->unit,
		baud, rbuffer, rbits, sbits, rtscts, parity, xonxoff);
	v = uaeser_setparams (dev->sysdata, baud, rbuffer,
		rbits, sbits, rtscts, parity, xonxoff);
	if (v) {
		write_log (_T("->failed\n"));
		return v;
	}
	return 0;
}
예제 #18
0
파일: uaeserial.c 프로젝트: Yamakuzure/PUAE
static int32_t add_async_request (struct devstruct *dev, uaecptr request)
{
	struct asyncreq *ar, *ar2;

	if (log_uaeserial)
		write_log (_T("%s:%d async request %x added\n"), getdevname(), dev->unit, request);

	uae_sem_wait (&async_sem);
	ar = xcalloc (struct asyncreq, 1);
	ar->request = request;
	if (!dev->ar) {
		dev->ar = ar;
	} else {
		ar2 = dev->ar;
		while (ar2->next)
			ar2 = ar2->next;
		ar2->next = ar;
	}
	uae_sem_post (&async_sem);
	return 1;
}
예제 #19
0
static uae_u32 REGPARAM2 dev_abortio (TrapContext *context)
{
    uae_u32 request = m68k_areg (&context->regs, 1);
    struct priv_devstruct *pdev = getpdevstruct (request);
    struct devstruct *dev;

    if (!pdev) {
	put_byte (request + 31, 32);
	return get_byte (request + 31);
    }
    dev = getdevstruct (pdev->unit);
    if (!dev) {
	put_byte (request + 31, 32);
	return get_byte (request + 31);
    }
    put_byte (request + 31, -2);
    if (log_scsi)
	write_log ("abortio %s unit=%d, request=%08.8X\n", getdevname (pdev->type), pdev->unit, request);
    abort_async (dev, request, -2, 0);
    return 0;
}
예제 #20
0
파일: uaeserial.c 프로젝트: Yamakuzure/PUAE
static uint32_t REGPARAM2 dev_beginio (TrapContext *context)
{
	uint32_t request = m68k_areg (regs, 1);
	uint8_t flags = get_byte (request + 30);
	int32_t command = get_word (request + 28);
	struct devstruct *dev = getdevstruct (get_long (request + 24));

	put_byte (request + 8, NT_MESSAGE);
	if (!dev) {
		put_byte (request + 31, 32);
		return get_byte (request + 31);
	}
	put_byte (request + 31, 0);
	if ((flags & 1) && dev_canquick (dev, request)) {
		if (dev_do_io (dev, request, 1))
			write_log (_T("device %s:%d command %d bug with IO_QUICK\n"), getdevname(), dev->unit, command);
		return get_byte (request + 31);
	} else {
		put_byte (request + 30, get_byte (request + 30) & ~1);
		write_comm_pipe_u32 (&dev->requests, request, 1);
		return 0;
	}
}
예제 #21
0
파일: uaeserial.c 프로젝트: Yamakuzure/PUAE
void uaeser_signal (void *vdev, int32_t sigmask)
{
	struct devstruct *dev = (struct devstruct*)vdev;
	struct asyncreq *ar;
	int32_t i = 0;

	uae_sem_wait (&async_sem);
	ar = dev->ar;
	while (ar) {
		if (!ar->ready) {
			uaecptr request = ar->request;
			uint32_t io_data = get_long (request + 40); // 0x28
			uint32_t io_length = get_long (request + 36); // 0x24
			int32_t command = get_word (request + 28);
			uint32_t io_error = 0, io_actual = 0;
			uint8_t *addr;
			int32_t io_done = 0;

			switch (command)
			{
			case SDCMD_BREAK:
				if (ar == dev->ar) {
					uaeser_break (dev->sysdata,  get_long (request + io_BrkTime));
					io_done = 1;
				}
				break;
			case CMD_READ:
				if (sigmask & 1) {
					addr = memmap(io_data, io_length);
					if (addr) {
						if (uaeser_read (dev->sysdata, addr, io_length)) {
							io_error = 0;
							io_actual = io_length;
							io_done = 1;
						}
					} else {
						io_error = IOERR_BADADDRESS;
						io_done = 1;
					}
				}
				break;
			case CMD_WRITE:
				if (sigmask & 2) {
					io_error = IOERR_BADADDRESS;
					addr = memmap(io_data, io_length);
					if (addr && uaeser_write (dev->sysdata, addr, io_length))
						io_error = 0;
					io_actual = io_length;
					io_done = 1;
				}
				break;
			default:
				write_log (_T("%s:%d incorrect async request %x (cmd=%d) signaled?!"), getdevname(), dev->unit, request, command);
				break;
			}

			if (io_done) {
				if (log_uaeserial)
					write_log (_T("%s:%d async request %x completed\n"), getdevname(), dev->unit, request);
				put_long (request + 32, io_actual);
				put_byte (request + 31, io_error);
				ar->ready = 1;
				write_comm_pipe_u32 (&dev->requests, request, 1);
			}

		}
		ar = ar->next;
	}
	uae_sem_post (&async_sem);
}
예제 #22
0
파일: sana2.cpp 프로젝트: sunfirefox/WinUAE
void netdev_install (void)
{
	uae_u32 functable, datatable;
	uae_u32 initcode, openfunc, closefunc, expungefunc;
	uae_u32 beginiofunc, abortiofunc;

	if (!currprefs.sana2)
		return;
	if (log_net)
		write_log (_T("netdev_install(): 0x%x\n"), here ());

	ethernet_enumerate_free ();
	ethernet_enumerate (td, NULL);

	ROM_netdev_resname = ds (getdevname());
	ROM_netdev_resid = ds (_T("UAE net.device 0.2"));
	timerdevname = ds (_T("timer.device"));

	/* initcode */
	initcode = here ();
	calltrap (deftrap2 (dev_init, TRAPFLAG_EXTRA_STACK, _T("uaenet.init"))); dw (RTS);

	/* Open */
	openfunc = here ();
	calltrap (deftrap2 (dev_open, TRAPFLAG_EXTRA_STACK, _T("uaenet.open"))); dw (RTS);

	/* Close */
	closefunc = here ();
	calltrap (deftrap2 (dev_close, TRAPFLAG_EXTRA_STACK, _T("uaenet.close"))); dw (RTS);

	/* Expunge */
	expungefunc = here ();
	calltrap (deftrap2 (dev_expunge, TRAPFLAG_EXTRA_STACK, _T("uaenet.expunge"))); dw (RTS);

	/* BeginIO */
	beginiofunc = here ();
	calltrap (deftrap2 (dev_beginio, TRAPFLAG_EXTRA_STACK, _T("uaenet.beginio"))); dw (RTS);

	/* AbortIO */
	abortiofunc = here ();
	calltrap (deftrap2 (dev_abortio, TRAPFLAG_EXTRA_STACK, _T("uaenet.abortio"))); dw (RTS);

	/* FuncTable */
	functable = here ();
	dl (openfunc); /* Open */
	dl (closefunc); /* Close */
	dl (expungefunc); /* Expunge */
	dl (EXPANSION_nullfunc); /* Null */
	dl (beginiofunc); /* BeginIO */
	dl (abortiofunc); /* AbortIO */
	dl (0xFFFFFFFFul); /* end of table */

	/* DataTable */
	datatable = here ();
	dw (0xE000); /* INITBYTE */
	dw (0x0008); /* LN_TYPE */
	dw (0x0300); /* NT_DEVICE */
	dw (0xC000); /* INITLONG */
	dw (0x000A); /* LN_NAME */
	dl (ROM_netdev_resname);
	dw (0xE000); /* INITBYTE */
	dw (0x000E); /* LIB_FLAGS */
	dw (0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */
	dw (0xD000); /* INITWORD */
	dw (0x0014); /* LIB_VERSION */
	dw (0x0004); /* 0.4 */
	dw (0xD000); /* INITWORD */
	dw (0x0016); /* LIB_REVISION */
	dw (0x0000); /* end of table already ??? */
	dw (0xC000); /* INITLONG */
	dw (0x0018); /* LIB_IDSTRING */
	dl (ROM_netdev_resid);
	dw (0x0000); /* end of table */

	ROM_netdev_init = here ();
	dl (0x00000100); /* size of device base */
	dl (functable);
	dl (datatable);
	dl (initcode);

	nscmd_cmd = here ();
	dw (CMD_READ);
	dw (CMD_WRITE);
	dw (CMD_FLUSH);
	dw (S2_DEVICEQUERY);
	dw (S2_GETSTATIONADDRESS);
	dw (S2_CONFIGINTERFACE);
	dw (S2_ADDMULTICASTADDRESS);
	dw (S2_DELMULTICASTADDRESS);
	dw (S2_MULTICAST);
	dw (S2_BROADCAST);
	dw (S2_TRACKTYPE);
	dw (S2_UNTRACKTYPE);
	dw (S2_GETTYPESTATS);
	dw (S2_GETSPECIALSTATS);
	dw (S2_GETGLOBALSTATS);
	dw (S2_ONEVENT);
	dw (S2_READORPHAN);
	dw (S2_ONLINE);
	dw (S2_OFFLINE);
	dw (S2_ADDMULTICASTADDRESSES);
	dw (S2_DELMULTICASTADDRESSES);
	dw (NSCMD_DEVICEQUERY);
	dw (0);

}
예제 #23
0
파일: sana2.cpp 프로젝트: sunfirefox/WinUAE
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;
}
예제 #24
0
int
main(int argc, char *argv[])
{
	const char *fwname, *udevname;
	char msgdev[256], datadev[256];
	struct uath_fwmsg txmsg, rxmsg;
	char *txdata;
	struct stat sb;
	int msg, data, fw, timeout, b, c;
	int bufsize = 512, verbose = 0;
	ssize_t len;

	udevname = NULL;
	while ((c = getopt(argc, argv, "d:v")) != -1) {
		switch (c) {
		case 'd':
			udevname = optarg;
			break;
		case 'v':
			verbose = 1;
			break;
		default:
			usage();
			/*NOTREACHED*/
		}
	}
	argc -= optind;
	argv += optind;

	if (udevname == NULL)
		errx(-1, "No device name; use -d to specify the ugen device");
	if (argc > 1)
		usage();

	if (argc == 1)
		fwname = argv[0];
	else
		fwname = _PATH_FIRMWARE "/ar5523.bin";
	fw = open(fwname, O_RDONLY, 0);
	if (fw < 0)
		err(-1, "open(%s)", fwname);
	if (fstat(fw, &sb) < 0)
		err(-1, "fstat(%s)", fwname);
	txdata = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fw, 0);
	if (txdata == MAP_FAILED)
		err(-1, "mmap(%s)", fwname);
	len = sb.st_size;
	/* XXX verify device is an AR5005 part */
	if (getdevname(udevname, msgdev, datadev))
		err(-1, "getdevname error");

	msg = open(msgdev, O_RDWR, 0);
	if (msg < 0)
		err(-1, "open(%s)", msgdev);
	timeout = UATH_DATA_TIMEOUT;
	if (ioctl(msg, USB_SET_RX_TIMEOUT, &timeout) < 0)
		err(-1, "%s: USB_SET_RX_TIMEOUT(%u)", msgdev, UATH_DATA_TIMEOUT);
	if (ioctl(msg, USB_SET_RX_BUFFER_SIZE, &bufsize) < 0)
		err(-1, "%s: USB_SET_RX_BUFFER_SIZE(%u)", msgdev, bufsize);

	data = open(datadev, O_WRONLY, 0);
	if (data < 0)
		err(-1, "open(%s)", datadev);
	timeout = UATH_DATA_TIMEOUT;
	if (ioctl(data, USB_SET_TX_TIMEOUT, &timeout) < 0)
		err(-1, "%s: USB_SET_TX_TIMEOUT(%u)", datadev,
		    UATH_DATA_TIMEOUT);

	VERBOSE("Load firmware %s to %s\n", fwname, udevname);

	bzero(&txmsg, sizeof (struct uath_fwmsg));
	txmsg.flags = htobe32(UATH_WRITE_BLOCK);
	txmsg.total = htobe32(len);

	b = 0;
	while (len > 0) {
		int mlen;

		mlen = len;
		if (mlen > UATH_MAX_FWBLOCK_SIZE)
			mlen = UATH_MAX_FWBLOCK_SIZE;
		txmsg.remain = htobe32(len - mlen);
		txmsg.len = htobe32(mlen);

		/* send firmware block meta-data */
		VERBOSE("send block %2u: %zd bytes remaining", b, len - mlen);
		if (write(msg, &txmsg, sizeof(txmsg)) != sizeof(txmsg)) {
			VERBOSE("%s", "\n");
			err(-1, "error sending msg (%s)", msgdev);
			break;
		}

		/* send firmware block data */
		VERBOSE("%s", "\n             : data...");
		if (write(data, txdata, mlen) != mlen) {
			VERBOSE("%s", "\n");
			err(-1, "error sending data (%s)", datadev);
			break;
		}

		/* wait for ack from firmware */
		VERBOSE("%s", "\n             : wait for ack...");
		bzero(&rxmsg, sizeof(rxmsg));
		if (read(msg, &rxmsg, sizeof(rxmsg)) != sizeof(rxmsg)) {
			VERBOSE("%s", "\n");
			err(-1, "error reading msg (%s)", msgdev);
			break;
		}

		VERBOSE("flags=0x%x total=%d\n",
		    be32toh(rxmsg.flags), be32toh(rxmsg.rxtotal));
		len -= mlen;
		txdata += mlen;
		b++;
	}
	sleep(1);
	close(fw);
	close(msg);
	close(data);
	return 0;
}
예제 #25
0
파일: sana2.cpp 프로젝트: sunfirefox/WinUAE
static uae_u32 REGPARAM2 dev_open_2 (TrapContext *context)
{
	uaecptr ioreq = m68k_areg (regs, 1);
	uae_u32 unit = m68k_dreg (regs, 0);
	uae_u32 flags = m68k_dreg (regs, 1);
	uaecptr buffermgmt;
	struct s2devstruct *dev = gets2devstruct (unit);
	struct priv_s2devstruct *pdev = 0;
	int i;
	uaecptr tagp, tagpnext;

	if (!dev)
		return openfail (ioreq, IOERR_OPENFAIL);
	if (!initint(context))
		return openfail (ioreq, IOERR_SELFTEST);
	if (log_net)
		write_log (_T("opening %s:%d opencnt=%d ioreq=%08X\n"), SANA2NAME, unit, dev->opencnt, ioreq);
	if (get_word (ioreq + 0x12) < IOSTDREQ_SIZE)
		return openfail (ioreq, IOERR_BADLENGTH);
	if ((flags & SANA2OPF_PROM) && dev->opencnt > 0)
		return openfail (ioreq, IOERR_UNITBUSY);

	for (i = 0; i < MAX_OPEN_DEVICES; i++) {
		pdev = &pdevst[i];
		if (pdev->inuse == 0)
			break;
	}
	if (i == MAX_OPEN_DEVICES)
		return openfail (ioreq, IOERR_UNITBUSY);

	put_long (ioreq + 24, pdev - pdevst);
	pdev->unit = unit;
	pdev->flags = flags;
	pdev->inuse = 1;
	pdev->td = td ? td[unit] : NULL;
	pdev->promiscuous = (flags & SANA2OPF_PROM) ? 1 : 0;

	if (pdev->td == NULL || pdev->td->active == 0)
		return openfail (ioreq, IOERR_OPENFAIL);

	if (dev->opencnt == 0) {
		dev->unit = unit;
		dev->sysdata = xcalloc (uae_u8, ethernet_getdatalenght (pdev->td));
		if (!ethernet_open (pdev->td, dev->sysdata, dev, uaenet_gotdata, uaenet_getdata, pdev->promiscuous)) {
			xfree (dev->sysdata);
			dev->sysdata = NULL;
			return openfail (ioreq, IOERR_OPENFAIL);
		}
		write_log (_T("%s: initializing unit %d\n"), getdevname (), unit);
		dev->td = pdev->td;
		dev->adapter = pdev->td ? pdev->td->active : 0;
		if (dev->adapter) {
			dev->online = 1;
			dev->configured = 1;
		}
		start_thread (dev);
	}

	if (kickstart_version >= 36) {
		m68k_areg (regs, 0) = get_long (4) + 350;
		m68k_areg (regs, 1) = timerdevname;
		CallLib (context, get_long (4), -0x114); /* FindName('timer.device') */
		pdev->timerbase = m68k_dreg (regs, 0);
	}

	pdev->copyfrombuff = pdev->copytobuff = pdev->packetfilter = 0;
	pdev->tempbuf = 0;
	if (get_word (ioreq + 0x12) >= SANA2_IOREQSIZE) {
		buffermgmt = get_long (ioreq + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4 + 4 + 4);
		tagpnext = buffermgmt;
		while (tagpnext) {
			uae_u32 tag = get_long (tagpnext);
			uae_u32 val = get_long (tagpnext + 4);
			tagp = tagpnext;
			tagpnext += 8;
			switch (tag)
			{
			case TAG_DONE:
				tagpnext = 0;
				break;
			case TAG_IGNORE:
				break;
			case TAG_MORE:
				tagpnext = val;
				break;
			case TAG_SKIP:
				tagpnext = tagp + val * 8;
				break;
			case S2_CopyToBuff:
				pdev->copytobuff = val;
				break;
			case S2_CopyFromBuff:
				pdev->copyfrombuff = val;
				break;
			case S2_PacketFilter:
				pdev->packetfilter = val;
				break;
			}
		}
		if (log_net)
			write_log (_T("%s:%d CTB=%08x CFB=%08x PF=%08x\n"),
			getdevname(), unit, pdev->copytobuff, pdev->copyfrombuff, pdev->packetfilter);
		m68k_dreg (regs, 0) = dev->td->mtu + ETH_HEADER_SIZE + 2;
		m68k_dreg (regs, 1) = 1;
		pdev->tempbuf = CallLib (context, get_long (4), -0xC6); /* AllocMem */
		if (!pdev->tempbuf) {
			if (dev->opencnt == 0) {
				ethernet_close (pdev->td, dev->sysdata);
				xfree (dev->sysdata);
				dev->sysdata = NULL;
			}
			return openfail (ioreq, S2ERR_BAD_ARGUMENT);
		}
		/* buffermanagement */
		put_long (ioreq + 32 + 4 + 4 + SANA2_MAX_ADDR_BYTES * 2 + 4 + 4 + 4, pdev->tempbuf);
	}
	dev->exclusive = flags & SANA2OPF_MINE;
	dev->opencnt++;
	put_word (m68k_areg (regs, 6) + 32, get_word (m68k_areg (regs, 6) + 32) + 1);
	put_byte (ioreq + 31, 0);
	put_byte (ioreq + 8, 7);
	return 0;
}