Пример #1
0
int
getchar(void)
{
	struct AmigaIO *ior;
	char c = '\n';
	struct Console *mc = ConsoleBase;
	unsigned long ticks;
#ifdef SERCONSOLE
	int32_t r;
#endif

	mc->cnior->length = 1;
	mc->cnior->buf = &c;
	mc->cnior->cmd = Cmd_Rd;

	SendIO(mc->cnior);

	ticks = 10 * timelimit;
	do {
		if (timelimit == 0)
			ticks = 2;

		mc->tmior->cmd = Cmd_Addtimereq;
		mc->tmior->secs = 0;
		mc->tmior->usec = 100000;
		SendIO((struct AmigaIO *)mc->tmior);

		ior = WaitPort(mc->cnmp);
		if (ior == mc->cnior) {
			AbortIO((struct AmigaIO *)mc->tmior);
			ticks = 1;
		} else /* if (ior == mc->tmior) */ {
#ifdef SERCONSOLE
			if (use_serconsole) {
				r = RawMayGetChar();
				if (r != -1) {
					c = r;
					ticks = 1;
				}
			}
#endif
			if (ticks == 1)
				AbortIO((struct AmigaIO *)mc->cnior);
		}
		WaitIO((struct AmigaIO *)mc->tmior);

		--ticks;
	} while (ticks != 0);
	timelimit = 0;

	(void)WaitIO(mc->cnior);
	return c;
}
Пример #2
0
void schedule(int t, void (*callback)(void *p), void *p)
{
	struct nscallback *nscb;
	struct TimeVal tv;
	ULONG time_us = 0;

	if(schedule_list == NULL) return;

	nscb = AllocVec(sizeof(struct nscallback), MEMF_PRIVATE | MEMF_CLEAR);
	if(!nscb) return;

	time_us = t*10000; /* t converted to µs */

	nscb->tv.Seconds = time_us / 1000000;
	nscb->tv.Microseconds = time_us % 1000000;

	GetSysTime(&tv);
	AddTime(&nscb->tv,&tv); // now contains time when event occurs

	if(nscb->treq = AllocVec(sizeof(struct TimeRequest),MEMF_PRIVATE | MEMF_CLEAR))
	{
		*nscb->treq = *tioreq;
    	nscb->treq->Request.io_Command=TR_ADDREQUEST;
    	nscb->treq->Time.Seconds=nscb->tv.Seconds; // secs
    	nscb->treq->Time.Microseconds=nscb->tv.Microseconds; // micro
    	SendIO((struct IORequest *)nscb->treq);
	}

	nscb->callback = callback;
	nscb->p = p;

	pblHeapInsert(schedule_list, nscb);
}
Пример #3
0
void conreqtkn(void)
{
	conreadreq->io_Command= CMD_READ;
	conreadreq->io_Data = (APTR)&coninput;
	conreadreq->io_Length = 1;
	SendIO((struct IORequest *)conreadreq);
}
Пример #4
0
void Sys_Net_Wait(struct SysNetData *netdata, struct SysSocket *socket, unsigned int timeout_us)
{
	fd_set rfds;
	ULONG sigmask;

	WaitIO((struct IORequest *)netdata->timerrequest);

	if (SetSignal(0, 0) & (1<<netdata->timerport->mp_SigBit))
		Wait(1<<netdata->timerport->mp_SigBit);

	FD_ZERO(&rfds);
	FD_SET(socket->s, &rfds);

	netdata->timerrequest->tr_node.io_Command = TR_ADDREQUEST;
	netdata->timerrequest->tr_time.tv_secs = timeout_us / 1000000;
	netdata->timerrequest->tr_time.tv_micro = timeout_us % 1000000;

	SendIO((struct IORequest *)netdata->timerrequest);

	sigmask = 1<<netdata->timerport->mp_SigBit;

	WaitSelect(socket->s + 1, &rfds, 0, 0, 0, &sigmask);

	AbortIO((struct IORequest *)netdata->timerrequest);
}
Пример #5
0
/* Waits for a signal or a timeout */
ULONG ata_WaitTO(struct IORequest* tmr, ULONG secs, ULONG micro, ULONG sigs)
{
    ULONG sig = 1 << tmr->io_Message.mn_ReplyPort->mp_SigBit;

    D(struct Node *t = (struct Node *)FindTask(NULL));
    D(bug("[ATA  ] Timed wait %lds %ldu (task='%s')\n", secs, micro,
        t->ln_Name));

    tmr->io_Command = TR_ADDREQUEST;
    ((struct timerequest*)tmr)->tr_time.tv_secs = secs;
    ((struct timerequest*)tmr)->tr_time.tv_micro = micro;

    SendIO(tmr);
    D(bug("[ATA  ] Preset signals: %lx ('%s')\n", SetSignal(0, 0), t->ln_Name));
    D(bug("[ATA  ] Signals requested: %lx ('%s')\n", sigs, t->ln_Name));
    D(bug("[ATA  ] Timer signal: %lx ('%s')\n", sig, t->ln_Name));
    sigs = Wait(sigs | sig);
    D(bug("[ATA  ] Signals received: %lx ('%s')\n", sigs, t->ln_Name));
    if (0 == (sigs & sig))
    {
	if (!CheckIO(tmr))
	    AbortIO(tmr);
    }
    WaitIO(tmr);

    SetSignal(0, sig);

    return sigs & ~sig;
}
Пример #6
0
void CSleep(int milliseconds)
{
	#if defined(PSP)
		sceKernelDelayThread(milliseconds * 1000);
	#elif defined(__BEOS__)
		snooze(milliseconds * 1000);
	#elif defined(__AMIGA__)
	{
		ULONG signals;
		ULONG TimerSigBit = 1 << TimerPort->mp_SigBit;

		/* send IORequest */
		TimerRequest->tr_node.io_Command = TR_ADDREQUEST;
		TimerRequest->tr_time.tv_secs    = (milliseconds * 1000) / 1000000;
		TimerRequest->tr_time.tv_micro   = (milliseconds * 1000) % 1000000;
		SendIO((struct IORequest *)TimerRequest);

		if (!((signals = Wait(TimerSigBit | SIGBREAKF_CTRL_C)) & TimerSigBit) ) {
			AbortIO((struct IORequest *)TimerRequest);
		}
		WaitIO((struct IORequest *)TimerRequest);
	}
	#else
		usleep(milliseconds * 1000);
	#endif
}
Пример #7
0
int sendtocon(char *pekare, int size)
{
	struct IntuiMessage *mymess;
	struct NiKMess *nikmess;
	int aborted = FALSE, paused=FALSE;
	ULONG signals,conwritesig = 1L << conwriteport->mp_SigBit,
		conreadsig = 1L << conreadport->mp_SigBit,windsig = 1L << NiKwind->UserPort->mp_SigBit,
		nikomnodesig = 1L << nikomnodeport->mp_SigBit;
	char console = 1, tecken;

	conwritereq->io_Command=CMD_WRITE;
	conwritereq->io_Data=(APTR)pekare;
	conwritereq->io_Length=size;
	SendIO((struct IORequest *)conwritereq);
	while(console)
	{
		signals = Wait(conwritesig | conreadsig | windsig | nikomnodesig);
		if(signals & conwritesig) {
			console=0;
			if(WaitIO((struct IORequest *)conwritereq)) printf("Error console\n");
		}
		if(signals & conreadsig) {
			if((tecken=congettkn()) == 3) {
				if(console) {
					AbortIO((struct IORequest *)conwritereq);
					WaitIO((struct IORequest *)conwritereq);
				}
				aborted=TRUE;
				console=0;
				putstring("^C\n\r",-1,0);
			} else if((tecken==' ' && (Servermem->inne[nodnr].flaggor & MELLANSLAG)) || tecken==19) paused=TRUE;
			else if(tecken && typeaheadbuftkn<50) {
				typeaheadbuf[typeaheadbuftkn++]=tecken;
				typeaheadbuf[typeaheadbuftkn]=0;
			}
		}
		if(signals & windsig) {
			mymess=(struct IntuiMessage *)GetMsg(NiKwind->UserPort);
			ReplyMsg((struct Message *)mymess);
			cleanup(OK,"");
		}
		if(signals & nikomnodesig) {
			while(nikmess = (struct NiKMess *) GetMsg(nikomnodeport)) {
				handleservermess(nikmess);
				ReplyMsg((struct Message *)nikmess);
			}
			if(carrierdropped()) aborted = TRUE;
		}
	}
	if(paused && gettekn()==3)
	{
		putstring("^C\n\r",-1,0);
		return(TRUE);
	}

	return(aborted);
}
Пример #8
0
long __saveds __regargs nik_sread(char *databuffer,long size,long timeout) {
    ULONG signals,sersig=1L << serreadport->mp_SigBit,
                  timersig=1L << timerport->mp_SigBit;
    if(timeout) {
        serreadreq->IOSer.io_Command=CMD_READ;
        serreadreq->IOSer.io_Length=size;
        serreadreq->IOSer.io_Data=(APTR)databuffer;
        SendIO((struct IORequest *)serreadreq);
        timerreq->tr_node.io_Command=TR_ADDREQUEST;
        timerreq->tr_time.tv_secs=timeout/1000000;
        timerreq->tr_time.tv_micro=timeout%1000000;
        timerreq->tr_node.io_Message.mn_ReplyPort=timerport;
        SendIO((struct IORequest *)timerreq);
        for(;;) {
            signals=Wait(sersig | timersig);
            if((signals & sersig) && CheckIO((struct IORequest *)serreadreq)) {
                WaitIO((struct IORequest *)serreadreq);
                AbortIO((struct IORequest *)timerreq);
                WaitIO((struct IORequest *)timerreq);
                if(serreadreq->IOSer.io_Error || carrierdropped()) return(-1L);
                return((long)serreadreq->IOSer.io_Actual);
            }
            if((signals & timersig) && CheckIO((struct IORequest *)timerreq)) {
                WaitIO((struct IORequest *)timerreq);
                AbortIO((struct IORequest *)serreadreq);
                WaitIO((struct IORequest *)serreadreq);
                /* printf("Timeout! Size=%d Timeout=%d Actual=%d",size,timeout,serreadreq->IOSer.io_Actual); */
                return((long)serreadreq->IOSer.io_Actual);
            }
        }
    } else {
        serreadreq->IOSer.io_Command=SDCMD_QUERY;
        DoIO((struct IORequest *)serreadreq);
        serreadreq->IOSer.io_Command=CMD_READ;
        if(serreadreq->IOSer.io_Actual > size) serreadreq->IOSer.io_Length=size;
        else serreadreq->IOSer.io_Length=serreadreq->IOSer.io_Actual;
        serreadreq->IOSer.io_Data=(APTR)databuffer;
        DoIO((struct IORequest *)serreadreq);
        return((long)serreadreq->IOSer.io_Actual);
    }
}
Пример #9
0
LONG addChangeInt(struct AFSBase *afsbase, struct IOHandle *ioh) {

	ioh->mc_int.is_Code = (VOID_FUNC)changeIntCode;
	ioh->mc_int.is_Data = ioh;
	ioh->iochangeint->iotd_Req.io_Command = TD_ADDCHANGEINT;
	ioh->iochangeint->iotd_Req.io_Flags = 0;
	ioh->iochangeint->iotd_Req.io_Length = sizeof(struct Interrupt);
	ioh->iochangeint->iotd_Req.io_Data = &ioh->mc_int;
	ioh->iochangeint->iotd_Req.io_Error = 0;
	SendIO((struct IORequest *)&ioh->iochangeint->iotd_Req);
	return ioh->iochangeint->iotd_Req.io_Error;
}
Пример #10
0
static int GM_UNIQUENAME(Init)(LIBBASETYPEPTR LIBBASE)
{
    /* Setup the timer.device data */
    LIBBASE->tb_CurrentTime.tv_secs = 0;
    LIBBASE->tb_CurrentTime.tv_micro = 0;
    LIBBASE->tb_VBlankTime.tv_secs = 0;
    LIBBASE->tb_VBlankTime.tv_micro = 1000000 / (SysBase->VBlankFrequency * SysBase->PowerSupplyFrequency);
    LIBBASE->tb_Elapsed.tv_secs = 0;
    LIBBASE->tb_Elapsed.tv_micro = 0;

    D(kprintf("Timer period: %ld secs, %ld micros\n",
	LIBBASE->tb_VBlankTime.tv_secs, LIBBASE->tb_VBlankTime.tv_micro));

    LIBBASE->tb_MiscFlags = TF_GO;

    /* Initialise the lists */
    NEWLIST( &LIBBASE->tb_Lists[0] );
    NEWLIST( &LIBBASE->tb_Lists[1] );
    NEWLIST( &LIBBASE->tb_Lists[2] );
    NEWLIST( &LIBBASE->tb_Lists[3] );
    NEWLIST( &LIBBASE->tb_Lists[4] );

    /* Start the timer2 */
    outb((inb(0x61) & 0xfd) | 1, 0x61); /* Enable the timer (set GATE on) */
    outb(0xb6, 0x43);   /* Binary mode on Timer2, count mode 3? */
    outb(0x00, 0x42);   /* We're counting whole range */
    outb(0x00, 0x42);

    LIBBASE->tb_prev_tick = 0xffff;

    /* Start up the interrupt server. This is shared between us and the
	HIDD that deals with the vblank */
    LIBBASE->tb_VBlankInt.is_Node.ln_Pri = 0;
    LIBBASE->tb_VBlankInt.is_Node.ln_Type = NT_INTERRUPT;
    LIBBASE->tb_VBlankInt.is_Node.ln_Name = (STRPTR)MOD_NAME_STRING;
    LIBBASE->tb_VBlankInt.is_Code = (APTR)&VBlankInt;
    LIBBASE->tb_VBlankInt.is_Data = LIBBASE;

    AddIntServer(INTB_TIMERTICK, &LIBBASE->tb_VBlankInt);

    /* VBlank EMU */

    LIBBASE->tb_vblank_timerequest.tr_node.io_Command = TR_ADDREQUEST;
    LIBBASE->tb_vblank_timerequest.tr_node.io_Device = (struct Device *)TimerBase;
    LIBBASE->tb_vblank_timerequest.tr_node.io_Unit = (struct Unit *)UNIT_MICROHZ;
    LIBBASE->tb_vblank_timerequest.tr_time.tv_secs = 0;
    LIBBASE->tb_vblank_timerequest.tr_time.tv_micro = 1000000 / SysBase->VBlankFrequency;

    SendIO(&LIBBASE->tb_vblank_timerequest.tr_node);

    return TRUE;
}
Пример #11
0
static void
ti_StartTimer(SyncTimer *st)
{
    st->st_Pkt->dp_Type = ACTION_TIMER;
    
    st->st_Req->Request.io_Command = TR_ADDREQUEST;
    st->st_Req->Time.Seconds = SYNC_TIME;
    st->st_Req->Time.Microseconds = 0;

    SendIO(&st->st_Req->Request);

    st->st_Flags |= STF_TIMER_USED;
}
Пример #12
0
void RestartTimer(void)
{
    if (glob->timer_active) {
        D(bug("Queuing timer restart\n"));
        glob->restart_timer = 1;
    } else {
        D(bug("Immediate timer restart\n"));
        glob->timereq->tr_node.io_Command = TR_ADDREQUEST;
        glob->timereq->tr_time.tv_secs = 2;
        glob->timereq->tr_time.tv_micro = 0;
        SendIO((struct IORequest *)glob->timereq);
        glob->timer_active = 1;
    }
}
Пример #13
0
__stkargs int start_timer(struct timeval * tv, struct timerequest * tr)
{
    if (!tr) {
	printf("no request structure\n");
	return 0;
    }
    if (tv->tv_secs == 0L && tv->tv_micro < 2L)
	tv->tv_micro = 2L;	/* minimal delay */

    tr->tr_time = *tv;
    tr->tr_node.io_Command = TR_ADDREQUEST;

    SendIO((struct IORequest *) tr);
    return 1;
}
Пример #14
0
static void rem_resethandler(void)
{
  if (rhdata->ioreq)
  {
    if (rhdata->handleradded)
    {
      if (rhdata->rebooting)
      {
        rhdata->timereq.tr_node.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
        rhdata->timereq.tr_node.io_Message.mn_Node.ln_Pri  = 0;
        rhdata->timereq.tr_node.io_Message.mn_ReplyPort    = rhdata->msgport;
        rhdata->timereq.tr_node.io_Message.mn_Length       = sizeof(rhdata->timereq);

        if (OpenDevice(TIMERNAME, UNIT_VBLANK, &rhdata->timereq.tr_node, 0) == 0)
        {
          rhdata->timereq.tr_node.io_Command = TR_ADDREQUEST;
          rhdata->timereq.tr_time.tv_secs    = 3;
          rhdata->timereq.tr_time.tv_micro   = 0;

          SendIO(&rhdata->timereq.tr_node);
          rhdata->timing = TRUE;
        }

        return;
      }

      rhdata->handleradded = FALSE;

      rhdata->ioreq->io_Command = KBD_REMRESETHANDLER;
      rhdata->ioreq->io_Data    = (APTR) &rhdata->is;
      DoIO((struct IORequest *) rhdata->ioreq);

      CloseDevice((struct IORequest *) rhdata->ioreq);
    }

    DeleteIORequest((struct IORequest *) rhdata->ioreq); rhdata->ioreq = NULL;
  }

  if (rhdata->msgport)
  {
    DeleteMsgPort(rhdata->msgport); rhdata->msgport = NULL;
  }
}
Пример #15
0
struct SysNetData *Sys_Net_Init()
{
	struct SysNetData *netdata;

