/******************************************************************************/
/* */
/* Copyright (C), 1995-2006, msystems Ltd. All rights reserved. */
/* */
/* Redistribution and use in source and binary forms, with or without */
/* modification, are permitted provided that the following conditions are */
/* met: */
/* 1. Redistributions of source code must retain the above copyright notice, */
/* this list of conditions and the following disclaimer. */
/* 2. Redistributions in binary form must reproduce the above copyright */
/* notice, this list of conditions and the following disclaimer in the */
/* documentation and/or other materials provided with the distribution. */
/* 3. Neither the name of msystems nor the names of its contributors may be */
/* used to endorse or promote products derived from this software without */
/* specific prior written permission. */
/* */
/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */
/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED */
/* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */
/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT */
/* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */
/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR */
/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */
/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */
/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */
/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
/* */
/******************************************************************************/
#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);
#endif
static 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);
#endif
int 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);
}
static
int 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;
}
static
int 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;
}
static
int 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_FORMATTING
static
int fl_ioctl_mount_volume (int fd)
{
flIOctlRecord ioctl_data;
flMountInput in;