Exemplo n.º 1
0
Arquivo: main.c Projeto: TCCQ/d2x-cios
int main(void)
{
	u32 queuehandle;
	s32 ret;

	/* Print info */
	svc_write("$IOSVersion: FAT: " __DATE__ " " __TIME__ " 64M$\n");

	/* Create blinker thread */
	Led_CreateBlinkThread();

	/* Initialize module */
	ret = __FAT_Initialize(&queuehandle);
	if (ret < 0)
		return ret;

	/* Main loop */
	while (1) {
		ipcmessage *message = NULL;

		/* Wait for message */
		ret = os_message_queue_receive(queuehandle, (void *)&message, 0);
		if (ret)
			continue;

		switch (message->command) {
		case IOS_OPEN: {
			char *devpath = message->open.device;
			u32   mode    = message->open.mode;

			if (*devpath == '$') {
				char path[256];

				/* Build absolute path to emu nand */
				strcpy(path, emuNandPath);
				FAT_Escape(path+emuNandPathLen, devpath+1);

				dbg_printf("FAT: IOS_OPEN: Opening relative file %s\n", devpath);
				/* Open file */
				ret = FAT_Open(path, mode);
				dbg_printf("FAT: IOS_OPEN: ret = %d\n", ret);
			}
			else if (!strcmp(devpath, DEVICE_FAT)) {
				/* Open module */
				dbg_printf("FAT: IOS_OPEN: Opening FAT module\n");
				ret = 0;
				dbg_printf("FAT: IOS_OPEN: ret = %d\n", ret);
			}
			else if (!strncmp(devpath, DEVICE_FAT, DEVICE_FAT_LEN)) {
				/* Open file */
				dbg_printf("FAT: IOS_OPEN: Opening absolute file %s\n", devpath + DEVICE_FAT_LEN);
				ret = FAT_Open(devpath + DEVICE_FAT_LEN, mode);
				dbg_printf("FAT: IOS_OPEN: ret = %d\n", ret);
			}
			else {
				dbg_printf("FAT: IOS_OPEN: Unknown device path %s\n", devpath);
				/* Error */
				ret = IPC_EINVAL;
			}

			break;
		}

		case IOS_CLOSE: {
			ret = 0;

			// FIX d2x v7 beta1
			// Check added because the fd might represent the module,
			// see IOS_OPEN.
			// Tipically a fd representing a module is far lower than 32, 
			// while a fd representing a file is an address 32 byte aligned.
			if(message->fd != 0 && (message->fd % 32) == 0) {
				dbg_printf("FAT: IOS_CLOSE: Closing file... fd = %d\n", message->fd);
				/* Close file */
				ret = FAT_Close(message->fd);
			}
#ifdef DEBUG
			else {
				dbg_printf("FAT: IOS_CLOSE: Closing FAT module...\n");
			}
#endif

			dbg_printf("FAT: IOS_CLOSE: ret = %d\n", ret);

			break;
		}

		case IOS_READ: {
			void *buffer = message->read.data;
			u32   len    = message->read.length;

			dbg_printf("FAT: IOS_READ: fd = %d, buffer = %x, len = %d\n", message->fd, buffer, len);

			/* Read file */
			ret = FAT_Read(message->fd, buffer, len);

			/* Flush cache */
			os_sync_after_write(buffer, len);

			dbg_printf("FAT: IOS_READ: ret = %d\n", ret);

			break;
		}

		case IOS_WRITE: {
			void *buffer = message->write.data;
			u32   len    = message->write.length;

			dbg_printf("FAT: IOS_WRITE: fd = %d, buffer = %x, len = %d\n", message->fd, buffer, len);

			/* Invalidate cache */
			os_sync_before_read(buffer, len);

			/* Sart blinking */
			Led_BlinkOn();

			/* Write file */
			ret = FAT_Write(message->fd, buffer, len);

			dbg_printf("FAT: IOS_WRITE: ret = %d\n", ret);

			/* Stop blinking */
			Led_BlinkOff();

			break;
		}

		case IOS_SEEK: {
			s32 where  = message->seek.offset;
			s32 whence = message->seek.origin;

			dbg_printf("FAT: IOS_SEEK: fd = %d, where = %d, whence = %d\n", message->fd, where, whence);
      
			/* Seek file */
			ret = FAT_Seek(message->fd, where, whence);

			dbg_printf("FAT: IOS_SEEK: ret = %d\n", ret);

			break;
		}

		case IOS_IOCTL: {
			void *inbuf = message->ioctl.buffer_in;
			void *iobuf = message->ioctl.buffer_io;
			u32   inlen = message->ioctl.length_in;
			u32   iolen = message->ioctl.length_io;
			u32   cmd   = message->ioctl.command;

			/* Parse IOCTL */
			ret = __FAT_Ioctl(message->fd, cmd, inbuf, inlen, iobuf, iolen);

			break;
		}

		case IOS_IOCTLV: {
			ioctlv *vector = message->ioctlv.vector;
			u32     inlen  = message->ioctlv.num_in;
			u32     iolen  = message->ioctlv.num_io;
			u32     cmd    = message->ioctlv.command;

			/* Parse IOCTLV */
			ret = __FAT_Ioctlv(message->fd, cmd, vector, inlen, iolen);

			break;
		}

		default:
			/* Unknown command */
			ret = IPC_EINVAL;
		}

		/* Acknowledge message */
		os_message_queue_ack((void *)message, ret);
	}
   
	return 0;
}
Exemplo n.º 2
0
int main(void)
{
	u32 queuehandle;
	s32 ret;

	/* Print info */
	write("$IOSVersion: FAT: " __DATE__ " " __TIME__ " 64M$\n");

	/* Initialize module */
	ret = __FAT_Initialize(&queuehandle);
	if (ret < 0)
		return ret;

	/* Main loop */
	while (1) {
		ipcmessage *message = NULL;

		/* Wait for message */
		os_message_queue_receive(queuehandle, (void *)&message, 0);

		switch (message->command) {
		case IOS_OPEN: {
			char *devpath = message->open.device;
			u32   mode    = message->open.mode;

			/* FAT device */
			if (!strcmp(devpath, DEVICE_FAT)) {
				ret = 0;
				break;
			}

			/* Open file */
			ret = FAT_Open(devpath, mode);

			break;
		}

		case IOS_CLOSE: {
			/* Close file */
			ret = FAT_Close(message->fd);

			break;
		}

		case IOS_READ: {
			void *buffer = message->read.data;
			u32   len    = message->read.length;

			/* Read file */
			ret = FAT_Read(message->fd, buffer, len);

			break;
		}

		case IOS_WRITE: {
			void *buffer = message->write.data;
			u32   len    = message->write.length;

			/* Write file */
			ret = FAT_Write(message->fd, buffer, len);

			break;
		}

		case IOS_SEEK: {
			u32 where  = message->seek.offset;
			u32 whence = message->seek.origin;

			/* Seek file */
			ret = FAT_Seek(message->fd, where, whence);

			break;
		}

		case IOS_IOCTL: {
			void *inbuf = message->ioctl.buffer_in;
			u32   inlen = message->ioctl.length_in;
			void *iobuf = message->ioctl.buffer_io;
			u32   iolen = message->ioctl.length_io;
			u32   cmd   = message->ioctl.command;

			/* Parse IOCTL message */
			ret = FAT_Ioctl(message->fd, cmd, inbuf, inlen, iobuf, iolen);

			break;
		}

		case IOS_IOCTLV: {
			ioctlv *vector = message->ioctlv.vector;
			u32     inlen  = message->ioctlv.num_in;
			u32     iolen  = message->ioctlv.num_io;
			u32     cmd    = message->ioctlv.command;

			/* Parse IOCTLV message */
			ret = FAT_Ioctlv(message->fd, cmd, vector, inlen, iolen);

			break;
		}

		default:
			/* Unknown command */
			ret = IPC_EINVAL;
		}

		/* Acknowledge message */
		os_message_queue_ack((void *)message, ret);
	}
   
	return 0;
}