	netdata = AllocVec(sizeof(*netdata), MEMF_ANY);
	if (netdata)
	{
		SocketBase = OpenLibrary("bsdsocket.library", 0);
		if (SocketBase)
		{
			netdata->timerport = CreateMsgPort();
			if (netdata->timerport)
			{
				netdata->timerrequest = (struct timerequest *)CreateIORequest(netdata->timerport, sizeof(*netdata->timerrequest));
				if (netdata->timerrequest)
				{
					if (OpenDevice(TIMERNAME, UNIT_MICROHZ, (struct IORequest *)netdata->timerrequest, 0) == 0)
					{
						netdata->timerrequest->tr_node.io_Command = TR_ADDREQUEST;
						netdata->timerrequest->tr_time.tv_secs = 1;
						netdata->timerrequest->tr_time.tv_micro = 0;
						SendIO((struct IORequest *)netdata->timerrequest);
						AbortIO((struct IORequest *)netdata->timerrequest);

						return netdata;
					}

					DeleteIORequest((struct IORequest *)netdata->timerrequest);
				}

				DeleteMsgPort(netdata->timerport);
			}

			CloseLibrary(SocketBase);
		}

		FreeVec(netdata);
	}

	return 0;
}
Пример #16
0
ULONG sdcard_WaitTO(struct IORequest* tmr, ULONG secs, ULONG micro, ULONG sigs)
{
    ULONG sig = 1 << tmr->io_Message.mn_ReplyPort->mp_SigBit;

    tmr->io_Command = TR_ADDREQUEST;
    ((struct timerequest*)tmr)->tr_time.tv_secs = secs;
    ((struct timerequest*)tmr)->tr_time.tv_micro = micro;

    SendIO(tmr);
    sigs = Wait(sigs | sig);
    if (0 == (sigs & sig))
    {
	if (!CheckIO(tmr))
	    AbortIO(tmr);
    }
    WaitIO(tmr);

    SetSignal(0, sig);

    return sigs &~ sig;
}
Пример #17
0
static void AHI_PlayAudio(_THIS)
{
	if(playing>1)
		WaitIO((struct IORequest *)audio_req[current_buffer]);

	/* Write the audio data out */
	audio_req[current_buffer] -> ahir_Std. io_Message.mn_Node.ln_Pri = 60;
	audio_req[current_buffer] -> ahir_Std. io_Data                = mixbuf[current_buffer];
	audio_req[current_buffer] -> ahir_Std. io_Length              = this->hidden->size;
	audio_req[current_buffer] -> ahir_Std. io_Offset              = 0;
	audio_req[current_buffer] -> ahir_Std . io_Command            = CMD_WRITE;
	audio_req[current_buffer] -> ahir_Frequency                   = this->hidden->freq;
	audio_req[current_buffer] -> ahir_Volume                      = 0x10000;
	audio_req[current_buffer] -> ahir_Type                        = this->hidden->type;
	audio_req[current_buffer] -> ahir_Position                    = 0x8000;
	audio_req[current_buffer] -> ahir_Link                        = (playing>0 ? audio_req[current_buffer^1] : NULL);

	SendIO((struct IORequest *)audio_req[current_buffer]);
	current_buffer^=1;

	playing++;
}
Пример #18
0
__saveds void ASERDPort::serial_func(void)
{
	struct ASERDPort *obj = (ASERDPort *)proc_arg;
	struct MsgPort *proc_port = NULL, *io_port = NULL, *control_port = NULL;
	struct IOExtSer *read_io = NULL, *write_io = NULL, *control_io = NULL;
	uint8 orig_params[sizeof(struct IOExtSer)];
	bool opened = false;
	ULONG io_mask = 0, proc_port_mask = 0;

	// Default: error occured
	obj->proc_error = true;

	// Create message port for communication with main task
	proc_port = CreateMsgPort();
	if (proc_port == NULL)
		goto quit;
	proc_port_mask = 1 << proc_port->mp_SigBit;

	// Create message ports for serial.device I/O
	io_port = CreateMsgPort();
	if (io_port == NULL)
		goto quit;
	io_mask = 1 << io_port->mp_SigBit;
	control_port = CreateMsgPort();
	if (control_port == NULL)
		goto quit;

	// Create IORequests
	read_io = (struct IOExtSer *)CreateIORequest(io_port, sizeof(struct IOExtSer));
	write_io = (struct IOExtSer *)CreateIORequest(io_port, sizeof(struct IOExtSer));
	control_io = (struct IOExtSer *)CreateIORequest(control_port, sizeof(struct IOExtSer));
	if (read_io == NULL || write_io == NULL || control_io == NULL)
		goto quit;
	read_io->IOSer.io_Message.mn_Node.ln_Type = 0;	// Avoid CheckIO() bug
	write_io->IOSer.io_Message.mn_Node.ln_Type = 0;
	control_io->IOSer.io_Message.mn_Node.ln_Type = 0;

	// Parse device name
	char dev_name[256];
	ULONG dev_unit;
	if (sscanf(obj->device_name, "%[^/]/%ld", dev_name, &dev_unit) < 2)
		goto quit;

	// Open device
	if (obj->is_parallel)
		((IOExtPar *)read_io)->io_ParFlags = PARF_SHARED;
	else
		read_io->io_SerFlags = SERF_SHARED | SERF_7WIRE;
	if (OpenDevice((UBYTE *) dev_name, dev_unit, (struct IORequest *)read_io, 0) || read_io->IOSer.io_Device == NULL)
		goto quit;
	opened = true;

	// Copy IORequests
	memcpy(write_io, read_io, sizeof(struct IOExtSer));
	memcpy(control_io, read_io, sizeof(struct IOExtSer));

	// Attach control_io to control_port and set default values
	control_io->IOSer.io_Message.mn_ReplyPort = control_port;
	if (!obj->is_parallel) {
		control_io->io_CtlChar = SER_DEFAULT_CTLCHAR;
		control_io->io_RBufLen = 64;
		control_io->io_ExtFlags = 0;
		control_io->io_Baud = 9600;
		control_io->io_BrkTime = 250000;
		control_io->io_ReadLen = control_io->io_WriteLen = 8;
		control_io->io_StopBits = 1;
		control_io->io_SerFlags = SERF_SHARED;
		control_io->IOSer.io_Command = SDCMD_SETPARAMS;
		DoIO((struct IORequest *)control_io);
		memcpy(orig_params, &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar));
	}

	// Initialization went well, inform main task
	obj->proc_port = proc_port;
	obj->control_io = control_io;
	obj->proc_error = false;
	Signal(MainTask, SIGF_SINGLE);

	// Main loop
	for (;;) {

		// Wait for I/O and messages (CTRL_C is used for quitting the task)
		ULONG sig = Wait(proc_port_mask | io_mask | SIGBREAKF_CTRL_C);

		// Main task wants to quit us
		if (sig & SIGBREAKF_CTRL_C)
			break;

		// Main task sent a command to us
		if (sig & proc_port_mask) {
			struct SerMessage *msg;
			while (msg = (SerMessage *)GetMsg(proc_port)) {
				D(bug("serial_proc received %08lx\n", msg->what));
				switch (msg->what) {
					case MSG_QUERY:
						control_io->IOSer.io_Command = SDCMD_QUERY;
						DoIO((struct IORequest *)control_io);
						D(bug(" query returned %08lx, actual %08lx\n", control_io->IOSer.io_Error, control_io->IOSer.io_Actual));
						break;

					case MSG_SET_PARAMS:
						// Only send SDCMD_SETPARAMS when configuration has changed
						if (memcmp(orig_params, &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar))) {
							memcpy(orig_params, &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar));
							memcpy(&(read_io->io_CtlChar), &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar));
							memcpy(&(write_io->io_CtlChar), &(control_io->io_CtlChar), (uint8 *)&(control_io->io_Status) - (uint8 *)&(control_io->io_CtlChar));
							control_io->IOSer.io_Command = SDCMD_SETPARAMS;
							D(bug(" params %08lx %08lx %08lx %08lx %08lx %08lx\n", control_io->io_CtlChar, control_io->io_RBufLen, control_io->io_ExtFlags, control_io->io_Baud, control_io->io_BrkTime, *(uint32 *)((uint8 *)control_io + 76)));
							DoIO((struct IORequest *)control_io);
							D(bug(" set_parms returned %08lx\n", control_io->IOSer.io_Error));
						}
						break;

					case MSG_SET_PAR_PARAMS:
						control_io->IOSer.io_Command = PDCMD_SETPARAMS;
						DoIO((struct IORequest *)control_io);
						D(bug(" set_par_parms returned %08lx\n", control_io->IOSer.io_Error));
						break;

					case MSG_BREAK:
						control_io->IOSer.io_Command = SDCMD_BREAK;
						DoIO((struct IORequest *)control_io);
						D(bug(" break returned %08lx\n", control_io->IOSer.io_Error));
						break;

					case MSG_RESET:
						control_io->IOSer.io_Command = CMD_RESET;
						DoIO((struct IORequest *)control_io);
						D(bug(" reset returned %08lx\n", control_io->IOSer.io_Error));
						break;

					case MSG_KILL_IO:
						AbortIO((struct IORequest *)read_io);
						AbortIO((struct IORequest *)write_io);
						WaitIO((struct IORequest *)read_io);
						WaitIO((struct IORequest *)write_io);
						obj->read_pending = obj->write_pending = false;
						obj->read_done = obj->write_done = false;
						break;

					case MSG_PRIME_IN:
						read_io->IOSer.io_Message.mn_Node.ln_Name = (char *)msg->pb;
						read_io->IOSer.io_Data = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer));
						read_io->IOSer.io_Length = ReadMacInt32(msg->pb + ioReqCount);
						read_io->IOSer.io_Actual = 0;
						read_io->IOSer.io_Command = CMD_READ;
						D(bug("serial_proc receiving %ld bytes from %08lx\n", read_io->IOSer.io_Length, read_io->IOSer.io_Data));
						SendIO((struct IORequest *)read_io);
						break;

					case MSG_PRIME_OUT: {
						write_io->IOSer.io_Message.mn_Node.ln_Name = (char *)msg->pb;
						write_io->IOSer.io_Data = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer));
						write_io->IOSer.io_Length = ReadMacInt32(msg->pb + ioReqCount);
						write_io->IOSer.io_Actual = 0;
						write_io->IOSer.io_Command = CMD_WRITE;
						D(bug("serial_proc transmitting %ld bytes from %08lx\n", write_io->IOSer.io_Length, write_io->IOSer.io_Data));
