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); }
void ps2mcfs_cleanup() { TRACE("ps2mcfs_cleanup()\n"); ps2sif_lock(ps2mcfs_lock, "mcfs cleanup"); #ifdef PS2MCFS_DEBUG if (ps2mcfs_debug & DBG_LOCK) ps2sif_setlockflags(ps2mcfs_lock, oldflags); #endif /* * un-hook block device read/write routine */ if (ps2mc_blkrw_hook == ps2mcfs_blkrw) ps2mc_blkrw_hook = NULL; /* * stop the thread */ if (thread_task != NULL) { send_sig(SIGKILL, thread_task, 1); wait_for_completion(&thread_comp); /* wait the thread exit */ } unregister_filesystem(&ps2mcfs_fs_type); ps2mcfs_exit_root(); ps2mcfs_exit_pathcache(); ps2mcfs_exit_fdcache(); ps2mcfs_exit_filebuf(); ps2sif_unlock(ps2mcfs_lock); }
static int ps2cdvd_drive_status(struct cdrom_device_info *cdi, int arg) { int res; /* spinup and re-check disc if the state is in IDLE */ ps2cdvd_ready(); if (ps2sif_lock(ps2cdvd_lock, "cdvd_drive_status") != 0) return CDS_NO_INFO; switch (ps2cdvd_state) { case STAT_WAIT_DISC: case STAT_INVALID_DISC: DPRINT(DBG_INFO, "drive_status=NO_DISC\n"); res = CDS_NO_DISC; break; case STAT_READY: case STAT_READ: case STAT_READ_ERROR_CHECK: DPRINT(DBG_INFO, "drive_status=DISC_OK\n"); res = CDS_DISC_OK; break; case STAT_ERROR: default: DPRINT(DBG_INFO, "drive_status=NO_INFO\n"); res = CDS_NO_INFO; break; } ps2sif_unlock(ps2cdvd_lock); return res; }
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); }
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; }
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(¤t->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); }
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); }
static int ps2cdvd_reset(struct cdrom_device_info *cdi) { unsigned long flags; save_flags(flags); cli(); ps2sif_lock(ps2cdvd_lock, "cdvd_reset"); RESET_TIMER(); #ifdef CONFIG_PS2_SBIOS_VER_CHECK if (0x0201 <= sbios(SB_GETVER, NULL)) ps2cdvdcall_reset(); #else ps2cdvdcall_reset(); #endif invalidate_discinfo(); ps2cdvd_state = ps2cdvd_enter(STAT_WAIT_DISC); ps2sif_unlock(ps2cdvd_lock); restore_flags(flags); return 0; }
static void ps2cdvd_cleanup() { DPRINT(DBG_VERBOSE, "cleanup\n"); ps2sif_lock(ps2cdvd_lock, "cdvd_cleanup"); RESET_TIMER(); if (initialized & INIT_LABELBUF) { DPRINT(DBG_VERBOSE, "free labelbuf %p\n", labelbuf); kfree(labelbuf); } if (initialized & INIT_DATABUF) { DPRINT(DBG_VERBOSE, "free databuf %p\n", ps2cdvd_databufx); kfree(ps2cdvd_databufx); } #if 0 if (initialized & INIT_IOPSIDE) ps2cdvd_cleanupiop(); #endif if (initialized & INIT_BLKDEV) { DPRINT(DBG_VERBOSE, "unregister block device\n"); unregister_blkdev(MAJOR_NR, "ps2cdvd"); } if (initialized & INIT_CDROM) { DPRINT(DBG_VERBOSE, "unregister cdrom\n"); unregister_cdrom(&ps2cdvd_info); } blksize_size[MAJOR_NR] = NULL; initialized = 0; ps2sif_unlock(ps2cdvd_lock); }
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); }
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); }