original files of m241

This commit is contained in:
neelimap
2026-07-30 11:19:44 +05:30
parent 170c2b3f3a
commit afc7070c1f
12254 changed files with 7655111 additions and 0 deletions
+33
View File
@@ -0,0 +1,33 @@
# Makefile - makefile for /target/src/vxsim
#
# modification history
# --------------------
# 01f,31aug04,jmp modified rules to build unixDrv.o only for SIMSPARCSOLARIS.
# 01e,09apr04,jeg removed vxsimBufLib.c
# 01d,05mar04,jmp added vxsimHostArchLib.c to DOC_FILES.
# 01c,04feb04,dbt Added unixDrv manual generation.
# 01b,31jul03,jmp added vxsimBufLib.o
# 01a,23jul03,jeg written
#
# DESCRIPTION
# This file contains the makefile rules for building vxsim specific files
#
#*/
TGT_DIR=$(WIND_BASE)/target
DOC_FILES = passFsLib.c unixDrv.c virtualDiskLib.c \
../arch/simsolaris/vxsimHostArchLib.c
LIB_BASE_NAME = vxsim
ifneq ($(subst SIM,,$(CPU)),$(CPU))
OBJS= passFsLib.o virtualDiskLib.o
ifeq ($(CPU),SIMSPARCSOLARIS)
OBJS += unixDrv.o
endif
else
OBJS=
endif
include $(TGT_DIR)/h/make/rules.library
File diff suppressed because it is too large Load Diff
+365
View File
@@ -0,0 +1,365 @@
/* unixDrv.c - UNIX-file disk driver (VxSim for Solaris) */
/*
* Copyright (c) 1984-1995,1997,1999,2000,2001,2003,2004,2006,2007
* Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use of this
* software may be licensed only pursuant to the terms of an applicable
* Wind River license agreement.
*/
/*
modification history
--------------------
01y,30jul07,elp added includes.
01x,18jun07,elp renamed field to coding convention.
01w,24may07,elp added SMP support.
01v,25oct06,elp include vxsimHostLibP.h rather than vxsimHostLib.h
01u,07apr06,dgp doc: fix formatting of routine name & examples in library
01t,31aug04,jmp modified to not build this library on SIMLINUX, it is only
kept on SIMSPARCSOLARIS for backward compatibility.
01s,04feb04,dbt Fixed documentation.
01r,23jun03,jeg reworked to use virtual disk APIs and documented as obsolete.
01q,16jun03,dbt Fixed previous changes
01p,18mar03,jeg improve error management ralative to host routine
01o,05mar03,jeg updated access to unix file definitions
01n,03feb03,jeg updated access to host specific routines. Code cleanup.
01m,04apr01,pfl doc update (SPR #63976)
01l,05dec00,jmp added SIMLINUX support.
01k,31jul00,jkf removal of RT-11 (rt11) file system, SPR#32821/31223
01j,16mar99,elg mention unixDrv is for Solaris and HP simulators (SPR 7719).
01i,11jul97,dgp doc: ad (VxSim) to title line
01h,09jan97,pr added ARCHCVTFLAGS for simsolaris
01g,30oct95,ism added support for simsolaris
01f,31oct94,kdl made conditional for simulator only.
01e,18aug93,gae modified unix_stat for hp.
01d,30jul93,gae doc touchup.
01c,23jan93,gae ANSIfied.
01b,20jul92,gae minor revision.
01a,01apr91,smeg derived from ramDrv.
*/
/*
DESCRIPTION
This driver emulates a VxWorks disk driver by using a virtual disk.
The VxWorks disk appears under UNIX as a single file.
The UNIX file name, and the size of the disk, may be specified during the
unixDiskDevCreate() call.
USER-CALLABLE ROUTINES
The routine unixDrv() must be called to initialize the driver and
the unixDiskDevCreate() routine is used to create devices.
CREATING UNIX DISKS
Before a UNIX disk can be used, it must be created. This is done
with the unixDiskDevCreate() call. The format of this call is:
\cs
BLK_DEV *unixDiskDevCreate
(
char *unixFile, /@ name of the UNIX file to use @/
int bytesPerBlk, /@ number of bytes per block @/
int blksPerTrack, /@ number of blocks per track @/
int nBlocks /@ number of blocks on this device @/
)
\ce
The UNIX file must be pre-allocated separately. This
can be done using the UNIX mkfile(8) command. Note that you have to
create an appropriately sized file. For example, to create a UNIX
file system that is used as a common floppy dosFs file system, you
would issue the comand:
\cs
mkfile 1440k /tmp/floppy.dos
\ce
This will create space for a 1.44 Meg DOS floppy (1474560 bytes,
or 2880 512-byte blocks).
The <bytesPerBlk> parameter specifies the size of each logical block
on the disk. If <bytesPerBlk> is zero, 512 is the default.
The <blksPerTrack> parameter specifies the number of blocks on each
logical track of the UNIX disk. If <blksPerTrack> is zero, the count of
blocks per track will be set to <nBlocks> (i.e., the disk will be defined
as having only one track). UNIX disk devices typically are specified
with only one track.
The <nBlocks> parameter specifies the size of the disk, in blocks.
If <nBlocks> is zero the size of the UNIX file specified, divided by
the number of bytes per block, is used.
The formatting parameters (<bytesPerBlk>, <blksPerTrack>, and <nBlocks>)
are critical only if the UNIX disk already contains the contents
of a disk created elsewhere. In that case, the formatting
parameters must be identical to those used when the image was created.
Otherwise, they may be any convenient number.
Once the device has been created it still does not have a name or
file system associated with it. This must be done by using the file
system's device initialization routine (e.g., dosFsDevInit()). The
dosFs file systems also provide make-file-system routines
(dosFsMkfs()), which may be used to associate a name
and file system with the block device and initialize that file system
on the device using default configuration parameters.
The unixDiskDevCreate() call returns a pointer to a block device
structure (BLK_DEV).
This structure contains fields that describe the physical properties of a
disk device and specify the addresses of routines within the UNIX disk driver.
The BLK_DEV structure address must be passed to the desired file system
(dosFs, or rawFs) during the file system's device
initialization or make-file-system routine. Only then is a name and file
system associated with the device, making it available for use.
As an example, to create a 200KB disk, 512-byte blocks, and only one track,
the proper call would be:
\cs
BLK_DEV *pBlkDev;
pBlkDev = unixDiskDevCreate ("/tmp/filesys1", 512, 400, 400, 0);
\ce
This will attach the UNIX file /tmp/filesys1 as a block device.
A convenience routine, unixDiskInit(), is provided to do the
unixDiskDevCreate() followed by either a dosFsMkFs() or dosFsDevInit(),
whichever is appropriate.
The format of this call is:
\cs
BLK_DEV *unixDiskInit
(
char * unixFile, /@ name of the UNIX file to use @/
char * volName, /@ name of the dosFs volume to use @/
int nBytes /@ number of bytes in dosFs volume @/
)
\ce
This call will create the UNIX disk if required.
IMPORTANT NOTE
This library is obsolete, but is kept for backward compatibility and is now
replaced by virtual disk library. But note that the virtual disk library is
not able to use unix disk created with unixDiskDevCreate() API.
SEE ALSO:
dosFsDevInit(), dosFsMkfs(), rawFsDevInit(),
*/
#include <vxWorks.h>
#include <errno.h>
#include <dosFsLib.h>
#include <stdlib.h>
#include <stdio.h>
#include <private/vxsimHostLibP.h>
#include <virtualDiskLib.h>
#include <string.h>
#include <ioLib.h>
/* USED ONLY WITH SOLARIS SIMULATOR */
#if (CPU_FAMILY==SIMSPARCSOLARIS)
#define BLOCKSIZE 8192 /* default block size */
/* host file permissions : User : RW / Group : Read / Other : Read */
#define FILE_PERM S_IRUSR| S_IWUSR | S_IRGRP | S_IROTH
/*******************************************************************************
*
* unixDrv - install UNIX disk driver
*
* This routine is to cause the UNIX disk driver to be linked in
* when building VxWorks when INCLUDE_DOS_DISK component is included in VxWorks
* image. Otherwise, it is not necessary to call this routine before using
* the UNIX disk driver.
*
* This routine is only applicable to VxSim for Solaris.
*
* IMPORTANT NOTE
* This routine is obsolete, but is kept for backward compatibility.
*
* RETURNS: OK (always).
*/
STATUS unixDrv (void)
{
return (OK);
}
/*******************************************************************************
*
* unixDiskDevCreate - create a UNIX disk device
*
* This routine creates a UNIX disk device.
*
* The <unixFile> parameter specifies the name of the UNIX file to use
* for the disk device.
*
* The <bytesPerBlk> parameter specifies the size of each logical block
* on the disk. If <bytesPerBlk> is zero, 512 is the default.
*
* The <blksPerTrack> parameter specifies the number of blocks on each
* logical track of the disk. If <blksPerTrack> is zero, the count of
* blocks per track is set to <nBlocks> (i.e., the disk is defined
* as having only one track).
*
* The <nBlocks> parameter specifies the size of the disk, in blocks.
* If <nBlocks> is zero, a default size is used. The default is calculated
* as the size of the UNIX disk divided by the number of bytes per block.
*
* This routine is only applicable to VxSim for Solaris.
*
* IMPORTANT NOTE
* This routine is obsolete, but is kept for backward compatibility with previous
* version.
*
* RETURNS: A pointer to block device (BLK_DEV) structure,
* or NULL, if unable to open the UNIX disk.
*/
BLK_DEV * unixDiskDevCreate
(
char * unixFile, /* name of the UNIX file */
int bytesPerBlk, /* number of bytes per block */
int blksPerTrack, /* number of blocks per track */
int nBlocks /* number of blocks on this device */
)
{
struct stat fileStat; /* host file stat */
/* check if the host file aready exist, if not the unix disk is not
* created and a NULL value is returned.
*/
if (vxsimHostStat (unixFile, &fileStat) == ERROR)
{
printErr ("unixDiskDevCreate: Could not open %s read/write\n",
unixFile);
return (NULL);
}
/* Set up defaults for any values not specified */
if (bytesPerBlk == 0)
bytesPerBlk = DEFAULT_SIZE;
if (nBlocks == 0)
{
/*
*if nBlocks parameters is null, it is calculated regarding the
* host file size and bytesPerBlk parameter.
*/
nBlocks = fileStat.st_size / bytesPerBlk;
}
if (blksPerTrack == 0)
blksPerTrack = nBlocks;
return ((BLK_DEV *) virtualDiskOldCreate (unixFile, bytesPerBlk,
blksPerTrack, nBlocks));
}
/*******************************************************************************
*
* unixDiskInit - initialize a dosFs disk on top of UNIX
*
* This routine provides some convenience for a user wanting to create
* a UNIX disk-based dosFs file system under VxWorks. The user only
* specifes the UNIX file to use, the dosFs volume name, and the
* size of the volume in bytes, if the UNIX file needs to be created.
*
* This routine is only applicable to VxSim for Solaris.
*
* IMPORTANT NOTE
* This routine is obsolete, but is kept for backward compatibility with previous
* version.
*
* RETURNS: N/A
*/
void unixDiskInit
(
char * unixFile, /* UNIX file name */
char * volName, /* dosFs name */
int diskSize /* number of bytes */
)
{
int fd; /* Unix file descriptor */
BOOL create; /* TRUE if a new Unix file have been created */
int dosFsStatus; /* DosFS creation status */
BLK_DEV * pBlkDev; /* created block device */
char * fileName; /* duplicate name in kernel (for host call) */
create = FALSE;
if ((fileName = strdup (unixFile)) == NULL)
{
printErr ("unixDiskInit: not enough memory\n");
return;
}
if ((fd = vxsimHostOpen (fileName, O_RDWR, FILE_PERM)) < 0)
{
/* Unix file not available, it must be created */
printErr ("unixDiskInit: %s not found. Creating...", unixFile);
if ((fd = vxsimHostOpen (unixFile, O_RDWR | O_CREAT, FILE_PERM)) < 0)
{
printErr ("permission denied\n");
goto done;
}
if (diskSize == 0)
diskSize = DEFAULT_DISK_SIZE;
/*
* filled the created file with empty characters to get the appropriated
* file size.
*/
if (vxsimHostFtruncate (fd, diskSize) != 0)
{
printErr ("unixDiskInit: Disk Write failed (disk full?)\n");
goto done;
}
create = TRUE;
}
vxsimHostClose (fd);
/* create the block device associated with the created file */
pBlkDev = unixDiskDevCreate (unixFile, DEFAULT_SIZE, 0, 0);
if (pBlkDev != NULL)
{
if (create)
dosFsStatus = (dosFsMkfs (volName, pBlkDev) == NULL) ? ERROR : OK;
else
dosFsStatus = (dosFsDevInit (volName, pBlkDev, 0) == NULL) ? ERROR : OK;
if (dosFsStatus == ERROR)
{
printErr ("unixDiskInit: could not init dosFs file system on %s\n",
unixFile);
}
else
{
printErr ("unixDiskInit: dosFs file system %s as device %s\n",
create ? "init'd" : "attached", volName);
}
}
else
printErr ("unixDiskInit: failed\n");
done:
free (fileName);
}
#endif /* (CPU_FAMILY==SIMSPARCSOLARIS) */
@@ -0,0 +1,832 @@
/* virtualDiskLib.c - virtual disk driver library (vxSim) */
/*
* Copyright (c) 2003-2008,2010 Wind River Systems, Inc.
*
* The right to copy, distribute, modify or otherwise make use
* of this software may be licensed only pursuant to the terms
* of an applicable Wind River license agreement.
*/
/*
modification history
--------------------
01m,12jan10,elp 64bits support (host calls).
01l,27aug08,jpb Renamed VSB header file
01k,18jun08,jpb Renamed _WRS_VX_SMP to _WRS_CONFIG_SMP. Added include path
for kernel configurations options set in vsb.
01j,18jun07,elp renamed field to coding convention.
01i,23may07,elp added SMP support.
01h,25oct06,elp include vxsimHostLibP.h rather than vxsimHostLib.h
01g,25jul05,pcm updated comments for new file system framework
01f,11may04,jeg switched vxsimHostPrintf() calls to printf ()/printErr ().
01e,16mar04,md update parameters to vxsimHostPrintf()
01d,04feb04,dbt Fixed manuals.
01c,17oct03,jeg added semGive () call when ERROR is detected.
01b,16oct03,jeg added virtualDiskClose () API + cleanup.
01a,17jun03,jeg written
*/
/*
DESCRIPTION
The module provides APIs to emulate a VxWorks disk driver. The VxWorks disk
appears under a single host file.
The host file name and the disk formating parameters must be specified to
virtualDiskCreate () when creating the virtual disk. The parameters are then
stored into the virtual disk host file. If the virtual disk already exists,
all information regarding structure of the disk (number of bytes per block,
number of blocks per track and number of blocks on this device) are read
from the existing virtual disk; values passed in parameter of the
virtualDiskCreate() routine are ignored.
USER-CALLABLE ROUTINES
Most of the routines in this driver are accessible only through the I/O
system. The routine virtualDiskInit () must be called to initialize the driver
and the virtualDiskCreate () routine is used to create devices. Before
removing the host file associated with the virtual disk, the routine
virtualDiskClose () must be called.
CREATING VIRTUAL DISKS
Before a virtual disk can be used, it must be created. This is done
with the virtualDiskCreate() call. The format of this call is:
.CS
BLK_DEV * vitualDiskCreate
(
char * hostFile, /@ name of the host file to use @/
int bytesPerBlk, /@ number of bytes per block @/
int blksPerTrack, /@ number of blocks per track @/
int nBlocks /@ number of blocks on this device @/
)
.CE
The <hostFile> parameter specifies the name of the host file used for the
virtual disk. The host file pathname is a standard host pathname without
the host name. For Windows VxSim, the path separator to use is either
'\\' or '/' (i.e. c:/myDir/myFile or c:\\myDir\\myFile).
The <bytesPerBlk> parameter specifies the size of each logical block
on the disk. If <bytesPerBlk> is zero, 512 is the default.
The <blksPerTrack> parameter specifies the number of blocks on each
logical track of the host disk. If <blksPerTrack> is zero, the count of
blocks per track will be set to <nBlocks> (i.e., the disk will be defined
as having only one track).
The <nBlocks> parameter specifies the size of the disk, in blocks.
If <nBlocks> is zero, 512 is the default.
The formatting parameters (<bytesPerBlk>, <blksPerTrack>, and <nBlocks>)
are critical only if the host file does not exist. In that case, the
formatting parameters are used to compute the disk size and to fill the
block device structure.
The disk size is defined by bytesPerBlk * nBlocks. blksPerTrack is used to
calculate the number of track.
The virtualDiskCreate () API is not able to open an old unix disk created
with the unixDiskDevCreate () API.
The virtualDiskCreate () call returns a pointer to a block device structure.
This structure contains fields that describe the physical properties of a
disk device and specify the addresses of routines within the virtual disk
driver.
Once the device has been created, it still does not have a name or file system
associated with it. This can be done by creating an XBD wrapper for the
returned BLK_DEV pointer (eg. xbdBlkDevCreate (pBlkDev, "/deviceName")). The
file system framework will attempt to identify and instantiate the type file
system (if any) currently installed on the virtual disk. If no identifiable
file system was found, then it will be instantiated with rawFs. The type of
file system installed on the virtual disk can be changed at any time by
formatting it with the desired file system (eg. dosFsVolFormat(), hrfsFormat()).
As an example, to create a 208KB disk, 512-byte blocks, and 32 blocks per track,
the proper call would be:
.CS
BLK_DEV * pBlkDev;
pBlkDev = virtualDiskCreate ("c:/tmp/filesys1", 512, 32, 416);
.CE
This will attach the host file c:/tmp/filesys1 as a block device.
CLOSING VIRTUAL DISKS
Closing a virtual disk is done with the virtualDiskClose() call.
The format of this call is:
.CS
STATUS vitualDiskClose
(
BLK_DEV blkDev; /@ virtual disk block device to close @/
)
.CE
The <blkDev> parameter specifies the virtual disk block device to close.
The virtualDiskClose () API close the host file associated with the virtual
disk. The virtual disk referenced by blkDev can then be removed if needed.
IOCTL
Only the FIODISKFORMAT request is supported; all other ioctl requests
return an error, and set the task's errno to S_ioLib_UNKNOWN_REQUEST.
SEE ALSO:
xbdBlkDevCreate(), dosFsVolFormat(), hrfsFormat(),
dosfsDiskFormat(), hrfsDiskFormat()
INCLUDE FILES: virtualDiskLib.h
*/
/* includes */
#include <vxWorks.h>
#include <vsbConfig.h>
#include <blkIo.h>
#include <stdio.h>
#include <ioLib.h>
#include <iosLib.h>
#include <memLib.h>
#include <errno.h>
#include <dosFsLib.h>
#include <stdlib.h>
#include <bootLib.h>
#include <string.h>
#include <unistd.h>
#include <private/semLibP.h>
#include <private/vxsimHostLibP.h>
#include <virtualDiskLib.h>
#ifdef _WRS_CONFIG_SMP
#include <taskLib.h>
#include <private/windLibP.h>
#endif /* _WRS_CONFIG_SMP */
/* defines */
/* stored parameters max size */
#define PARAM_MAX_SIZE sizeof (VIRTUAL_DISK_PARAM)
#define VIRTUAL_DISK_MAGIC 0x148a25f1 /* host file magic number */
#define VERSION 1 /* virtual disk version number */
#define VIRTUAL_DISK_KBUF_SZ 0x4000 /* cache used to buffer RTPs buffers */
/* Allocate user space copy buffer (if not already done) */
#define VIRTUAL_DISK_KBUF_ALLOC_CHECK(pVirtualDiskDev) \
((pVirtualDiskDev->pKernelBuffer != NULL) ? TRUE : \
(((pVirtualDiskDev->pKernelBuffer = malloc (VIRTUAL_DISK_KBUF_SZ)) \
!= NULL)? TRUE : FALSE))
/* typedefs */
typedef struct /* virtual disk device descriptor */
{
BLK_DEV virtualDiskBlkDev; /* generic block device structure */
int hostFd; /* host file descriptor */
BOOL oldVirtualDisk; /* TRUE if it is an old unix disk */
char * pKernelBuffer; /* kernel buffer for RTP data copy */
} VIRTUAL_DISK_DEV;
typedef struct /* virtual disk formating parameters */
{
int mark; /* virtual disk file mark */
int bytesPerBlk; /* name of the host file */
int blksPerTrack; /* number of blocks per track */
int nBlocks; /* number of blocks on this device */
int version; /* virtual disk version number */
int endianness; /* endianness used to store parameters */
int unused1;
int unused2;
int unused3;
int unused4;
int unused5;
int unused6;
}VIRTUAL_DISK_PARAM;
/* globals */
SEMAPHORE virtDiskMuteSem; /* mutex semaphore for mutual-exclusion */
/* forward declarations */
LOCAL BLK_DEV * virtualDiskBlockDeviceCreate (VIRTUAL_DISK_PARAM vdParam,
int fd, BOOL old);
LOCAL STATUS virtualDiskIoctl (VIRTUAL_DISK_DEV * pVirtualDiskDev, int function,
int arg);
LOCAL STATUS virtualDiskBlkRd (VIRTUAL_DISK_DEV * pVirtualDiskDev, int startBlk,
int numBlks, char * pBuffer);
LOCAL STATUS virtualDiskBlkWrt (VIRTUAL_DISK_DEV * pVirtualDiskDev,
int startBlk, int numBlks, char * pBuffer);
/*******************************************************************************
*
* virtualDiskInit - install the virtual disk driver
*
* This routine is used to initialize the virtual disk driver. This
* routine is automatically called when the INCLUDE_VIRTUAL_DISK component
* is included.
*
* RETURNS: OK, always.
*/
STATUS virtualDiskInit (void)
{
semMInit (&virtDiskMuteSem, SEM_Q_PRIORITY | SEM_DELETE_SAFE |
SEM_INVERSION_SAFE);
return (OK);
}
/*******************************************************************************
*
* virtualDiskCreate - create a virtual disk device.
*
* This routine creates a virtual disk device. The host file is created if it
* does not exist. If it already exists, only the <hostFile> parameter is taken
* in account, the others parameters are extracted from the host file.
*
* The <hostFile> parameter specifies the name of the host file used for the
* virtual disk. The host file pathname is a standard host pathname without
* the host name. For Windows VxSim, the path separator to use is '\\' or '/'
* (i.e. c:/myDir/myFile or c:\\myDir\\myFile).
*
* The <bytesPerBlk> parameter specifies the size of each logical block
* on the disk. If <bytesPerBlk> is zero, 512 is the default.
*
* The <blksPerTrack> parameter specifies the number of blocks on each
* logical track of the disk. If <blksPerTrack> is zero, the count of
* blocks per track is set to <nBlocks> (i.e., the disk is defined
* as having only one track).
*
* The <nBlocks> parameter specifies the size of the disk, in blocks.
* If <nBlocks> is zero, 512 is the default.
*
* RETURNS: A pointer to block device (BLK_DEV) structure, or NULL if the
* virtual disk creation failed.
*/
BLK_DEV * virtualDiskCreate
(
char * hostFile, /* name of the host file */
int bytesPerBlk, /* number of bytes per block */
int blksPerTrack, /* number of blocks per track */
int nBlocks /* number of blocks on this device */
)
{
VIRTUAL_DISK_PARAM vdParam; /* virtual disk formating parameters */
int fd; /* host file descriptor */
char * hFile; /* dup file name in kernel for host call */
/* Set up defaults for any values not specified */
if (bytesPerBlk == 0)
{
vdParam.bytesPerBlk = DEFAULT_SIZE;
}
else
{
vdParam.bytesPerBlk = bytesPerBlk;
}
if (nBlocks == 0)
{
vdParam.nBlocks = DEFAULT_SIZE;
}
else
{
vdParam.nBlocks = nBlocks;
}
if (blksPerTrack == 0)
{
vdParam.blksPerTrack = nBlocks;
}
else
{
vdParam.blksPerTrack = blksPerTrack;
}
vdParam.mark = VIRTUAL_DISK_MAGIC;
vdParam.version = VERSION;
vdParam.endianness = _BYTE_ORDER;
/*
* make sure filename is stored in kernel memory before calling
* vxsimHostOpen()
*/
if ((hFile = strdup (hostFile)) == NULL)
{
printErr ("virtualDiskCreate: not enough memory\n");
return NULL;
}
/* check if the virtual disk host file already exist */
if ((fd = vxsimHostOpen (hFile, O_RDWR, S_IRUSR| S_IWUSR)) < 0)
{
/* the file does not exist, it must be created. */
printf ("virtualDiskCreate: %s not found. Creating ... \n", hostFile);
fd = vxsimHostOpen (hFile, O_RDWR| O_CREAT, S_IRUSR| S_IWUSR);
free (hFile); /* no longer needed */
if (fd < 0)
{
printErr ("virtualDiskCreate: can not create host file %s \n",
hostFile);
return (NULL);
}
/* store the virtual disk mark and parameters into the host file */
if (vxsimHostWrite (fd, (char *) &vdParam, PARAM_MAX_SIZE)
!= PARAM_MAX_SIZE)
{
printErr ("virtualDiskCreate : can't store parameters\n");
vxsimHostClose (fd);
return (NULL);
}
/* fill the file to get the appropriated file size */
if (vxsimHostFtruncate (fd, bytesPerBlk * nBlocks + PARAM_MAX_SIZE)
!= 0)
{
printErr ("virtualDiskCreate : can't truncate host file\n");
vxsimHostClose (fd);
return (NULL);
}
}
else
{
free (hFile); /* no longer needed */
/* the virtual disk file already exist, the formatting parameters are
* exctracted from the host disk file.
*/
if (vxsimHostRead (fd, (char *)&vdParam, (size_t)PARAM_MAX_SIZE) !=
PARAM_MAX_SIZE)
{
printErr ("virtualDiskCreate : can't read parameters.\n");
vxsimHostClose (fd);
return (NULL);
}
/* take in account the endianess used to store parameters */
if (vdParam.endianness != _BYTE_ORDER)
{
vdParam.bytesPerBlk = LONGSWAP (vdParam.bytesPerBlk);
vdParam.blksPerTrack = LONGSWAP (vdParam.blksPerTrack);
vdParam.nBlocks = LONGSWAP (vdParam.nBlocks);
vdParam.version = LONGSWAP (vdParam.version);
vdParam.mark = LONGSWAP (vdParam.mark);
}
/* check the virtual disk mark, if it is not correct, the extraction
* failed or user is opening and old unix disk or a non virtual disk
* file.
*/
if (vdParam.mark != (int) VIRTUAL_DISK_MAGIC)
{
printErr ("virtualDiskCreate: virtual disk mark not found.");
printErr (" %s is probably not a virtual disk file. \n", hostFile);
vxsimHostClose (fd);
return (NULL);
}
}
/* create and return the virtual disk device */
return ((BLK_DEV * ) virtualDiskBlockDeviceCreate (vdParam, fd, FALSE));
}
/*******************************************************************************
*
* virtualDiskOldCreate - create an old virtual disk device .
*
* This routine creates an old virtual disk device (a unix disk). This API
* must not be called, it is a private function only used by
* unixDiskDevCreate () API.
*
* The <hostFile> parameter specifies the name of the host file to use
* for the disk device.
*
* The <bytesPerBlk> parameter specifies the size of each logical block
* on the disk.
*
* The <blksPerTrack> parameter specifies the number of blocks on each
* logical track of the disk.
*
* The <nBlocks> parameter specifies the size of the disk, in blocks.
*
* The parameters are not verified, this is already done by unixDiskDevCreate ()
* routine. The host file already exist, this is checked by unixDiskDevCreate ()
* API.
*
* RETURNS: A pointer to block device (BLK_DEV) structure, or NULL if the
* virtual disk creation failed.
*
* NOMANUAL
*/
BLK_DEV * virtualDiskOldCreate
(
char * hostFile, /* name of the host file */
int bytesPerBlk, /* number of bytes per block */
int blksPerTrack, /* number of blocks per track */
int nBlocks /* number of blocks on this device */
)
{
VIRTUAL_DISK_PARAM vdParam; /* virtual disk formating parameters */
int fd; /* host file descriptor */
char * hFile; /* dup in kernel for host call */
vdParam.bytesPerBlk = bytesPerBlk;
vdParam.nBlocks = nBlocks;
vdParam.blksPerTrack = blksPerTrack;
/* open the virtual disk host file */
if ((hFile = strdup (hostFile)) == NULL)
{
return NULL;
}
if ((fd = vxsimHostOpen (hostFile, O_RDWR, S_IRUSR| S_IWUSR)) < 0)
{
free (hFile);
return (NULL);
}
free (hFile);
/* create and return the block device */
return ((BLK_DEV * ) virtualDiskBlockDeviceCreate (vdParam, fd, TRUE));
}
/*******************************************************************************
*
* virtualDiskBlockDeviceCreate - create a virtual disk block device.
*
* This routine creates and return a virtual disk block device.
*
* The <vdParam> parameter specifies the virtual disk formating parameters.
*
* The <fd> parameter specifies the host file descriptor.
*
* The <old> parameter specifies if it is and old virtual disk (unix disk).
*
* RETURNS: A pointer to block device (BLK_DEV) structure, or NULL if the
* virtual disk creation failed.
*/
LOCAL BLK_DEV * virtualDiskBlockDeviceCreate
(
VIRTUAL_DISK_PARAM vdParam, /* virtual disk formating parameters */
int fd, /* host file descriptor */
BOOL old /* TRUE if it is an old virtual disk */
)
{
/* pointer to created VIRTUAL_DISK_DEV structure */
VIRTUAL_DISK_DEV * pVirtualDiskDev;
/* ptr to BLK_DEV struct in VIRTUAL_DISK_DEV */
BLK_DEV * pBlkDev;
pVirtualDiskDev = (VIRTUAL_DISK_DEV *)calloc (1, sizeof (VIRTUAL_DISK_DEV));
if (pVirtualDiskDev == NULL)
{
printErr ("virtualDiskCreate: Could not allocate memory \n");
if (vxsimHostClose (fd) == ERROR)
{
printErr ("virtualDiskCreate: Could not close host file\n");
}
return (NULL); /* no memory */
}
pVirtualDiskDev->oldVirtualDisk = old;
/* Initialize BLK_DEV structure (in VIRTUAL_DISK_DEV) */
pBlkDev = &pVirtualDiskDev->virtualDiskBlkDev;
pBlkDev->bd_nBlocks = vdParam.nBlocks; /* number of blocks */
pBlkDev->bd_bytesPerBlk = vdParam.bytesPerBlk; /* bytes per block */
pBlkDev->bd_blksPerTrack = vdParam.blksPerTrack;/* blocks per track */
pBlkDev->bd_nHeads = 1; /* one "head" */
pBlkDev->bd_removable = FALSE; /* not removable */
pBlkDev->bd_retry = 1; /* retry count */
pBlkDev->bd_mode = UPDATE; /* initial mode for device */
pBlkDev->bd_readyChanged = TRUE; /* new ready status */
pBlkDev->bd_blkRd = virtualDiskBlkRd; /* read block function */
pBlkDev->bd_blkWrt = virtualDiskBlkWrt;/* write block function */
pBlkDev->bd_ioctl = virtualDiskIoctl; /* ioctl function */
pBlkDev->bd_reset = NULL; /* no reset function */
pBlkDev->bd_statusChk = NULL; /* no check-status function */
/* Initialize remainder of device struct */
pVirtualDiskDev->hostFd = fd;
return (pBlkDev);
}
/*******************************************************************************
*
* virtualDiskClose - close a virtual disk block device.
*
* This routine closes a virtual disk block device by closing the host
* file associated with the virtual disk.
*
* The <blkDev> parameter specifies the virtual disk to close.
*
* RETURNS: OK on success, else ERROR.
*/
STATUS virtualDiskClose
(
BLK_DEV * blkDev /* virtual disk block device */
)
{
int hostFdOffset; /* offset of hostFd field */
int * fd; /* host file descriptor */
/* close the virtual disk host file */
hostFdOffset = OFFSET(VIRTUAL_DISK_DEV, hostFd);
fd = (int *) (blkDev) + hostFdOffset / sizeof (int);
if (vxsimHostClose (*fd) == ERROR)
{
printErr ("virtualDiskClose: unable to close host file\n");
return (ERROR);
}
return (OK);
}
/*******************************************************************************
*
* virtualDiskIoctl - do device specific control function
*
* This routine is called when the file system cannot handle an ioctl
* function.
*
* The FIODISKFORMAT function always returns OK, since a host file does
* not require formatting. All other requests return ERROR.
*
* RETURNS: OK or ERROR.
*/
LOCAL STATUS virtualDiskIoctl
(
VIRTUAL_DISK_DEV * pVirtualDiskDev, /* device structure pointer */
int function, /* function code */
int arg /* some argument */
)
{
FAST int status; /* returned status value */
switch (function)
{
case FIODISKFORMAT:
status = OK;
break;
default:
status = ERROR;
errno = S_ioLib_UNKNOWN_REQUEST;
break;
}
return (status);
}
/*******************************************************************************
*
* virtualDiskBlkRd - read one or more blocks from a virtual file disk volume
*
* This routine reads one or more blocks from the specified volume,
* starting with the specified block number. The byte offset is
* calculated and the virtual disk data is copied to the specified buffer.
*
* RETURNS: OK for success and ERROR for bad block.
*/
LOCAL STATUS virtualDiskBlkRd
(
VIRTUAL_DISK_DEV * pVirtualDiskDev,/* pointer to device desriptor */
int startBlk, /* starting block number to read */
int numBlks, /* number of blocks to read */
char * pBuffer /* pointer to buffer to receive data */
)
{
off_t offset; /* host file offset */
size_t numBytes; /* number of bytes to read */
ssize_t readCnt = 0; /* bytes read */
FAST int bytesPerBlk; /* number of bytes per block */
#ifdef _WRS_CONFIG_SMP
size_t chunkRdSz; /* chunk size if read has to be splitted */
ssize_t chunkRd; /* chunk bytes read */
#endif /* _WRS_CONFIG_SMP */
/*
* if the formatting parameters are stored into the host file, an offset
* must be added to avoid the area where the parameters are saved
*/
if ( pVirtualDiskDev->oldVirtualDisk)
{
offset = 0;
}
else
{
offset = PARAM_MAX_SIZE;
}
bytesPerBlk = pVirtualDiskDev->virtualDiskBlkDev.bd_bytesPerBlk;
/* Add in the block offset */
offset += startBlk*bytesPerBlk;
semTake (&virtDiskMuteSem, WAIT_FOREVER);
if (vxsimHostLseek (pVirtualDiskDev->hostFd, offset, 0) != offset)
{
printErr ("virtualDiskBlkRd: lseek to offset %d failed\n", offset);
semGive (&virtDiskMuteSem);
return (ERROR);
}
numBytes = bytesPerBlk * numBlks;
/* Read the block(s) */
#ifdef _WRS_CONFIG_SMP
if (!IS_KERNEL_TASK(_WRS_KERNEL_GLOBAL_ACCESS(taskIdCurrent)))
{
/*
* if not kernel task use temporary buffer to provide kernel address
* to vxsimHostRead() host call
*/
if (VIRTUAL_DISK_KBUF_ALLOC_CHECK(pVirtualDiskDev))
{
while (readCnt < numBytes)
{
chunkRdSz = min ((numBytes - readCnt), VIRTUAL_DISK_KBUF_SZ);
chunkRd = vxsimHostRead (pVirtualDiskDev->hostFd,
pVirtualDiskDev->pKernelBuffer,
chunkRdSz);
if (chunkRd != chunkRdSz)
{
readCnt += chunkRd;
break;
}
bcopy (pVirtualDiskDev->pKernelBuffer, pBuffer, chunkRd);
pBuffer += chunkRd;
readCnt += chunkRd;
}
}
}
else
readCnt = vxsimHostRead (pVirtualDiskDev->hostFd, pBuffer, numBytes);
#else /* _WRS_CONFIG_SMP */
readCnt = vxsimHostRead (pVirtualDiskDev->hostFd, pBuffer, numBytes);
#endif /* _WRS_CONFIG_SMP */
semGive (&virtDiskMuteSem);
if (readCnt != numBytes)
{
printErr ("virtualDiskBlkRd: failed to read %d bytes\n", numBytes);
return (ERROR);
}
return (OK);
}
/*******************************************************************************
*
* virtualDiskBlkWrt - write one or more blocks to a virtual disk volume
*
* This routine writes one or more blocks to the specified volume,
* starting with the specified block number. The byte offset is
* calculated and the buffer data is copied to the virtual disk.
*
* RETURNS: OK for success and ERROR for bad block.
*/
LOCAL STATUS virtualDiskBlkWrt
(
VIRTUAL_DISK_DEV * pVirtualDiskDev,/* pointer to device desriptor */
int startBlk, /* starting block number to write */
int numBlks, /* number of blocks to write */
char * pBuffer /* pointer to buffer of data to write */
)
{
off_t offset;
size_t numBytes;
ssize_t writeCnt = 0;
FAST ssize_t bytesPerBlk; /* number of bytes per block */
#ifdef _WRS_CONFIG_SMP
size_t chunkWrSz; /* chunk size if write has to be splitted */
ssize_t chunkWr; /* chunk bytes written */
#endif /* _WRS_CONFIG_SMP */
/*
* if the formatting parameters are stored into the host file, an offset
* must be added to avoid the area where the parameters are saved
*/
if ( pVirtualDiskDev->oldVirtualDisk)
{
offset = 0;
}
else
{
offset = PARAM_MAX_SIZE;
}
bytesPerBlk = pVirtualDiskDev->virtualDiskBlkDev.bd_bytesPerBlk;
/* Add in the block offset */
offset += startBlk * bytesPerBlk;
semTake (&virtDiskMuteSem, WAIT_FOREVER);
if (vxsimHostLseek (pVirtualDiskDev->hostFd, offset, 0) != offset)
{
printErr ("virtualDiskBlkWrt: lseek to offset %d failed\n", offset);
semGive (&virtDiskMuteSem);
return (ERROR);
}
numBytes = bytesPerBlk * numBlks;
#ifdef _WRS_CONFIG_SMP
if (!IS_KERNEL_TASK(_WRS_KERNEL_GLOBAL_ACCESS(taskIdCurrent)))
{
/*
* if not kernel task use cache to provide a kernel address to
* vxsimHostWrite()
*/
if (VIRTUAL_DISK_KBUF_ALLOC_CHECK(pVirtualDiskDev))
{
while (writeCnt < numBytes)
{
chunkWrSz = min (VIRTUAL_DISK_KBUF_SZ, (numBytes - writeCnt));
bcopy (pBuffer, pVirtualDiskDev->pKernelBuffer, chunkWrSz);
chunkWr = vxsimHostWrite (pVirtualDiskDev->hostFd,
pVirtualDiskDev->pKernelBuffer,
chunkWrSz);
if (chunkWr != chunkWrSz)
{
writeCnt += chunkWr;
break;
}
writeCnt += chunkWr;
pBuffer += chunkWr;
}
}
}
else
writeCnt = vxsimHostWrite (pVirtualDiskDev->hostFd, pBuffer, numBytes);
#else /* _WRS_CONFIG_SMP */
writeCnt = vxsimHostWrite (pVirtualDiskDev->hostFd, pBuffer, numBytes);
#endif /* _WRS_CONFIG_SMP */
semGive (&virtDiskMuteSem);
if (writeCnt != numBytes)
{
printErr ("virtualDiskBlkWrt: failed to write %d bytes\n", numBytes);
return (ERROR);
}
return (OK);
}