📄 ioctl-example.c
字号:
/****************************************************************************** * * * Project: DOC Driver for Linux 2.6 Block device driver for mDOC H3 family * * of devices under Linux kernel 2.6. * * * * Version: 1.0 * * Email questions to: oemsupport@sandisk.com * * Copyright (C) SanDisk IL Ltd. 1995 - 2007 * * SanDisk IL Ltd., 7 Atir Yeda Street, Kfar Saba 44425, Israel * * * ****************************************************************************** * * * 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 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, which is set forth in the readme.txt file. * * 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., 51 * * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * * * This License does not grant you any right to use the trademarks, service * * marks or logos of SanDisk IL Ltd. or SanDisk Corporation. * * Subject to the foregoing, SanDisk IL Ltd., for itself and on behalf of its * * licensors, hereby reserves all intellectual property rights in the program,* * except for the rights expressly granted in this License. * * * ******************************************************************************/#include <stdio.h>#include <unistd.h>#include <stdlib.h>#include <string.h>#include <fcntl.h>#include <sys/mount.h>#include <errno.h>#include "tffsioct.h"#define ALLOW_FORMATTING#undef ALLOW_BDK#define ALLOW_HW_PROTECTION/* make TrueFFS ahndle out of socket and disk ## */#define mk_tffs_handle(socNo,diskNo) (((unsigned short)(socNo) & 0xf) | \ (((unsigned int)(diskNo) << 4) & 0xf0))/* * static routines */static int fl_ioctl_get_info (int fd);static int fl_ioctl_defragment (int fd);static int fl_ioctl_customer_id (int fd);#ifdef ALLOW_BDK static int fl_ioctl_bdk_operation (int fd);#endifstatic int hdio_getgeo (int fd);#ifdef ALLOW_FORMATTING static int fl_ioctl_erase_bd (int fd); static int fl_ioctl_flash_format (int fd); static int fl_ioctl_flash_unformat (int fd); static int fl_ioctl_mount_volume (int fd);#endif#ifdef ALLOW_HW_PROTECTION static int fl_ioctl_hw_protection (int fd, int ioctl_opcode);#endifint main ( int argc, char * argv[] ){ int ioctl_opcode; int flags; int fd; int rc = -1; /* check if devce name and IOCTL opcode are specified, and get IOCTL opcode */ if ((argc < 3) || (sscanf(argv[2], "%d", &ioctl_opcode) != 1)) { fprintf (stderr, "Usage: ioctl-example <device-file-name> <ioctl-code>\n"); fprintf (stderr, "Example: ioctl-example /dev/tffsa 14\n"); fprintf (stderr, "Accepted values for <ioctl-code>:\n"); fprintf (stderr, " %d for FL_IOCTL_CUSTOMER_ID\n", FL_IOCTL_CUSTOMER_ID); fprintf (stderr, " %d for FL_IOCTL_DEFRAGMENT\n", FL_IOCTL_DEFRAGMENT); fprintf (stderr, " %d for FL_IOCTL_GET_INFO\n", FL_IOCTL_GET_INFO);#ifdef ALLOW_BDK fprintf (stderr, " %d for FL_IOCTL_BDK_OPERATION\n", FL_IOCTL_BDK_OPERATION);#endif#ifdef ALLOW_FORMATTING fprintf (stderr, " %d for FL_IOCTL_MOUNT_VOLUME\n", FL_IOCTL_MOUNT_VOLUME); fprintf (stderr, " %d for FL_IOCTL_ERASE_BD\n", FL_IOCTL_ERASE_BD); fprintf (stderr, " %d for FL_IOCTL_FLASH_FORMAT\n", FL_IOCTL_FLASH_FORMAT); fprintf (stderr, " %d for FL_IOCTL_FLASH_UNFORMAT\n", FL_IOCTL_FLASH_UNFORMAT);#endif#ifdef ALLOW_HW_PROTECTION fprintf (stderr, " %d for FL_IOCTL_BDTL_HW_PROTECTION\n", FL_IOCTL_BDTL_HW_PROTECTION);#endif fprintf (stderr, " %d for HDIO_GETGEO\n", 0x0301 /* HDIO_GETGEO */); exit (-1); } /* open device */ flags = ((ioctl_opcode == FL_IOCTL_GET_INFO) ? O_RDONLY : O_RDWR); if((fd = open(argv[1], flags)) == -1) { perror ("Can't open device"); exit (-1); } /* issue IOCTL to device */ switch (ioctl_opcode) { case FL_IOCTL_CUSTOMER_ID: rc = fl_ioctl_customer_id (fd); break; case FL_IOCTL_DEFRAGMENT: rc = fl_ioctl_defragment (fd); break; case FL_IOCTL_MOUNT_VOLUME: rc = fl_ioctl_mount_volume (fd); break; case FL_IOCTL_GET_INFO: rc = fl_ioctl_get_info (fd); break;#ifdef ALLOW_BDK case FL_IOCTL_BDK_OPERATION: rc = fl_ioctl_bdk_operation (fd); break;#endif#ifdef ALLOW_FORMATTING case FL_IOCTL_ERASE_BD: rc = fl_ioctl_erase_bd (fd); break; case FL_IOCTL_FLASH_FORMAT: rc = fl_ioctl_flash_format (fd); break; case FL_IOCTL_FLASH_UNFORMAT: rc = fl_ioctl_flash_unformat (fd); break;#endif#ifdef ALLOW_HW_PROTECTION case FL_IOCTL_BDTL_HW_PROTECTION: rc = fl_ioctl_hw_protection (fd, ioctl_opcode); break;#endif case 0x0301: /* HDIO_GETGEO */ rc = hdio_getgeo (fd); break; } close (fd); exit (rc);}staticint fl_ioctl_customer_id (int fd){ flIOctlRecord ioctl_data; flCustomerIdOutput out; int rc; ioctl_data.inputRecord = NULL; /* no input record for this IOCTL */ ioctl_data.outputRecord = &out; rc = ioctl (fd, FL_IOCTL_CUSTOMER_ID, &ioctl_data); if ((rc != 0) || (out.status != flOK)) fprintf (stderr, "FL_IOCTL_CUSTOMER_ID IOCTL failed, error %d\n", out.status); else fprintf (stdout, "SUCCESS getting customer ID: 0x%x 0x%x 0x%x 0x%x\n", out.id[0], out.id[1], out.id[2], out.id[3]); return rc;}staticint fl_ioctl_defragment (int fd){ flIOctlRecord ioctl_data; flDefragInput in; flDefragOutput out; int rc; in.requiredNoOfSectors = -1; ioctl_data.inputRecord = ∈ ioctl_data.outputRecord = &out; rc = ioctl (fd, FL_IOCTL_DEFRAGMENT, &ioctl_data); if ((rc == 0) && (out.status == flOK)) fprintf (stdout, "free sectors after defragmentation: %ld\n", out.actualNoOfSectors); return rc;}staticint fl_ioctl_get_info (int fd){ flIOctlRecord ioctl_data; flDiskInfoOutput out; int rc; ioctl_data.inputRecord = NULL; /* no input record for this IOCTL */ ioctl_data.outputRecord = &out; rc = ioctl (fd, FL_IOCTL_GET_INFO, &ioctl_data); if ((rc != 0) || (out.status != flOK)) fprintf (stderr, "FL_IOCTL_GET_INFO failed %d\n", out.status); else fprintf (stdout, "FL_IOCTL_GET_INFO reports %ld sectors\n", out.info.logicalSectors); return rc;}#ifdef ALLOW_FORMATTINGstaticint fl_ioctl_mount_volume (int fd){ flIOctlRecord ioctl_data; flMountInput in; flOutputStatusRecord out; int rc; ioctl_data.inputRecord = ∈ ioctl_data.outputRecord = &out;#if 1 in.type = FL_DISMOUNT; /* unmount disk */#else in.type = FL_MOUNT; /* re-mount disk */#endif rc = ioctl (fd, FL_IOCTL_MOUNT_VOLUME, &ioctl_data); if ((rc != 0) || (out.status != flOK)) fprintf (stderr, "FL_IOCTL_MOUNT_VOLUME failed %d\n", out.status); return rc;}#endif /* ALLOW_FORMATTING */#ifdef ALLOW_FORMATTINGstaticint fl_ioctl_erase_bd (int fd){ flIOctlRecord ioctl_data; int rc; /* unmount disk before formatting */ { flMountInput in; flOutputStatusRecord out; in.type = FL_DISMOUNT; ioctl_data.inputRecord = ∈ ioctl_data.outputRecord = &out; rc = ioctl (fd, FL_IOCTL_MOUNT_VOLUME, &ioctl_data); if ((rc != 0) || (out.status != flOK)) fprintf (stderr, "FL_IOCTL_MOUNT_VOLUME/FL_DISMOUNT failed %d\n", out.status); } /* re-format disk */ { flEraseBDInput in; flOutputStatusRecord out; in.dwFlags = 0; ioctl_data.inputRecord = ∈ ioctl_data.outputRecord = &out; rc = ioctl (fd, FL_IOCTL_ERASE_BD, &ioctl_data); if ((rc != 0) || (out.status != flOK)) fprintf (stderr, "FL_IOCTL_ERASE_BD failed %d\n", out.status); } /* re-mount disk */ { flMountInput in; flOutputStatusRecord out; in.type = FL_MOUNT; ioctl_data.inputRecord = ∈ ioctl_data.outputRecord = &out; rc = ioctl (fd, FL_IOCTL_MOUNT_VOLUME, &ioctl_data); if ((rc != 0) || (out.status != flOK)) fprintf (stderr, "FL_IOCTL_MOUNT_VOLUME/FL_MOUNT failed %d\n", out.status); } return rc;}#endif /* ALLOW_FORMATTING */#ifdef ALLOW_FORMATTINGstaticint fl_ioctl_flash_format (int fd){ flIOctlRecord ioctl_data; flOutputStatusRecord out; int rc; /* WARNING: You must send FL_IOCTL_MOUNT_VOLUME/FL_DISMOUNT call * to all DiskOnChip disks (except for '/dev/tffsa') prior * to calling this routine. You should not do that for * /dev/tffsa - this routine must do it by itself. */ /* send FL_IOCTL_MOUNT_VOLUME/FL_DISMOUNT call to '/dev/tffsa' */ { flMountInput in; in.type = FL_DISMOUNT; ioctl_data.inputRecord = ∈ ioctl_data.outputRecord = &out; rc = ioctl (fd, FL_IOCTL_MOUNT_VOLUME, &ioctl_data); if ((rc != 0) || (out.status != flOK)) fprintf (stderr, "FL_IOCTL_MOUNT_VOLUME/FL_DISMOUNT failed %d\n", out.status); } /* format DiskOnChip */ { flFlashFormatInput in; FormatParams3 fp3; BDTLPartitionFormatParams3 disks[16]; /* WARNING: Large data structure 1 */ BinaryPartitionFormatParams3 bins[4]; memset (&in, 0, sizeof(in)); memset (&fp3, 0, sizeof(FormatParams3)); memset (disks, 0, sizeof(disks)); memset (bins, 0, sizeof(bins)); in.fpPtr = &fp3;#if 1 in.dwFormatFlags = TL_NORMAL_FORMAT;#else /* If you intent on keeping some of BDTL partitions, uncomment * this section, and specify how many partitions you want to keep. */ in.dwFormatFlags = TL_LEAVE_SOME_PARTITIONS; in.sdwNoOfKeeps = 5; /* keep this many partitions */#endif fp3.progressCallback = NULL; fp3.percentUse = 95; fp3.BDTLPartitionInfo = &disks[0]; fp3.binaryPartitionInfo = &bins[0]; fp3.noOfBinaryPartitions = 0; fp3.noOfBDTLPartitions = 0; /* specify size of 1-st DiskOnChip disk */ disks[ fp3.noOfBDTLPartitions ].length = (40 * 0x100000); /* disk size in bytes */ disks[ fp3.noOfBDTLPartitions++ ].noOfSpareUnits = 3;#if 0 /* specify sizes of 2-nd .. 13-th DiskOnChip disk (if you need them) */ disks[ fp3.noOfBDTLPartitions ].length = (20 * 0x100000); /* 2-nd disk size in bytes */ disks[ fp3.noOfBDTLPartitions++ ].noOfSpareUnits = 3; disks[ fp3.noOfBDTLPartitions ].length = (30 * 0x100000); /* 3-rd disk size in bytes */ disks[ fp3.noOfBDTLPartitions++ ].noOfSpareUnits = 3; disks[ fp3.noOfBDTLPartitions ].length = (40 * 0x100000); /* 4-th disk size in bytes */ disks[ fp3.noOfBDTLPartitions++ ].noOfSpareUnits = 3;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -