original files of m241
This commit is contained in:
@@ -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
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user