Example #1
0
static int __init
ps2mcfs_init()
{
	TRACE("ps2mcfs_init()\n");
	printk("PlayStation 2 Memory Card file system\n");
	init_completion(&thread_comp);

	if ((ps2mcfs_lock = ps2sif_getlock(PS2LOCK_MC)) == NULL) {
		printk(KERN_ERR "ps2mcfs: Can't get lock\n");
		return (-1);
	}
#ifdef PS2MCFS_DEBUG
	if (ps2mcfs_debug & DBG_LOCK) {
		oldflags = ps2sif_getlockflags(ps2mcfs_lock);
		ps2sif_setlockflags(ps2mcfs_lock,
				    (oldflags | PS2LOCK_FLAG_DEBUG));
	}
#endif

	if (ps2sif_lock_interruptible(ps2mcfs_lock, "mcfs init") < 0)
		return (-1);

	if (ps2mcfs_init_filebuf() < 0 ||
	    ps2mcfs_init_pathcache() < 0 ||
	    ps2mcfs_init_fdcache() < 0 ||
	    ps2mcfs_init_dirent() < 0 ||
	    ps2mcfs_init_root() < 0)
		goto error;

	/*
	 * hook block device read/write routine
	 */
	if (ps2mc_blkrw_hook == NULL)
		ps2mc_blkrw_hook = ps2mcfs_blkrw;

	/*
	 * create and start thread
	 */
	kernel_thread(ps2mcfs_thread, NULL, 0);
	wait_for_completion(&thread_comp);	/* wait the thread ready */
                
	if (register_filesystem(&ps2mcfs_fs_type) < 0)
		goto error;

	ps2sif_unlock(ps2mcfs_lock);

	return (0);

 error:
	ps2mcfs_cleanup();
	ps2sif_unlock(ps2mcfs_lock);

	return (-1);
}
Example #2
0
int
ps2sdmixer_setvol(struct ps2sd_mixer_channel *ch, int volr, int voll)
{
	int res;

	if (volr < 0) volr = 0;
	if (100 < volr) volr = 100;
	if (voll < 0) voll = 0;
	if (100 < voll) voll = 100;

	if (ch->mixer != NULL)
		ch->mixer->modified++;
	ch->volr = volr;
	ch->voll = voll;
	ch->vol = (volr << 8) | voll;

	volr = volr * ch->scale / 100;
	voll = voll * ch->scale / 100;

	DPRINT(DBG_MIXER, "%14s R=%04x/L=%04x\n", ch->name, volr, voll);

	res = ps2sif_lock_interruptible(ps2sd_mc.lock, "mixer volume");
	if (res < 0)
		return res;

	if (ch->regr != -1) {
	  res = ps2sdcall_set_reg(ch->regr, volr);
	  if (res < 0) {
		DPRINT(DBG_DIAG, "%s R=%04x/L=%04x: failed, res=%d\n",
		       ch->name, volr, voll, res);
		goto unlock_and_return;
	  }
	}
	if (ch->regl != -1) {
	  res = ps2sdcall_set_reg(ch->regl, voll);
	  if (res < 0) {
		DPRINT(DBG_DIAG, "%s R=%04x/L=%04x: failed, res=%d\n",
		       ch->name, volr, voll, res);
		goto unlock_and_return;
	  }
	}

 unlock_and_return:
	ps2sif_unlock(ps2sd_mc.lock);

	return res;
}
Example #3
0
int
ps2mc_close(int fd)
{
	int res, result;

	res = ps2sif_lock_interruptible(ps2mc_lock, "mc close");
	if (res < 0)
		return (res);

	if (fd < 0 || MAXFILEDESC <= fd || !(openedfd & (1 << fd))) {
		ps2sif_unlock(ps2mc_lock);
		return -EBADF;
	}

	res = 0;
	if (ps2mclib_Close(fd, &result) != 0) {
		/* error */
		printk("ps2mclib_Close() failed\n");
		res = -EIO;
		goto out;
	}

	DPRINT(DBG_INFO, "close(): result=%d\n", result);

	switch (result) {
	case 0: /* succeeded */
		break;
	case 4: /* Bad file number */
		res = -EBADF;
		break;
	default:
		res = -EIO;
		break;
	}

 out:
	openedfd &= ~(1 << fd);
	ps2sif_unlock(ps2mc_lock);
	up(&ps2mc_filesem);
	DPRINT(DBG_FILESEM, "UP file sem(->%d)\n",
	       ps2mc_filesem.count.counter);

	return (res);
}
Example #4
0
static int
ps2mcfs_thread(void *arg)
{

	DPRINT(DBG_INFO, "start thread\n");

	lock_kernel();
	/* get rid of all our resources related to user space */
	daemonize();
	siginitsetinv(&current->blocked,
		      sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM));
	/* Set the name of this process. */
	sprintf(current->comm, "ps2mcfs");
	unlock_kernel();

	thread_task = current;
	complete(&thread_comp); /* notify that we are ready */

	/*
	 * loop
	 */
	while(1) {
		if (ps2sif_lock_interruptible(ps2mcfs_lock, "mcfs_thread")==0){
			ps2mcfs_check_fd();
			ps2sif_unlock(ps2mcfs_lock);
		}

		interruptible_sleep_on_timeout(&thread_wq,
					       PS2MCFS_CHECK_INTERVAL);

		if (signal_pending(current) )
			break;
	}

	DPRINT(DBG_INFO, "exit thread\n");

	thread_task = NULL;
	complete(&thread_comp); /* notify that we've exited */

	return (0);
}
Example #5
0
ssize_t
ps2mc_read(int fd, const void *buf, size_t size)
{
	int res, result;

	res = ps2sif_lock_interruptible(ps2mc_lock, "mc read");
	if (res < 0)
		return (res);

	res = 0;
	if (ps2mclib_Read(fd, (char*)buf, size, &result) != 0) {
		/* error */
		printk("ps2mclib_Read() failed\n");
		res = -EIO;
		goto out;
	}

	DPRINT(DBG_INFO, "read(): result=%d\n", result);

	if (0 <= result) {
		/* succeeded */
		res = result;
	} else {
		switch (result) {
		case -4: /* Bad file number */
			res = -EBADF;
			break;
		case -5: /* Operation not permitted */
			res = -EPERM;
			break;
		default:
			res = -EIO;
			break;
		}
	}

 out:
	ps2sif_unlock(ps2mc_lock);

	return (res);
}
Example #6
0
off_t
ps2mc_lseek(int fd, off_t offset, int whence)
{
	int res, result;

	res = ps2sif_lock_interruptible(ps2mc_lock, "mc lseek");
	if (res < 0)
		return (res);

	res = 0;
	if (ps2mclib_Seek(fd, offset, whence, &result) != 0) {
		/* error */
		printk("ps2mclib_Seek() failed\n");
		res = -EIO;
		goto out;
	}

	DPRINT(DBG_INFO, "lseek(): result=%d\n", result);

	if (0 <= result) {
		/* succeeded */
		res = result;
	} else {
		switch (result) {
		case 4: /* Bad file number */
			res = -EBADF;
			break;
		default:
			res = -EIO;
			break;
		}
	}

 out:
	ps2sif_unlock(ps2mc_lock);

	return (res);
}
Example #7
0
int
ps2mc_open(int portslot, const char *path, int mode)
{
	int res, result;
	int iopflags;

	switch (mode & O_ACCMODE) {
	case O_RDONLY:
		iopflags = McRDONLY;
		break;
	case O_WRONLY:
		iopflags = McWRONLY;
		break;
	case O_RDWR:
		iopflags = McRDWR;
		break;
	default:
		return -EINVAL;
	}
	if (mode & O_CREAT)
		iopflags |= McCREAT;

	if ((res = down_interruptible(&ps2mc_filesem)) < 0)
		return (res);
	DPRINT(DBG_FILESEM, "DOWN file sem(->%d)\n",
	       ps2mc_filesem.count.counter);
	res = ps2sif_lock_interruptible(ps2mc_lock, "mc open");
	if (res < 0) {
		up(&ps2mc_filesem);
		return (res);
	}
	if (mode & O_CREAT) {
		/*
		 * This might create a new entry, thereby,
		 * invalidate directory cache.
		 */
		ps2mc_dircache_invalidate(portslot);
	}

	res = 0;
	if (ps2mclib_Open(PS2MC_PORT(portslot), PS2MC_SLOT(portslot),
		      (char *)path, iopflags, &result) != 0) {
		/* error */
		printk("ps2mclib_Open() failed\n");
		res = -EIO;
		goto out;
	}

	DPRINT(DBG_INFO, "open(): card%d%d %s result=%d\n",
	       PS2MC_PORT(portslot), PS2MC_SLOT(portslot), path, result);

	if (0 <= result) {
		/* succeeded */
		res = result;
	} else {
		switch (result) {
		case -7: /* Too many open files */
			res = -EMFILE;
			break;
		default:
			res = -EIO;
			break;
		}
	}

 out:
	if (res < 0) {
		ps2sif_unlock(ps2mc_lock);
		up(&ps2mc_filesem);
		DPRINT(DBG_FILESEM, "UP file sem(->%d)\n",
		       ps2mc_filesem.count.counter);
	} else {
		if (MAXFILEDESC <= res) {
			printk(KERN_CRIT "ps2mc: ERROR: unexpected fd=%d\n",
			       res);
			ps2sif_unlock(ps2mc_lock);
			up(&ps2mc_filesem);
			DPRINT(DBG_FILESEM, "UP file sem(->%d)\n",
			       ps2mc_filesem.count.counter);
		} else {
			openedfd |= (1 << res);
			ps2sif_unlock(ps2mc_lock);
		}
	}
	return (res);
}