#if MONITOR
						bug("Sending serial data:\n");
						uint8 *adr = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer));
						for (int i=0; i<len; i++) {
							bug("%02lx ", adr[i]);
						}
						bug("\n");
#endif
						SendIO((struct IORequest *)write_io);
						break;
					}
				}
				D(bug(" serial_proc replying\n"));
				ReplyMsg(msg);
			}
		}

		// I/O operation completed
		if (sig & io_mask) {
			struct IOExtSer *io;
			while (io = (struct IOExtSer *)GetMsg(io_port)) {
				if (io == read_io) {
					D(bug("read_io complete, %ld bytes received, error %ld\n", read_io->IOSer.io_Actual, read_io->IOSer.io_Error));
					uint32 pb = (uint32)read_io->IOSer.io_Message.mn_Node.ln_Name;
#if MONITOR
					bug("Receiving serial data:\n");
					uint8 *adr = Mac2HostAddr(ReadMacInt32(msg->pb + ioBuffer));
					for (int i=0; i<read_io->IOSer.io_Actual; i++) {
						bug("%02lx ", adr[i]);
					}
					bug("\n");
#endif
					WriteMacInt32(pb + ioActCount, read_io->IOSer.io_Actual);
					obj->conv_error(read_io, obj->input_dt);
					obj->read_done = true;
					SetInterruptFlag(INTFLAG_SERIAL);
					TriggerInterrupt();
				} else if (io == write_io) {
					D(bug("write_io complete, %ld bytes sent, error %ld\n", write_io->IOSer.io_Actual, write_io->IOSer.io_Error));
					uint32 pb = (uint32)write_io->IOSer.io_Message.mn_Node.ln_Name;
					WriteMacInt32(pb + ioActCount, write_io->IOSer.io_Actual);
					obj->conv_error(write_io, obj->output_dt);
					obj->write_done = true;
					SetInterruptFlag(INTFLAG_SERIAL);
					TriggerInterrupt();
				}
			}
		}
	}
