/*------------------------------------------------------------------------------------------*\ * * Copyright (C) 2004 AVM GmbH * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA \*------------------------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include /*--- #include ---*/ #include #include #include #include #include #include #if defined(CONFIG_PROC_FS) #include #endif /*--- #if defined(CONFIG_PROC_FS) ---*/ /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ /*--- #define TFFS_DEBUG ---*/ #include "tffs_local.h" #if 0 #include #include #include static char hashbuf[64]; static int plaintext_to_sha1(uint8_t *plaintext, unsigned int plen, uint8_t *hash, unsigned int hlen) { struct crypto_hash *tfm; struct hash_desc desc; struct scatterlist sg; unsigned int hashsize; tfm = crypto_alloc_hash("sha1", 0, CRYPTO_ALG_ASYNC); if (tfm == NULL) { pr_err("Failed to load transform for SHA1\n"); return -EINVAL; } desc.tfm = tfm; desc.flags = 0; hashsize = crypto_hash_digestsize(tfm); if (hashsize > hlen){ pr_err("[%s] hashbuf too small\n", __func__); return -EINVAL; } sg_init_one(&sg, plaintext, plen); crypto_hash_init(&desc); crypto_hash_update(&desc, &sg, plen); crypto_hash_final(&desc, hash); crypto_free_hash(tfm); return hashsize; } #endif int write_segment(struct _tffs_open *handle, size_t to_write, unsigned int final) { int result; to_write = min(handle->z_length - handle->stream.avail_out, to_write); #if 0 { int hashsize; pr_err("[%s] z_length: 0x%x avail_out: 0x%x, to_write: 0x%x\n", __func__, handle->z_length, handle->stream.avail_out, to_write); hashsize = plaintext_to_sha1(handle->z_Buffer, to_write, hashbuf, sizeof(hashbuf)); if(hashsize <= 0){ return hashsize; } print_hex_dump(KERN_ERR, "hash: ", DUMP_PREFIX_OFFSET, hashsize, 1, hashbuf, hashsize, 0); } #endif result = TFFS3_Write(handle, handle->id, handle->z_Buffer, to_write, final); if(result == 0){ memmove(handle->z_Buffer, handle->z_Buffer + to_write, handle->z_length - to_write); handle->stream.next_out = handle->z_Buffer; handle->stream.avail_out += to_write; } #if 0 pr_err("[%s] z_length: 0x%x avail_out: 0x%x, to_write: 0x%x\n", __func__, handle->z_length, handle->stream.avail_out, to_write); #endif return result; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #if 0 void tffs3_dump_block(unsigned char *p, unsigned int len) { int i, ii; printk("[dump] 0x%8p (%u bytes)\n", p, len); for(i = 0 ; i < len ; i += 16, p += 16) { printk("\t0x%8p: ", p); for(ii = 0 ; ii < 16 && (i + ii) < len ; ii++) printk("0x%02x ", p[ii]); for( ; ii < 16 ; ii++ ) printk(" "); printk(" : "); for(ii = 0 ; ii < 16 && (i + ii) < len ; ii++) printk("%c ", p[ii] > ' ' ? p[ii] : '.'); printk("\n"); } } #endif /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ #if defined(TFFS_DEBUG) static void dump_buffer(char *text, unsigned int len, unsigned char *buffer) { int i; #define dump_buffer_block_size 128 for(i = 0 ; i < len ; i += dump_buffer_block_size) { printk("%s(%u bytes): 0x%x: % *B\n", text, len, len, len - i > dump_buffer_block_size ? dump_buffer_block_size : len - i, buffer + i); } } #endif /*--- #if defined(TFFS_DEBUG) ---*/ #define STATIC_ZBUFFER_LEN 8010UL //((32 * 1024) + 16) #define STATIC_ZBUFFER_LEN_CRYPT (STATIC_ZBUFFER_LEN + 4) static unsigned char static_z_Buffer[STATIC_ZBUFFER_LEN_CRYPT]; /*-----------------------------------------------------------------------------------------------*\ \*-----------------------------------------------------------------------------------------------*/ struct _tffs_open *tffs3_open_kern(unsigned int id, unsigned int wr_mode) { struct _tffs_open *handle; int result, status; int workspacesize; handle = (struct _tffs_open *) TFFS3_Open(wr_mode ? tffs3_mode_write : tffs3_mode_read); if(handle == NULL) { DBG((KERN_ERR "%s: tffs3_open: TFFS3_Open failed\n", MODULE_NAME)); return NULL; } /*--------------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------------*/ result = 0; handle->id = id; handle->z_Buffer = NULL; handle->stream.workspace = NULL; /* * minor 0 is only for ioctl, no read or write support */ if(id != 0) { handle->stream.data_type = Z_ASCII; handle->z_length = handle->max_segment_size; //STATIC_ZBUFFER_LEN; handle->z_Buffer = vmalloc(handle->z_length); if(handle->z_Buffer == NULL) { DBG((KERN_ERR "%s: tffs3_open: no memory for z_buffer\n", MODULE_NAME)); result = -ENOMEM; goto err_out; } /*----------------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------------*/ memset(&(handle->stream), 0x0, sizeof(handle->stream)); if(wr_mode) { workspacesize = zlib_deflate_workspacesize(); handle->stream.next_out = handle->z_Buffer; handle->stream.avail_out = handle->z_length; handle->stream.total_out = 0; } else { workspacesize = zlib_inflate_workspacesize(); handle->stream.next_in = handle->z_Buffer; handle->stream.avail_in = 0; handle->stream.total_in = 0; } handle->stream.workspace = vmalloc(workspacesize); if(handle->stream.workspace == NULL) { pr_err("%s: tffs3_open: no memory for %s workspace\n", MODULE_NAME, wr_mode ? "write" : "read"); result = -ENOMEM; goto err_out; } if(wr_mode){ status = zlib_deflateInit(&handle->stream, Z_DEFAULT_COMPRESSION); } else { status = zlib_inflateInit(&handle->stream); } if(status != Z_OK) { DBG((KERN_ERR "%s: tffs3_open: zlib_deflateInit failed, status = %d\n", MODULE_NAME, status)); result = -EIO; goto err_out; } handle->init_flag = 1; /*----------------------------------------------------------------------------------*\ \*----------------------------------------------------------------------------------*/ } DBG((KERN_INFO "%s: tffs3_open: TFFS3_Open success flags=0x%x\n", MODULE_NAME, filp->f_flags)); return handle; err_out: if(handle->z_Buffer){ vfree(handle->z_Buffer); } if(handle->stream.workspace){ vfree(handle->stream.workspace); } TFFS3_Close(handle); return NULL; } struct _tffs_open *tffs3_open_panic(void) { struct _tffs_open *handle; int status; int workspacesize; if(panic_log_workspace == NULL){ pr_err("[%s] no panic log workspace available\n", __func__); return NULL; } handle = (struct _tffs_open *) TFFS3_Open(tffs3_mode_panic); if(handle == NULL) { DBG((KERN_ERR "%s: tffs3_open: TFFS3_Open failed\n", MODULE_NAME)); return NULL; } /*--------------------------------------------------------------------------------------*\ \*--------------------------------------------------------------------------------------*/ handle->id = FLASH_FS_ID_PANIC_LOG; handle->stream.data_type = Z_ASCII; handle->stream.workspace = NULL; handle->z_length = min_t(size_t, handle->max_segment_size, STATIC_ZBUFFER_LEN); handle->z_Buffer = static_z_Buffer; memset(&(handle->stream), 0x0, sizeof(handle->stream)); workspacesize = zlib_deflate_workspacesize(); if(workspacesize > PANIC_LOG_WRKSPC_SIZE){ pr_err("[%s] workspace buffer too small (0x%x) for zlib workspace (0x%x)\n", __func__, PANIC_LOG_WRKSPC_SIZE, workspacesize); goto err_out; } handle->stream.next_out = handle->z_Buffer; handle->stream.avail_out = handle->z_length; handle->stream.total_out = 0; handle->stream.workspace = panic_log_workspace; status = zlib_deflateInit(&handle->stream, Z_DEFAULT_COMPRESSION); if(status != Z_OK) { pr_err("[%s] zlib_deflateInit failed, status = %d\n", __func__, status); goto err_out; } handle->init_flag = 1; return handle; err_out: if(handle != NULL){ TFFS3_Close(handle); } return NULL; } int tffs3_open(struct inode *inode, struct file *filp) { struct _tffs_open *handle; int minor = MINOR(inode->i_rdev); // int major = MAJOR(inode->i_rdev); DBG((KERN_INFO "%s: tffs3_open: MAJOR %u MINOR %u\n", MODULE_NAME, MAJOR(inode->i_rdev), MINOR(inode->i_rdev))); /*--- printk(KERN_INFO "%s: tffs3_open: MAJOR %u MINOR %u\n", MODULE_NAME, MAJOR(inode->i_rdev), MINOR(inode->i_rdev)); ---*/ if(filp->private_data) { TFFS3_Close(filp->private_data); filp->private_data = NULL; } if(filp->f_flags & O_APPEND) { DBG((KERN_ERR "%s: tffs3_open: TFFS3_Open O_APPEND not supported\n", MODULE_NAME)); return -EFAULT; } if(filp->f_flags & O_RDWR) { DBG(("%s: tffs3_open: open O_RDONLY and O_WRONLY simultary not supported\n", MODULE_NAME)); return -EFAULT; } handle = tffs3_open_kern(minor, (filp->f_flags & O_WRONLY)); filp->private_data = handle; if(!filp->private_data) { DBG((KERN_ERR "%s: tffs3_open: TFFS3_Open failed\n", MODULE_NAME)); return -ENOMEM; } return 0; } /*------------------------------------------------------------------------------------------*\ \*------------------------------------------------------------------------------------------*/ int tffs3_flush(struct file *filp, fl_owner_t id) { int status, result; struct _tffs_open *handle; status = 0; result = 0; handle = (struct _tffs_open *)filp->private_data; if(!handle){ return -EFAULT; } if(handle->id && handle->mode != tffs3_mode_read) { DBG((KERN_INFO "{%s} Z_SYNC_FLUSH: zlib_deflate(total_in=%u next_in=0x%p avail_in=%u total_out=%u next_out=0x%p avail_out=%u): status = %d\n", __func__, (int)handle->stream.total_in, handle->stream.next_in, (int)handle->stream.avail_in, (int)handle->stream.total_out, handle->stream.next_out, (int)handle->stream.avail_out, status)); do { status = zlib_deflate(&handle->stream, Z_SYNC_FLUSH); #if 0 pr_err("[%s] after: deflate(total_in=%u next_in=0x%p avail_in=%u total_out=%u next_out=0x%p avail_out=%u): status = %d\n", __func__, (int)handle->stream.total_in, handle->stream.next_in, (int)handle->stream.avail_in, (int)handle->stream.total_out, handle->stream.next_out, (int)handle->stream.avail_out, status); #endif if(status == Z_BUF_ERROR && handle->stream.avail_out < handle->z_length){ result = write_segment(handle, handle->z_length - handle->stream.avail_out, 0); if(result != 0){ goto err_out; } handle->stream.avail_out = handle->z_length; handle->stream.next_out = handle->z_Buffer; } } while(status == Z_BUF_ERROR && handle->stream.avail_out < handle->z_length); /*--- if ((status != Z_OK) || ((status == Z_OK) && ( ! handle->stream.avail_out))) { ---*/ if (status != Z_OK && status != Z_BUF_ERROR) { result = -ENOSPC; } } err_out: return result; } /*-----------------------------------------------------------------------------------------------*\ \*-----------------------------------------------------------------------------------------------*/ int tffs3_release_kern(struct _tffs_open *handle) { int status, result; if(!handle){ return -EBADF; } status = 0; result = 0; if(handle->id) { if(handle->mode != tffs3_mode_read) { handle->stream.next_in = NULL; handle->stream.avail_in = 0; do{ status = zlib_deflate(&(handle->stream), Z_FINISH); #if 0 pr_err("[%s] after: deflate(total_in=%u next_in=0x%p avail_in=%u total_out=%u next_out=0x%p avail_out=%u): status = %d\n", __func__, (int)handle->stream.total_in, handle->stream.next_in, (int)handle->stream.avail_in, (int)handle->stream.total_out, handle->stream.next_out, (int)handle->stream.avail_out, status); #endif if(status == Z_BUF_ERROR && handle->stream.avail_out < handle->z_length){ status = Z_OK; result = write_segment(handle, handle->z_length - handle->stream.avail_out, 0); if(result != 0){ goto err_out; } handle->stream.avail_out = handle->z_length; handle->stream.next_out = handle->z_Buffer; } }while(status == Z_OK); if(status == Z_STREAM_END) { zlib_deflateEnd(&handle->stream); #if 0 pr_err("[%s] after: deflate(total_in=%u next_in=0x%p avail_in=%u total_out=%u next_out=0x%p avail_out=%u): status = %d\n", __func__, (int)handle->stream.total_in, handle->stream.next_in, (int)handle->stream.avail_in, (int)handle->stream.total_out, handle->stream.next_out, (int)handle->stream.avail_out, status); #endif result = write_segment(handle, handle->z_length - handle->stream.avail_out, 1); } else { result = -ENOSPC; } } else { zlib_inflateEnd(&handle->stream); } } err_out: if(result != 0){ pr_emerg("[%s] Close error %d on ID 0x%x\n", __func__, result, handle->id); } if(handle->mode != tffs3_mode_panic){ if(handle->stream.workspace) { vfree(handle->stream.workspace); handle->stream.workspace = NULL; } if(handle->z_Buffer) { vfree(handle->z_Buffer); handle->z_Buffer = NULL; } } TFFS3_Close(handle); return result; } int tffs3_release(struct inode *inode, struct file *filp) { struct _tffs_open *handle; int result; handle = (struct _tffs_open *)filp->private_data; if(!handle){ return -EBADF; } result = tffs3_release_kern(handle); if(result == 0){ filp->private_data = NULL; } return result; } /*-----------------------------------------------------------------------------------------------*\ \*-----------------------------------------------------------------------------------------------*/ ssize_t tffs3_read_kern(struct _tffs_open *handle, char *read_buffer, size_t max_read_length, loff_t *offp) { size_t this_read, total_read; int result; unsigned int status; result = 0; total_read = 0; if(handle->mode != tffs3_mode_read){ result = -EBADF; goto err_out; } if(handle->id == 0) { DBG((KERN_ERR "tffs_read: no read supported on minor 0\n")); result = -EOPNOTSUPP; goto err_out; } handle->stream.next_out = read_buffer; handle->stream.avail_out = max_read_length; do{ if(handle->stream.avail_in == 0){ this_read = handle->z_length; result = TFFS3_Read(handle, handle->id, handle->z_Buffer, &this_read); if(result == 0){ handle->stream.avail_in = this_read; handle->stream.next_in = handle->z_Buffer; #if 0 { int hashsize; hashsize = plaintext_to_sha1(handle->z_Buffer, this_read, hashbuf, sizeof(hashbuf)); if(hashsize <= 0){ result = hashsize; goto err_out; } print_hex_dump(KERN_ERR, "hash: ", DUMP_PREFIX_OFFSET, hashsize, 1, hashbuf, hashsize, 0); } #endif } else { // if there is no data entry for this ID in flash, we pretend it was empty if(result == -ENOENT){ result = 0; } goto err_out; } } #if 0 pr_err("[%s] before: inflate(total_in=%u next_in=0x%p avail_in=%u total_out=%u next_out=0x%p avail_out=%u)\n", __func__, (int)handle->stream.total_in, handle->stream.next_in, (int)handle->stream.avail_in, (int)handle->stream.total_out, handle->stream.next_out, (int)handle->stream.avail_out); #endif status = zlib_inflate(&handle->stream, Z_SYNC_FLUSH); #if 0 pr_err("[%s] after: inflate(total_in=%u next_in=0x%p avail_in=%u total_out=%u next_out=0x%p avail_out=%u)\n", __func__, (int)handle->stream.total_in, handle->stream.next_in, (int)handle->stream.avail_in, (int)handle->stream.total_out, handle->stream.next_out, (int)handle->stream.avail_out); #endif switch(status) { case Z_STREAM_END: zlib_inflateEnd(&handle->stream); // fall through case Z_OK: case Z_BUF_ERROR: break; default: if(handle->stream.msg) { printk("[tffs_read] id 0x%x msg = %s\n", handle->id, handle->stream.msg); } result = -EIO; goto err_out; break; } } while(status == Z_OK && handle->stream.avail_out > 0); total_read = max_read_length - handle->stream.avail_out; *offp += total_read; err_out: return (result == 0) ? total_read : result; } ssize_t tffs3_read(struct file *filp, char *read_buffer, size_t max_read_length, loff_t *offp) { size_t total_read; int result; struct _tffs_open *handle; char *local_buff; result = 0; total_read = 0; handle = (struct _tffs_open *)filp->private_data; local_buff = NULL; if(handle->id == 0) { DBG((KERN_ERR "tffs_read: no read supported on minor 0\n")); result = -EOPNOTSUPP; goto err_out; } local_buff = vmalloc(max_read_length); if(local_buff == NULL) { /*--- kein speicher mehr ---*/ DBG((KERN_ERR "tffs_read: vmalloc(%u) failed\n", max_read_length)); result = -ENOMEM; goto err_out; } total_read = tffs3_read_kern(handle, local_buff, max_read_length, offp); if(copy_to_user(read_buffer, local_buff, total_read)) { result = -EIO; goto err_out; } err_out: if(local_buff != NULL){ vfree(local_buff); } return (result == 0) ? total_read : result; } /*-----------------------------------------------------------------------------------------------*\ \*-----------------------------------------------------------------------------------------------*/ ssize_t tffs3_write_kern(struct _tffs_open *handle, const char *write_buffer, size_t write_length, loff_t *offp) { unsigned int status; int result; ssize_t written; size_t to_write; DBG((KERN_DEBUG "%s: tffs_write(%u bytes)\n", MODULE_NAME, write_length)); result = 0; written = 0; if(handle->mode != tffs3_mode_write && handle->mode != tffs3_mode_panic){ result = -EBADF; goto err_out; } if(write_length == 0) { result = -EINVAL; goto err_out; } if(handle->id == 0) { DBG((KERN_ERR "tffs_write: no write supported on minor 0\n")); result = -EOPNOTSUPP; goto err_out; } handle->stream.next_in = write_buffer; handle->stream.avail_in = write_length; written = 0; do{ #if 0 pr_err("[%s] before: deflate(total_in=%u next_in=0x%p avail_in=%u total_out=%u next_out=0x%p avail_out=%u)\n", __func__, (int)handle->stream.total_in, handle->stream.next_in, (int)handle->stream.avail_in, (int)handle->stream.total_out, handle->stream.next_out, (int)handle->stream.avail_out); #endif status = zlib_deflate(&(handle->stream), Z_NO_FLUSH); #if 0 pr_err("[%s] after: deflate(total_in=%u next_in=0x%p avail_in=%u total_out=%u next_out=0x%p avail_out=%u): status = %d\n", __func__, (int)handle->stream.total_in, handle->stream.next_in, (int)handle->stream.avail_in, (int)handle->stream.total_out, handle->stream.next_out, (int)handle->stream.avail_out, status); #endif if(status == Z_OK || status == Z_BUF_ERROR){ written = write_length - handle->stream.avail_in; to_write = handle->z_length - handle->stream.avail_out; if(to_write == handle->max_segment_size || (to_write > 0 && status == Z_BUF_ERROR)){ result = write_segment(handle, to_write, 0); } } else { if(handle->stream.msg){ printk("[tffs_write] msg = %s\n", handle->stream.msg); } result = -EIO; } }while(result == 0 && handle->stream.avail_in > 0); err_out: *offp += written; return (result == 0) ? written : result; } ssize_t tffs3_write(struct file *filp, const char *write_buffer, size_t write_length, loff_t *offp) { int result; ssize_t written; struct _tffs_open *handle = (struct _tffs_open *)filp->private_data; char *local_write_buffer; DBG((KERN_DEBUG "%s: tffs3_write_user(%u bytes)\n", MODULE_NAME, write_length)); result = 0; written = 0; local_write_buffer = NULL; if(write_length == 0) { result = -EFAULT; goto err_out; } if(handle->id == 0) { DBG((KERN_ERR "tffs_write: no write supported on minor 0\n")); result = -EOPNOTSUPP; goto err_out; } local_write_buffer = vmalloc(write_length); if (local_write_buffer == NULL) { result = -ENOMEM; goto err_out; } if(copy_from_user(local_write_buffer, write_buffer, write_length)) { result = -EFAULT; goto err_out; } written = tffs3_write_kern(handle, local_write_buffer, write_length, offp); err_out: if(local_write_buffer != NULL){ vfree(local_write_buffer); } return (result == 0) ? written : result; } /*-----------------------------------------------------------------------------------------------*\ \*-----------------------------------------------------------------------------------------------*/ int tffs3_ioctl(struct inode *inode, struct file *filp, unsigned int ioctl_param, unsigned long argv) { struct _tffs_cmd tffs_cmd; unsigned char *buffer; unsigned int number = _IOC_NR(ioctl_param); struct _tffs_open *open_data = (struct _tffs_open *)filp->private_data; DBG((KERN_INFO "%s: tffs_ioctl: type %u number %u size %u\n", MODULE_NAME, _IOC_TYPE(ioctl_param), number, _IOC_SIZE(ioctl_param))); if(open_data->id != 0) { /*--- printk(KERN_WARNING "%s: tffs_ioctl: ioctl not supported by minor != 0\n", MODULE_NAME); ---*/ return -EOPNOTSUPP; } if(argv == 0) { pr_err("%s: tffs_ioctl: no data pointer for cmd number %u\n", MODULE_NAME, number); return -EFAULT; } if(copy_from_user(&tffs_cmd, (const void *)argv, sizeof(tffs_cmd))) { pr_err("%s: tffs_ioctl: copy_from_user failed\n", MODULE_NAME); return -EFAULT; } switch(number) { case _TFFS_READ_ID: if((filp->f_flags & O_ACCMODE) == O_WRONLY) { pr_err("%s: tffs_ioctl: read failed: flags=O_WRONLY\n", MODULE_NAME); return -EFAULT; } buffer = kmalloc(tffs_cmd.size, GFP_KERNEL); if(!buffer) { pr_err("%s: tffs_ioctl: alloc(%u) failed\n", MODULE_NAME, tffs_cmd.size); return -EFAULT; } DBG((KERN_DEBUG "%s: tffs_ioctl: read \n", MODULE_NAME)); tffs_cmd.status = TFFS3_Read(filp->private_data, tffs_cmd.id, buffer, &tffs_cmd.size); if(tffs_cmd.status == 0) { if(copy_to_user((void *)tffs_cmd.buffer, buffer, (unsigned long)tffs_cmd.size)) { kfree(buffer); pr_err("%s: tffs_ioctl: copy_to_user failed\n", MODULE_NAME); return -EFAULT; } } kfree(buffer); break; case _TFFS_WRITE_ID: if((filp->f_flags & O_ACCMODE) == O_RDONLY) { pr_err("%s: tffs_ioctl: write failed: flags=O_RDONLY\n", MODULE_NAME); return -EFAULT; } buffer = kmalloc(tffs_cmd.size, GFP_KERNEL); if(!buffer) { pr_err("%s: tffs_ioctl: alloc(%u) failed\n", MODULE_NAME, tffs_cmd.size); return -EFAULT; } if(copy_from_user(buffer, (void *)tffs_cmd.buffer, (unsigned long)tffs_cmd.size)) { kfree(buffer); pr_err("%s: tffs_ioctl: copy_from_user failed\n", MODULE_NAME); return -EFAULT; } DBG((KERN_DEBUG "%s: tffs_ioctl: write\n", MODULE_NAME)); tffs_cmd.status = TFFS3_Write(filp->private_data, tffs_cmd.id, buffer, tffs_cmd.size, 0); kfree(buffer); break; #if 0 /*--- rausgeflogen durch h.schillert 01.03.2007 ---*/ case _TFFS_FORMAT: DBG((KERN_DEBUG "%s: tffs_ioctl: format\n", MODULE_NAME)); if(down_interruptible(&tffs3_sema)) { pr_err("%s: tffs_ioctl(FORMAT): down_interruptible() failed\n", MODULE_NAME); return -ERESTARTSYS; } tffs_cmd.status = TFFS3_Format(filp->private_data); up(&tffs3_sema); break; #endif case _TFFS_WERKSEINSTELLUNG: DBG((KERN_DEBUG "%s: tffs_ioctl: format\n", MODULE_NAME)); tffs_cmd.status = TFFS3_Werkseinstellungen(filp->private_data); break; case _TFFS_CLEAR_ID: DBG((KERN_DEBUG "%s: tffs_ioctl: clear id\n", MODULE_NAME)); tffs_cmd.status = TFFS3_Clear(filp->private_data, tffs_cmd.id); break; case _TFFS_CLEANUP: DBG((KERN_DEBUG "%s: tffs_ioctl: cleanup\n", MODULE_NAME)); tffs_cmd.status = TFFS3_Cleanup(filp->private_data); break; case _TFFS_REINDEX: DBG((KERN_DEBUG "%s: tffs_ioctl: reindex\n", MODULE_NAME)); tffs_cmd.status = TFFS3_Create_Index(); break; case _TFFS_INFO: DBG((KERN_DEBUG "%s: tffs_ioctl: info\n", MODULE_NAME)); tffs_cmd.status = TFFS3_Info(filp->private_data, &tffs_cmd.id); break; default: pr_err("%s: tffs_ioctl: unknwon\n", MODULE_NAME); return -EINVAL; } if(copy_to_user((void *)argv, &tffs_cmd, sizeof(tffs_cmd))) { pr_err("%s: tffs_ioctl: copy_to_user failed\n", MODULE_NAME); return -EFAULT; } return 0; }