quit:

	// Close everything
	if (opened) {
		if (CheckIO((struct IORequest *)write_io) == 0) {
			AbortIO((struct IORequest *)write_io);
			WaitIO((struct IORequest *)write_io);
		}
		if (CheckIO((struct IORequest *)read_io) == 0) {
			AbortIO((struct IORequest *)read_io);
			WaitIO((struct IORequest *)read_io);
		}
		CloseDevice((struct IORequest *)read_io);
	}
	if (control_io)
		DeleteIORequest(control_io);
	if (write_io)
		DeleteIORequest(write_io);
	if (read_io)
		DeleteIORequest(read_io);
	if (control_port)
		DeleteMsgPort(control_port);
	if (io_port)
		DeleteMsgPort(io_port);

	// Send signal to main task to confirm termination
	Forbid();
	Signal(MainTask, SIGF_SINGLE);
}
Пример #19
0
void IOFS_SendPkt(struct DosPacket *dp, struct MsgPort *replyport, struct DosLibrary *DOSBase)
{
    /*
     * Trying to emulate the packet system by rewriting the
     * packets to IO Requests. Sometimes there are too many
     * parameters in the packet but thats fine. If there are
     * not enough parameters or the wrong type etc. then
     * it is more difficult to translate the packet.
     *
     */

    struct IOFileSys  *iofs = AllocMem(sizeof(struct IOFileSys), MEMF_CLEAR);
    struct FileHandle *fh;
    BPTR               oldCurDir;
    LONG               result; 
     
    if (iofs != NULL)
    {
	/*
	 * Also attach the packet to the io request.
	 * Will remain untouched by the driver.
	 */

	iofs->io_PacketEmulation = dp;
    
	/*
	 * In case the packet is to be aborted 
	 * I know which IORequest to use. The user will
	 * use the packet itself to abort the operation.
	 */
	dp->dp_Arg7 = (IPTR)iofs;


	iofs->IOFS.io_Message.mn_Node.ln_Type = NT_REPLYMSG;
	iofs->IOFS.io_Message.mn_ReplyPort = replyport;
	iofs->IOFS.io_Message.mn_Length = sizeof(struct IOFileSys);
	iofs->IOFS.io_Flags = 0;

        /*
         * Have to rewrite this packet...
         */

        switch (dp->dp_Type)
	{
	case ACTION_NIL:
	case ACTION_READ_RETURN:
	case ACTION_WRITE_RETURN:
	case ACTION_TIMER:
	    kprintf("This packet is a reserved one and should not be sent"
		    " by you!\n");
	    // Alert();
	    return;
	    
	    // case ACTION_GET_BLOCK:
	case ACTION_DISK_CHANGE:
	case ACTION_DISK_TYPE:
	case ACTION_EVENT:
	case ACTION_SET_MAP:
	    
	    kprintf("This packet is obsolete. (ACTION type %d)\n",
		    dp->dp_Type);
	    return;


	case ACTION_FINDINPUT:      // Open() MODE_OLDFILE [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    
	    iofs->IOFS.io_Command = FSA_OPEN_FILE;
	    iofs->io_Union.io_OPEN_FILE.io_FileMode = FMF_WRITE | FMF_READ;
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg2);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg3),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		kprintf("Error: Didn't find file\n");
		return;
	    }
	    
	    kprintf("Returned from DoNameAsynch()\n");

	    break;
	    
	case ACTION_FINDOUTPUT:     // Open() MODE_NEWFILE [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    
	    iofs->IOFS.io_Command = FSA_OPEN_FILE;
	    iofs->io_Union.io_OPEN_FILE.io_FileMode = FMF_LOCK |
		FMF_CREATE | FMF_CLEAR | FMF_WRITE | FMF_READ;
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg2);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg3),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    	    
	    break;
	    

	case ACTION_FINDUPDATE:     // Open() MODE_READWRITE [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    
	    iofs->IOFS.io_Command = FSA_OPEN_FILE;
	    iofs->io_Union.io_OPEN_FILE.io_FileMode = FMF_CREATE |
		FMF_WRITE | FMF_READ;
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg2);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg3),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    	    
	    break;

	case ACTION_READ:           // Read() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_READ;
	    iofs->io_Union.io_READ_WRITE.io_Buffer = (APTR)dp->dp_Arg2;
	    iofs->io_Union.io_READ_WRITE.io_Length = (LONG)dp->dp_Arg3;
	    
	    break;


	case ACTION_WRITE:          // Write() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_WRITE;
	    iofs->io_Union.io_READ_WRITE.io_Buffer = (APTR)dp->dp_Arg2;
	    iofs->io_Union.io_READ_WRITE.io_Length = (LONG)dp->dp_Arg3;

	    break;

	case ACTION_SEEK:           // Seek()      [*] CH
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;

	    /* If the file is in write mode flush it. This is done
	       synchronously as otherwise the seek may be served before
	       the flush. (TODO: What are a reasonable semantics here?) */
	    if (fh->fh_Flags & FHF_WRITE)
	    {
		Flush(MKBADDR(fh));
	    }
	    else
	    {
		/* Read mode. Just reinit the buffers. We can't call
		   Flush() in this case as that would end up in recursion. */
		fh->fh_Pos = fh->fh_End = fh->fh_Buf;
	    }
	    
	    iofs->IOFS.io_Command = FSA_SEEK;
	    iofs->io_Union.io_SEEK.io_Offset = (QUAD)dp->dp_Arg2;
	    iofs->io_Union.io_SEEK.io_SeekMode = dp->dp_Arg3;
	    
	    break;
	    
	case ACTION_SET_FILE_SIZE:  // SetFileSize()        [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_SET_FILE_SIZE;
	    iofs->io_Union.io_SET_FILE_SIZE.io_Offset   = (QUAD)dp->dp_Arg2;
	    iofs->io_Union.io_SET_FILE_SIZE.io_SeekMode = dp->dp_Arg3;
	    break;

	case ACTION_EXAMINE_FH:     // ExamineFH()
	case ACTION_EXAMINE_OBJECT: // Examine() [*]  --  the same thing
	                            //                    in AROS
	    {
		UBYTE *buffer = AllocVec(sizeof(struct ExAllData), 
					 MEMF_PUBLIC | MEMF_CLEAR);

		if (buffer == NULL)
		{
		    dp->dp_Res1 = DOSFALSE;
		    dp->dp_Res2 = ERROR_NO_FREE_STORE;

		    return;
		}
		
		fh = (struct FileHandle *)dp->dp_Arg1;
		
		iofs->IOFS.io_Device = fh->fh_Device;
		iofs->IOFS.io_Unit   = fh->fh_Unit;
		
		iofs->IOFS.io_Command = FSA_EXAMINE;
		iofs->io_Union.io_EXAMINE.io_ead = (struct ExAllData *)buffer;
		iofs->io_Union.io_EXAMINE.io_Size = sizeof(struct ExAllData);
		iofs->io_Union.io_EXAMINE.io_Mode = ED_OWNER;

		/* A supplied FileInfoBlock (is a BPTR) is in dp_Arg2 */
		
		break;
	    }
	    
	case ACTION_EXAMINE_NEXT:   // ExNext() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_EXAMINE_NEXT;
	    iofs->io_Union.io_EXAMINE_NEXT.io_fib = (BPTR)dp->dp_Arg2;
	    
	    break;	    

	case ACTION_CREATE_DIR:     // CreateDir() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_CREATE_DIR;
	    iofs->io_Union.io_CREATE_DIR.io_Filename = BStrtoCStr((BSTR)dp->dp_Arg2);
	    iofs->io_Union.io_CREATE_DIR.io_Protection = 0;
	    
	    break;

	    
	case ACTION_DELETE_OBJECT:  // DeleteFile()     [*]
	    // ARG1:   LOCK    Lock to which ARG2 is relative
	    // ARG2:   BSTR    Name of object to delete (relative to ARG1)
	    
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    /* IFS_DELETE_OBJECT just consists of a STRPTR so we have to
	       use NameFromLock() here -- TODO */
	    // iofs->io_Union.io_DELETE_OBJECT.io_Filename = BStrtoCStr((BSTR)dp->dp_Arg2);
	    iofs->IOFS.io_Command = FSA_DELETE_OBJECT;
	    
	    break;

	case ACTION_RENAME_OBJECT:  // Rename()
	    /* TODO */
	    break;

	case ACTION_LOCK_RECORD:    // LockRecord()
	    fh = (struct FileHandle *)BADDR(dp->dp_Arg1);

	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit = fh->fh_Unit;

	    iofs->io_Union.io_RECORD.io_Offset = (QUAD)dp->dp_Arg2;
	    iofs->io_Union.io_RECORD.io_Size = (LONG)dp->dp_Arg3;
	    iofs->io_Union.io_RECORD.io_RecordMode = (LONG)dp->dp_Arg4;
	    iofs->io_Union.io_RECORD.io_Timeout = (LONG)dp->dp_Arg5;
	    break;
	    
	case ACTION_FREE_RECORD:    // UnlockRecord()
	    fh = (struct FileHandle *)BADDR(dp->dp_Arg1);
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit = fh->fh_Unit;

	    iofs->io_Union.io_RECORD.io_Offset = (QUAD)dp->dp_Arg2;
	    iofs->io_Union.io_RECORD.io_Size = (LONG)dp->dp_Arg3;
	    iofs->io_Union.io_RECORD.io_RecordMode = (LONG)dp->dp_Arg4;
	    break; 

	case ACTION_PARENT:         // ParentDir()     [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_OPEN;
	    iofs->io_Union.io_OPEN.io_FileMode = FMF_READ; // Shared lock
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg1);
	    result = DoNameAsynch(iofs, "/", DOSBase);
	    CurrentDir(oldCurDir);
	    
	    if (result != 0)
	    {
		return;
	    }

	    return;

	case ACTION_SET_PROTECT:    // SetProtection()    [*]
	    // STRPTR io_Filename;   /* The file to change. */
	    // ULONG  io_Protection; /* The new protection bits. */

	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    	
	    iofs->IOFS.io_Command = FSA_SET_PROTECT;
	    iofs->io_Union.io_SET_PROTECT.io_Protection = dp->dp_Arg4;
	    iofs->io_Union.io_SET_PROTECT.io_Filename = BStrtoCStr(dp->dp_Arg3);
		
	    break;
	    
	case ACTION_SET_COMMENT:    // SetComment()       [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_SET_COMMENT;
	    iofs->io_Union.io_SET_COMMENT.io_Filename = BStrtoCStr((BSTR)dp->dp_Arg3);
	    iofs->io_Union.io_SET_COMMENT.io_Comment = BStrtoCStr(dp->dp_Arg4);
	    
	    break;

	case ACTION_LOCATE_OBJECT:  // Lock()         [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_OPEN;
	    
	    switch (dp->dp_Arg3)
	    {
	    case EXCLUSIVE_LOCK:
		iofs->io_Union.io_OPEN.io_FileMode = FMF_LOCK | FMF_READ;
		break;
		
	    case SHARED_LOCK:
		iofs->io_Union.io_OPEN.io_FileMode = FMF_READ;
		break;
		
	    default:
		iofs->io_Union.io_OPEN.io_FileMode = dp->dp_Arg3;
		break;
	    }
	    
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg1);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg2),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    	    
	    dp->dp_Arg6 = (IPTR)AllocDosObject(DOS_FILEHANDLE, NULL);

	    if (dp->dp_Arg6 == (IPTR)NULL)
	    {
		return;
	    }

	    break;

	case ACTION_COPY_DIR:       // DupLock()
	case ACTION_COPY_DIR_FH:    // DupLockFromFH() -- the same thing
	                            //                    in AROS
	    fh = (struct FileHandle *)BADDR(dp->dp_Arg1);
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_OPEN;
	    
	    /* Create a shared lock */
	    iofs->io_Union.io_OPEN.io_FileMode = FMF_READ;
		
	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg1);
	    result = DoNameAsynch(iofs, "", DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    
	    dp->dp_Arg6 = (IPTR)AllocDosObject(DOS_FILEHANDLE, NULL);

	    if (dp->dp_Arg6 == (IPTR)NULL)
	    {
		return;
	    }

	    break;

	case ACTION_END:            // Close() [*]
	case ACTION_FREE_LOCK:      // UnLock() -- the same thing in AROS
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    /* If the filehandle has a pending write on it Flush() the buffer.
	       This is made synchronously... */
	    if (fh->fh_Flags & FHF_WRITE)
	    {
		Flush(MKBADDR(fh));
	    }

	    iofs->IOFS.io_Command = FSA_CLOSE;

	    break;

	case ACTION_SET_DATE:       // SetFileDate() [*]
	    fh = (struct FileHandle *)dp->dp_Arg2;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_SET_DATE;
	    memcpy(&iofs->io_Union.io_SET_DATE.io_Date, (APTR)dp->dp_Arg4,
		   sizeof(struct DateStamp));

	    oldCurDir = CurrentDir((BPTR)dp->dp_Arg2);
	    result = DoNameAsynch(iofs, BStrtoCStr((BSTR)dp->dp_Arg3),
				  DOSBase);
	    CurrentDir(oldCurDir);

	    if (result != 0)
	    {
		return;
	    }
	    	    
	    break;

	case ACTION_SAME_LOCK:      // SameLock() [*]
	    fh = (struct FileHandle *)dp->dp_Arg1;
	    
	    iofs->IOFS.io_Device = fh->fh_Device;
	    iofs->IOFS.io_Unit   = fh->fh_Unit;
	    
	    iofs->IOFS.io_Command = FSA_SAME_LOCK;
	    
	    iofs->io_Union.io_SAME_LOCK.io_Lock[0] = BADDR((BPTR)dp->dp_Arg1);
	    iofs->io_Union.io_SAME_LOCK.io_Lock[1] = BADDR((BPTR)dp->dp_Arg2);
	    
	    break;
	    
	case ACTION_MAKE_LINK:      // MakeLink()
	    {
		STRPTR name = BStrtoCStr(dp->dp_Arg2);
	    
		if (dp->dp_Arg4 == LINK_SOFT)
		{
		    /* We want a soft-link. */
		    iofs->IOFS.io_Command = FSA_CREATE_SOFTLINK;
		    iofs->io_Union.io_CREATE_SOFTLINK.io_Reference = (STRPTR)dp->dp_Arg3;
		}
		else
		{
		    /* We want a hard-link. */
		    struct FileHandle *fh = (struct FileHandle *)BADDR((BPTR)dp->dp_Arg3);
                    struct DevProc *dvp;

		    /* We check, if name and dest are on the same device. */
                    if ((dvp = GetDeviceProc(name, NULL)) == NULL)
		    {
			/* TODO: Simulate packet return */
			return;
		    }
		    
		    if (dvp->dvp_Port != (struct MsgPort *)fh->fh_Device)
		    {
                        FreeDeviceProc(dvp);
			SetIoErr(ERROR_RENAME_ACROSS_DEVICES);
			
			/* TODO: Simulate packet return */
			return;
		    }

                    FreeDeviceProc(dvp);
		    
		    iofs->IOFS.io_Command = FSA_CREATE_HARDLINK;
		    iofs->io_Union.io_CREATE_HARDLINK.io_OldFile = fh->fh_Unit;
		}
		
		oldCurDir = CurrentDir((BPTR)dp->dp_Arg1);
		DoNameAsynch(iofs, name, DOSBase);
		CurrentDir(oldCurDir);
	    }
	    
	    break;
	    
	case ACTION_READ_LINK:      // ReadLink()
	    /* TODO */
	    break;
	    
	case ACTION_EXAMINE_ALL:    // ExAll()
	    /* TODO */
	    break;
	    
	case ACTION_ADD_NOTIFY:     // StartNotify()
	    {
		struct NotifyRequest *notify = (struct NotifyRequest *)BADDR(dp->dp_Arg1);
	        struct FileHandle *dir;

		iofs->IOFS.io_Command = FSA_ADD_NOTIFY;
		iofs->io_Union.io_NOTIFY.io_NotificationRequest = notify;

		notify->nr_MsgCount = 0;

		if (strchr(notify->nr_Name, ':') != NULL)
		{
		    DoNameAsynch(iofs, notify->nr_Name, DOSBase);
		}
		else
		{
		    dir = BADDR(CurrentDir(NULL));
		    CurrentDir(MKBADDR(dir));	/* Set back the current dir */
		    
		    if (dir == NULL)
		    {
			return;
		    }
		    
		    iofs->IOFS.io_Device = dir->fh_Device;
		    iofs->IOFS.io_Unit = dir->fh_Unit;
		    
		    /* Save device for EndNotify() purposes */
		    notify->nr_Handler = (struct MsgPort *) dir->fh_Device;
	
		    if (iofs->IOFS.io_Device == NULL)
		    {
			return;
		    }
		}
	    }

	    break;
	    
	case ACTION_REMOVE_NOTIFY:  // EndNotify()
	    {
		struct NotifyRequest *notify = (struct NotifyRequest *)BADDR(dp->dp_Arg1);

		iofs->IOFS.io_Command = FSA_REMOVE_NOTIFY;
		iofs->io_Union.io_NOTIFY.io_NotificationRequest = notify;
		
		if (strchr(notify->nr_Name, ':'))
		{
		    DoNameAsynch(iofs, notify->nr_Name, DOSBase);
		}
		else
		{
		    iofs->IOFS.io_Device = (struct Device *)notify->nr_Handler;
		    
		    if (iofs->IOFS.io_Device == NULL)
		    {
			return;
		    }
		}
	    }

	    break;
	    

	    /* The following five packets are only relative to the
	       message port of the file system to send to. Therefore, 
	       we fill in only partial information in the IOFileSys and
	       hope for the best... Specifically, the device cannot
	       use iofs->io_Device. TODO */
	case ACTION_RENAME_DISK:    // Relabel()
	    /* TODO */
	    break;

	case ACTION_FORMAT:         // Format()
	    /* TODO */
	    break;
	    
	case ACTION_MORE_CACHE:     // AddBuffers()
	    /* TODO */
	    break;
	    
	case ACTION_INHIBIT:        // Inhibit()
	    /* TODO */
	    break;

	case ACTION_IS_FILESYSTEM:  // IsFileSystem()
	    /* TODO */
	    break;

	case ACTION_DISK_INFO:      // Info()
	    /* TODO */
	    break;

	case ACTION_INFO:           // No associated function
	    /* TODO */
	    break;

	case ACTION_CURRENT_VOLUME: // No associated function
	    /* TODO */
	    break;

	case ACTION_PARENT_FH:      // ParentOfFH()
	    /* TODO -- Should be the same as ACTION_PARENT? For some reason
	               ParentDir() and ParentOfFH() is implemented differently
	               in AROS. Have to investigate this further. */
	    break;
	    
	case ACTION_FH_FROM_LOCK:   // OpenFromLock()
	    /* TODO: Have so simulate ReplyMsg() here */
	    return;

	case ACTION_SET_OWNER:      // SetOwner()
	    // Unfortunately, I have no info regardning this packet.
	    
	    // iofs->IOFS.io_Command = FSA_SET_OWNER;
	    // iofs->io_Union.io_SET_OWNER.io_UID = owner_info >> 16;
	    // iofs->io_Union.io_SET_OWNER.io_GID = owner_info & 0xffff;
	    
	    break;

	case ACTION_CHANGE_MODE:    // ChangeMode()
	    /* TODO */
	    break;

	    /* I haven't looked into the following packets in detail */
	case ACTION_DIE:            // No associated function
	    break;
	    
	case ACTION_WRITE_PROTECT:  // No associated function
	    break;
	    
	case ACTION_FLUSH:          // No associated function
	    break;
	    
	case ACTION_SERIALIZE_DISK: // No associated function
	    break;
	    

	    // ---  Console only packets  ------------------------------
	    /* I think these should not be implemented as packets except
	       for ACTION_WAIT_CHAR which is not really a console only
	       packet. Instead functions should be added to console.device */

	case ACTION_SCREEN_MODE:    // SetMode()
	    /* TODO*/
	    break;
	    
	case ACTION_CHANGE_SIGNAL:  // No associated function
	    {
	    	struct MsgPort *msgport;
		struct Task    *task;
		
		fh = (struct FileHandle *)dp->dp_Arg1;
    	    	msgport = (struct MsgPort *)dp->dp_Arg2;
		task = msgport ? msgport->mp_SigTask : NULL;
		
		iofs->IOFS.io_Device = fh->fh_Device;
		iofs->IOFS.io_Unit   = fh->fh_Unit;

		iofs->IOFS.io_Command = FSA_CHANGE_SIGNAL;
		iofs->io_Union.io_CHANGE_SIGNAL.io_Task = task;
	    }
	    break;
	    
	case ACTION_WAIT_CHAR:      // WaitForChar()	
	    /* TODO */
	    break;

	default:
	    D(kprintf("Unknown packet type %d found in SendPkt()\n", dp->dp_Type));
            dp->dp_Res1 = DOSFALSE;
            dp->dp_Res2 = ERROR_ACTION_NOT_KNOWN;
            PutMsg(replyport, dp->dp_Link);
	    return;
	}

	D(kprintf("Calling SendIO() with command %u\n", iofs->IOFS.io_Command));
	
	SendIO((struct IORequest *)iofs);
    }        
 
}
Пример #20
0
int main(int argc, char *argv[])
{
  BYTE *p1=buffer1,*p2=buffer2;
  void *tmp;
  ULONG signals,length;
  struct AHIRequest *link = NULL;
  LONG priority = 0;
  BYTE pri;

  if(argc == 2)
  {
    StrToLong(argv[1], &priority);
  }
  pri = priority;
  Printf("Sound priority: %ld\n", pri);

  if((AHImp=CreateMsgPort()) != NULL) {
    if((AHIio=(struct AHIRequest *)CreateIORequest(AHImp,sizeof(struct AHIRequest))) != NULL) {
      AHIio->ahir_Version = 4;
      AHIDevice=OpenDevice(AHINAME,0,(struct IORequest *)AHIio,0);
    }
  }

  if(AHIDevice) {
    Printf("Unable to open %s/0 version 4\n",AHINAME);
    cleanup(RETURN_FAIL);
  }

// Make a copy of the request (for double buffering)
  AHIiocopy = AllocMem(sizeof(struct AHIRequest), MEMF_ANY);
  if(! AHIiocopy) {
    cleanup(RETURN_FAIL);
  }
  CopyMem(AHIio, AHIiocopy, sizeof(struct AHIRequest));
  AHIios[0]=AHIio;
  AHIios[1]=AHIiocopy;

  SetIoErr(0);

  for(;;) {

// Fill buffer
    length = Read(Input(),p1,BUFFERSIZE);

// Play buffer
    AHIios[0]->ahir_Std.io_Message.mn_Node.ln_Pri = pri;
    AHIios[0]->ahir_Std.io_Command  = CMD_WRITE;
    AHIios[0]->ahir_Std.io_Data     = p1;
    AHIios[0]->ahir_Std.io_Length   = length;
    AHIios[0]->ahir_Std.io_Offset   = 0;
    AHIios[0]->ahir_Frequency       = FREQUENCY;
    AHIios[0]->ahir_Type            = TYPE;
    AHIios[0]->ahir_Volume          = 0x10000;          // Full volume
    AHIios[0]->ahir_Position        = 0x8000;           // Centered
    AHIios[0]->ahir_Link            = link;
    SendIO((struct IORequest *) AHIios[0]);

    if(link) {

// Wait until the last buffer is finished (== the new buffer is started)
      signals=Wait(SIGBREAKF_CTRL_C | (1L << AHImp->mp_SigBit));

// Check for Ctrl-C and abort if pressed
      if(signals & SIGBREAKF_CTRL_C) {
        SetIoErr(ERROR_BREAK);
        break;
      }

// Remove the reply and abort on error
      if(WaitIO((struct IORequest *) link)) {
        SetIoErr(ERROR_WRITE_PROTECTED);
        break;
      }
    }

// Check for end-of-sound, and wait until it is finished before aborting
    if(length != BUFFERSIZE) {
      WaitIO((struct IORequest *) AHIios[0]);
      break;
    }

    link = AHIios[0];

// Swap buffer and request pointers, and restart
    tmp    = p1;
    p1     = p2;
    p2     = tmp;

    tmp    = AHIios[0];
    AHIios[0] = AHIios[1];
    AHIios[1] = tmp;
  }
  

// Abort any pending iorequests
  AbortIO((struct IORequest *) AHIios[0]);
  WaitIO((struct IORequest *) AHIios[0]);

  if(link) { // Only if the second request was started
    AbortIO((struct IORequest *) AHIios[1]);
    WaitIO((struct IORequest *) AHIios[1]);
  }

  if(IoErr()) {
    PrintFault(IoErr(), argv[0] );
    cleanup(RETURN_ERROR);
  }

  cleanup(RETURN_OK);
  return RETURN_OK; // Make compiler happy
}
Пример #21
0
void main(int argc, char *argv[])
{
  BYTE *p1=buffer1,*p2=buffer2,*tmp;
  ULONG signals;

  if(AHImp=CreateMsgPort()) {
    if(AHIio=(struct AHIRequest *)CreateIORequest(AHImp,sizeof(struct AHIRequest))) {
      AHIio->ahir_Version = 4;
      AHIDevice=OpenDevice(AHINAME,0,(struct IORequest *)AHIio,NULL);
    }
  }

  if(AHIDevice) {
    Printf("Unable to open %s/0 version 4\n",AHINAME);
    cleanup(RETURN_FAIL);
  }

// Initialize the first read
  AHIio->ahir_Std.io_Command=CMD_READ;
  AHIio->ahir_Std.io_Data=&buffer1;
  AHIio->ahir_Std.io_Length=BUFFERSIZE;
  AHIio->ahir_Std.io_Offset=0;
  AHIio->ahir_Frequency=FREQUENCY;
  AHIio->ahir_Type=TYPE;
  if(!DoIO((struct IORequest *) AHIio)) {

// The first buffer is now filled
    SetIoErr(NULL);

    for(;;) {
      ULONG length;
      
      length=AHIio->ahir_Std.io_Actual;

// Initialize the second read (note that io_Offset is not cleared!)
      AHIio->ahir_Std.io_Data=p2;
      AHIio->ahir_Std.io_Length=BUFFERSIZE;
      AHIio->ahir_Frequency=FREQUENCY;
      AHIio->ahir_Type=TYPE;
      SendIO((struct IORequest *) AHIio);

// While the second read is in progress, save the first buffer to stdout
      if(Write(Output(),p1,length) != length) {
        break;
      }

      signals=Wait(SIGBREAKF_CTRL_C | (1L << AHImp->mp_SigBit));

      if(signals & SIGBREAKF_CTRL_C) {
        SetIoErr(ERROR_BREAK);
        break;
      }

// Remove the reply 
      if(WaitIO((struct IORequest *) AHIio)) {
        SetIoErr(ERROR_READ_PROTECTED);
        break;
      }

// Swap buffer pointers and repeat
      tmp=p1;
      p1=p2;
      p2=tmp;
    }

// Abort any pending iorequests
    AbortIO((struct IORequest *) AHIio);
    WaitIO((struct IORequest *) AHIio);
  }

  if(IoErr())
  {
    PrintFault(IoErr(), argv[0] ); // Oh, common! It's not MY fault that this
                                   // routine prints to stdout instead of stderr!
    cleanup(RETURN_ERROR);
  }

  cleanup(RETURN_OK);
}
Пример #22
0
static void
Slave( struct ExecBase* SysBase )
{
  struct AHIAudioCtrlDrv* AudioCtrl;
  struct DriverBase*      AHIsubBase;
  struct DeviceBase* DeviceBase;
  BOOL                    running;
  ULONG                   signals;

  AudioCtrl  = (struct AHIAudioCtrlDrv*) FindTask( NULL )->tc_UserData;
  AHIsubBase = (struct DriverBase*) dd->ahisubbase;
  DeviceBase = (struct DeviceBase*) AHIsubBase;

  dd->slavesignal = AllocSignal( -1 );

  if( dd->slavesignal != -1 )
  {
    struct MsgPort*    ahi_mp           = NULL;
    struct AHIRequest* ahi_iorequest    = NULL;
    APTR               ahi_iocopy       = NULL;
    BYTE               ahi_device       = -1;

    struct AHIRequest* ahi_io[ 2 ]      = { NULL,  NULL };
    BOOL               ahi_io_used[ 2 ] = { FALSE, FALSE };

    ULONG              frame_length     = 0;

    ahi_mp = CreateMsgPort();

    if( ahi_mp != NULL )
    {
      ahi_iorequest = CreateIORequest( ahi_mp, sizeof( struct AHIRequest ) );

      if( ahi_iorequest != NULL )
      {
	ahi_iorequest->ahir_Version = 4;

	ahi_device = OpenDevice( AHINAME, dd->unit,
				 (struct IORequest*) ahi_iorequest, 0 );

	if( ahi_device == 0 )
	{
	  struct Library* AHIBase = (struct Library*) ahi_iorequest->ahir_Std.io_Device;

	  ahi_iocopy = AllocVec( sizeof( *ahi_iorequest ), MEMF_ANY );

	  if( ahi_iocopy != NULL )
	  {
	    bcopy( ahi_iorequest, ahi_iocopy, sizeof( *ahi_iorequest ) );

	    ahi_io[ 0 ] = ahi_iorequest;
	    ahi_io[ 1 ] = ahi_iocopy;
    
	    // Everything set up. Tell Master we're alive and healthy.

	    Signal( (struct Task*) dd->mastertask,
		    1L << dd->mastersignal );

	    running = TRUE;

	    // The main playback loop follow

	    while( running )
	    {
	      int skip_mix;
	      APTR tmp_buff;
	      struct AHIRequest* tmp_io;
	      
	      if( ahi_io_used[ 0 ] )
	      {
		LONG  err;
		ULONG mask = ( SIGBREAKF_CTRL_C |
			       (1L << dd->slavesignal) |
			       (1L << ahi_mp->mp_SigBit) );
	      
		signals = Wait( mask );

		if( signals & ( SIGBREAKF_CTRL_C |
				(1L << dd->slavesignal) ) ) 
		{
		  running = FALSE;
		  break;
		}

		err = WaitIO( (struct IORequest*) ahi_io[ 0 ] );

		if( err != 0 )
		{
		  KPrintF( DRIVER ": AHI device error %ld\n", err );
//		  running = FALSE;
		  break;
		}
	      }

	      skip_mix = CallHookPkt( AudioCtrl->ahiac_PreTimerFunc,
				      (Object*) AudioCtrl, 0 );

	      CallHookPkt( AudioCtrl->ahiac_PlayerFunc, AudioCtrl, NULL );
		
	      if( ! skip_mix )
	      {
		CallHookPkt( AudioCtrl->ahiac_MixerFunc, AudioCtrl,
			     dd->mixbuffers[ 0 ] );
	      }
		
	      CallHookPkt( AudioCtrl->ahiac_PostTimerFunc, (Object*) AudioCtrl, 0 );

	      if( frame_length == 0 )
	      {
		frame_length = AHI_SampleFrameSize( AudioCtrl->ahiac_BuffType );
	      }
	      
	      ahi_io[ 0 ]->ahir_Std.io_Command = CMD_WRITE;
	      ahi_io[ 0 ]->ahir_Std.io_Data    = dd->mixbuffers[ 0 ];
	      ahi_io[ 0 ]->ahir_Std.io_Length  = ( AudioCtrl->ahiac_BuffSamples *
						   frame_length );
	      ahi_io[ 0 ]->ahir_Std.io_Offset  = 0;
	      ahi_io[ 0 ]->ahir_Frequency      = AudioCtrl->ahiac_MixFreq;
	      ahi_io[ 0 ]->ahir_Type           = AudioCtrl->ahiac_BuffType;
	      ahi_io[ 0 ]->ahir_Volume         = 0x10000;
	      ahi_io[ 0 ]->ahir_Position       = 0x08000;
	      ahi_io[ 0 ]->ahir_Link           = ( ahi_io_used[ 1 ] ?
						   ahi_io[ 1 ] : NULL );

	      SendIO( (struct IORequest*) ahi_io[ 0 ] );
    
	      tmp_io = ahi_io[ 0 ];
	      ahi_io[ 0 ] = ahi_io[ 1 ];
	      ahi_io[ 1 ] = tmp_io;

	      tmp_buff = dd->mixbuffers[ 0 ];
	      dd->mixbuffers[ 0 ] = dd->mixbuffers[ 1 ];
	      dd->mixbuffers[ 1 ] = tmp_buff;
	      
	      ahi_io_used[ 0 ] = ahi_io_used[ 1 ];
	      ahi_io_used[ 1 ] = TRUE;
	    }

	    
	    if( ahi_io_used[ 0 ] )
	    {
	      AbortIO( (struct IORequest*) ahi_io[ 0 ] );
	      WaitIO( (struct IORequest*) ahi_io[ 0 ] );
	    }

	    if( ahi_io_used[ 1 ] )
	    {
	      AbortIO( (struct IORequest*) ahi_io[ 1 ] );
	      WaitIO( (struct IORequest*) ahi_io[ 1 ] );
	    }
	    
	    FreeVec( ahi_iocopy );
	  }

	  CloseDevice( (struct IORequest*) ahi_iorequest );
	}

	DeleteIORequest( (struct IORequest*) ahi_iorequest );
      }

      DeleteMsgPort( ahi_mp );
    }
  }

  FreeSignal( dd->slavesignal );
  dd->slavesignal = -1;

  Forbid();

  // Tell the Master we're dying

  Signal( (struct Task*) dd->mastertask,
          1L << dd->mastersignal );

  dd->slavetask = NULL;

  // Multitaking will resume when we are dead.
}