RTFSをver.44xからver.44zbへバージョンアップ

git-svn-id: file:///Users/lillianskinner/Downloads/platinum/twl/twl_wrapsdk/trunk@321 4ee2a332-4b2b-5046-8439-1ba90f034370
This commit is contained in:
shirait 2007-11-22 05:23:18 +00:00
parent 6751049144
commit a7449d85df
31 changed files with 2029 additions and 553 deletions

View File

@ -37,6 +37,8 @@
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
extern変数 extern変数
*---------------------------------------------------------------------------*/ *---------------------------------------------------------------------------*/
extern void (*func_SDCARD_In)(void); /* カード挿入イベント用コールバック保存用 */
extern void (*func_SDCARD_Out)(void); /* カード排出イベント用コールバック保存用 */
extern int rtfs_first_stat_flag[26]; extern int rtfs_first_stat_flag[26];
/*SDメモリカードのスペック構造体*/ /*SDメモリカードのスペック構造体*/
@ -306,7 +308,7 @@ int nandRtfsCtrl( int driveno, int opcode, void* pargs)
case DEVCTL_WARMSTART: //attachのときしか呼ばれない case DEVCTL_WARMSTART: //attachのときしか呼ばれない
PRINTDEBUG( "DEVCTL_WARMSTART\n"); PRINTDEBUG( "DEVCTL_WARMSTART\n");
/*-- GoIdleセット --*/ /*-- GoIdleセット --*/
sdmcGoIdle( NULL, NULL); //カード初期化シーケンス TODO:1ポートだけにする sdmcGoIdle( func_SDCARD_In, func_SDCARD_Out); //カード初期化シーケンス TODO:1ポートだけにする
/*------------------*/ /*------------------*/
pdr->drive_flags |= (DRIVE_FLAGS_VALID | DRIVE_FLAGS_REMOVABLE | DRIVE_FLAGS_PARTITIONED); pdr->drive_flags |= (DRIVE_FLAGS_VALID | DRIVE_FLAGS_REMOVABLE | DRIVE_FLAGS_PARTITIONED);
pdr->drive_flags |= DRIVE_FLAGS_INSERTED; pdr->drive_flags |= DRIVE_FLAGS_INSERTED;

View File

@ -1,5 +1,5 @@
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
Project: CTR - SD driver Project: TWL - SD driver
File: sdif_reg.h File: sdif_reg.h
Copyright 2006,2007 Nintendo. All rights reserved. Copyright 2006,2007 Nintendo. All rights reserved.

View File

@ -39,7 +39,7 @@ SRCS = apistat.c prfsapi.c rtlowl.c apickdsk.c apiwrite.c \
apifilio.c csjis.c rtdevio.c rtvfat.c apifilmv.c csjistab.c \ apifilio.c csjis.c rtdevio.c rtvfat.c apifilmv.c csjistab.c \
rtdrobj.c apifrmat.c csstrtab.c rtfat16.c apigetwd.c \ rtdrobj.c apifrmat.c csstrtab.c rtfat16.c apigetwd.c \
rtfat32.c apigfrst.c csunicod.c rtfatxx.c apiinfo.c \ rtfat32.c apigfrst.c csunicod.c rtfatxx.c apiinfo.c \
portio.c apiinit.c portkern.c \ portio.c apiinit.c portkern.c apifastmv.c \
apimkdir.c apirealt.c \ apimkdir.c apirealt.c \
prapipro.c apiregrs.c prblock.c apisetwd.c \ prapipro.c apiregrs.c prblock.c apisetwd.c \
rtkernfn.c \ rtkernfn.c \

View File

@ -12,13 +12,13 @@
* *
* Description - This routine traverses a subdirectory tree. It tests each * Description - This routine traverses a subdirectory tree. It tests each
* directory entry to see if it matches user supplied selection criteria. * directory entry to see if it matches user supplied selection criteria.
* if it does match the criteria a user supplied callback function is * if it does match the criteria a user supplied callback function is
* called with the full path name of the directory entry and a pointer * called with the full path name of the directory entry and a pointer
* to a DSTAT structure that contains detailed information about the * to a DSTAT structure that contains detailed information about the
* directory entry. (see the manual page for a detailed description of the * directory entry. (see the manual page for a detailed description of the
* DSTAT structure. * DSTAT structure.
* *
* Selection criteria - Two arguments are used to determine the selection * Selection criteria - Two arguments are used to determine the selection
* criteria. On is a flags word that specifies attributes the other is * criteria. On is a flags word that specifies attributes the other is
* a pattern that specifies a wild card pattern. * a pattern that specifies a wild card pattern.
* The flags argument contains a bitwise or of one or more of the following: * The flags argument contains a bitwise or of one or more of the following:
@ -29,10 +29,10 @@
* MATCH_DOTDOT - Select the '..' entry MATCH_DIR must be true also * MATCH_DOTDOT - Select the '..' entry MATCH_DIR must be true also
* *
* The selection pattern is a standard wildcard pattern such as '*.*' or * The selection pattern is a standard wildcard pattern such as '*.*' or
* *.txt. * *.txt.
* Note: Patterns don't work the same for VFAT and DOS 8.3. If VFAT is * Note: Patterns don't work the same for VFAT and DOS 8.3. If VFAT is
* enable the pattern *.* will return any file name that has a '.' in it * enable the pattern *.* will return any file name that has a '.' in it
* in 8.3 systems it returns all files. * in 8.3 systems it returns all files.
* *
* Note: pc_enumerate() requires a fair amount of buffer space to function. * Note: pc_enumerate() requires a fair amount of buffer space to function.
* Instead of allocating the space internally we require that the application * Instead of allocating the space internally we require that the application
@ -48,7 +48,7 @@
* byte * root_search - Root of the search IE C:\ or C:\USR etc. * byte * root_search - Root of the search IE C:\ or C:\USR etc.
* word match_flags - Selection flags (see above) * word match_flags - Selection flags (see above)
* byte match_pattern - Match pattern (see above) * byte match_pattern - Match pattern (see above)
* int maxdepth - Maximum depth of the traversal. * int maxdepth - Maximum depth of the traversal.
* Note: to scan only one level set this to * Note: to scan only one level set this to
* 1. For all levels set it to 99 * 1. For all levels set it to 99
* PENUMCALLBACK pcallback - User callback function. (see below) * PENUMCALLBACK pcallback - User callback function. (see below)
@ -66,44 +66,44 @@
* About the callback. * About the callback.
* *
* The callback function is a function that returns an integer and is passed * The callback function is a function that returns an integer and is passed
* the fully qualified path to the current directory entry and a DSTAT * the fully qualified path to the current directory entry and a DSTAT
* structure. The callback fuction must return 0 if it wishes the scan to * structure. The callback fuction must return 0 if it wishes the scan to
* continue or any other integer value to stop the scan and return the * continue or any other integer value to stop the scan and return the
* callback's return value to the application layer. * callback's return value to the application layer.
* *
* Examples * Examples
* *
* The next two function implement a multilevel directory scan. * The next two function implement a multilevel directory scan.
* int rdir_callback(byte *path, DSTAT *d) {printf("%s\n", path);return(0);} * int rdir_callback(byte *path, DSTAT *d) {printf("%s\n", path);return(0);}
* *
* rdir(byte *path, byte *pattern) * rdir(byte *path, byte *pattern)
* { * {
* pc_enumerate(from_path,from_pattern,spath,dpath,path, * pc_enumerate(from_path,from_pattern,spath,dpath,path,
* (MATCH_DIR|MATCH_VOL|MATCH_FILES), pattern, 99, rdir_callback); * (MATCH_DIR|MATCH_VOL|MATCH_FILES), pattern, 99, rdir_callback);
* } * }
* *
* Poor mans deltree package * Poor mans deltree package
* int delfile_callback(byte *path, DSTAT *d) { * int delfile_callback(byte *path, DSTAT *d) {
* pc_unlink(path); return(0); * pc_unlink(path); return(0);
* } * }
* int deldir_callback(byte *path, DSTAT *d) { * int deldir_callback(byte *path, DSTAT *d) {
* pc_rmdir(path); return(0); * pc_rmdir(path); return(0);
* } * }
* *
* *
* deltree(byte *path) * deltree(byte *path)
* { * {
* int i; * int i;
* ==> First delete all of the files * ==> First delete all of the files
* pc_enumerate(from_path,from_pattern,spath,dpath,path, * pc_enumerate(from_path,from_pattern,spath,dpath,path,
* (MATCH_FILES), "*",99, delfile_callback); * (MATCH_FILES), "*",99, delfile_callback);
* i = 0; * i = 0;
* ==> Now delete all of the dirs.. deleting path won't work until the * ==> Now delete all of the dirs.. deleting path won't work until the
* ==> tree is empty * ==> tree is empty
* while(!pc_rmdir(path) && i++ < 50) * while(!pc_rmdir(path) && i++ < 50)
* pc_enumerate(from_path,from_pattern,spath,dpath,path, * pc_enumerate(from_path,from_pattern,spath,dpath,path,
* (MATCH_DIR), "*", 99, deldir_callback); * (MATCH_DIR), "*", 99, deldir_callback);
* } * }
* *
*/ */
@ -172,24 +172,24 @@ int pc_enumerate( /* __apifn__ */
for(i = 0; i < 8; i++) if (filepat[i]==' ') filepat[i]=0; for(i = 0; i < 8; i++) if (filepat[i]==' ') filepat[i]=0;
for(i = 0; i < 3; i++) if (extpat[i]==' ') extpat[i]=0; for(i = 0; i < 3; i++) if (extpat[i]==' ') extpat[i]=0;
#endif #endif
ret_val = 0; ret_val = 0;
pc_str2upper((byte *)from_path_buffer, (byte *) root_search); pc_str2upper((byte *)from_path_buffer, (byte *) root_search);
depth = 0; depth = 0;
pc_mpath(from_pattern_buffer, from_path_buffer, (byte *)ALL_FILES); pc_mpath(from_pattern_buffer, from_path_buffer, (byte *)ALL_FILES);
dir_index[0] = 0; dir_index[0] = 0;
dir_block[0] = 0; dir_block[0] = 0;
do do
{ {
step_into_dir: step_into_dir:
dodone = 0; dodone = 0;
if (pc_gfirst(&statobj, (byte *)from_pattern_buffer)) if (pc_gfirst(&statobj, (byte *)from_pattern_buffer))
{ {
dodone = 1; dodone = 1;
process_it = 0; process_it = 0;
do do
@ -204,30 +204,30 @@ step_into_dir:
if (process_it) if (process_it)
{ {
call_back = 1; call_back = 1;
/* Don't report directories if not requested */ /* Don't report directories if not requested */
if ((statobj.fattribute & ADIRENT) && if ((statobj.fattribute & ADIRENT) &&
!(match_flags & MATCH_DIR) ) !(match_flags & MATCH_DIR) )
call_back = 0; call_back = 0;
/* Don't report volumes if not requested */ /* Don't report volumes if not requested */
if (call_back && (statobj.fattribute & AVOLUME) && if (call_back && (statobj.fattribute & AVOLUME) &&
!(match_flags & MATCH_VOL) ) !(match_flags & MATCH_VOL) )
call_back = 0; call_back = 0;
/* Don't report plain files if not requested */ /* Don't report plain files if not requested */
if (call_back && !(statobj.fattribute & (AVOLUME|ADIRENT)) && if (call_back && !(statobj.fattribute & (AVOLUME|ADIRENT)) &&
!(match_flags & MATCH_FILES) ) !(match_flags & MATCH_FILES) )
call_back = 0; call_back = 0;
/* Don't report DOT if not requested */ /* Don't report DOT if not requested */
if (call_back && dirscan_isdot(&statobj) && !(match_flags & MATCH_DOT)) if (call_back && dirscan_isdot(&statobj) && !(match_flags & MATCH_DOT))
call_back = 0; call_back = 0;
/* Don't report DOTDOT if not requested */ /* Don't report DOTDOT if not requested */
if (call_back && dirscan_isdotdot(&statobj) && !(match_flags & MATCH_DOTDOT)) if (call_back && dirscan_isdotdot(&statobj) && !(match_flags & MATCH_DOTDOT))
call_back = 0; call_back = 0;
if (call_back) if (call_back)
{ {
/* Take it if the pattern match work */ /* Take it if the pattern match work */
@ -240,7 +240,7 @@ step_into_dir:
#else #else
/* Non VFAT uses 8.3 matching conventions */ /* Non VFAT uses 8.3 matching conventions */
pc_ascii_fileparse(filepat, extpat, (byte *)match_pattern); pc_ascii_fileparse(filepat, extpat, (byte *)match_pattern);
call_back = call_back =
pc_patcmp_8((byte *)&statobj.fname[0], (byte *)&filepat[0] , TRUE); pc_patcmp_8((byte *)&statobj.fname[0], (byte *)&filepat[0] , TRUE);
call_back = call_back && call_back = call_back &&
pc_patcmp_3((byte *)&statobj.fext[0], (byte *)&extpat[0] , TRUE); pc_patcmp_3((byte *)&statobj.fext[0], (byte *)&extpat[0] , TRUE);
@ -267,7 +267,7 @@ step_into_dir:
{ {
/* Construct the full path */ /* Construct the full path */
pc_mpath(spath_buffer, from_path_buffer, (byte *)statobj.filename); pc_mpath(spath_buffer, from_path_buffer, (byte *)statobj.filename);
if (statobj.fattribute & (AVOLUME | ADIRENT)) if (statobj.fattribute & (AVOLUME | ADIRENT))
{ {
if (pc_gnext(&statobj)) if (pc_gnext(&statobj))
@ -277,7 +277,7 @@ step_into_dir:
dir_index[depth] = ((DROBJ *) (statobj.pobj))->blkinfo.my_index; dir_index[depth] = ((DROBJ *) (statobj.pobj))->blkinfo.my_index;
dodone = 0; dodone = 0;
pc_gdone(&statobj); pc_gdone(&statobj);
} }
else else
{ {
@ -285,23 +285,23 @@ step_into_dir:
pc_gdone(&statobj); pc_gdone(&statobj);
dir_index[depth] = -1; dir_index[depth] = -1;
} }
depth += 1; depth += 1;
dir_block[depth] = 0; dir_block[depth] = 0;
dir_index[depth] = 0; dir_index[depth] = 0;
rtfs_cs_strcpy((byte *)from_path_buffer, (byte *)spath_buffer); rtfs_cs_strcpy((byte *)from_path_buffer, (byte *)spath_buffer);
pc_mpath(from_pattern_buffer, from_path_buffer, (byte *)ALL_FILES); pc_mpath(from_pattern_buffer, from_path_buffer, (byte *)ALL_FILES);
goto step_into_dir; goto step_into_dir;
} }
} }
} while (pc_gnext(&statobj)); /* Get the next file in dir */ } while (pc_gnext(&statobj)); /* Get the next file in dir */
if (dodone) if (dodone)
pc_gdone(&statobj); pc_gdone(&statobj);
} }
if (!get_parent_path(from_path_buffer, from_path_buffer)) if (!get_parent_path(from_path_buffer, from_path_buffer))
break; break;
pc_mpath(from_pattern_buffer, from_path_buffer, (byte *)ALL_FILES); pc_mpath(from_pattern_buffer, from_path_buffer, (byte *)ALL_FILES);
@ -309,7 +309,12 @@ step_into_dir:
while (depth >= 0 && dir_index[depth] == -1) while (depth >= 0 && dir_index[depth] == -1)
{ {
if (!get_parent_path(from_path_buffer, from_path_buffer)) if (!get_parent_path(from_path_buffer, from_path_buffer))
break; {
if(depth == 0) /* If we are at the root and have no more files, exit */
goto ex_it;
else
break;
}
pc_mpath(from_pattern_buffer, from_path_buffer, (byte *)ALL_FILES); pc_mpath(from_pattern_buffer, from_path_buffer, (byte *)ALL_FILES);
depth--; depth--;
} }
@ -322,9 +327,9 @@ int get_parent_path(byte *parent, byte *path)
{ {
byte *last_backslash; byte *last_backslash;
int size; int size;
last_backslash = 0; last_backslash = 0;
size = 0; size = 0;
while (*path != '\0') while (*path != '\0')
{ {
@ -336,11 +341,11 @@ int get_parent_path(byte *parent, byte *path)
*(parent++) = *(path++); *(parent++) = *(path++);
} }
/* This is to prevent catastrophie if caller ignores failure */ /* This is to prevent catastrophie if caller ignores failure */
*parent = '\0'; *parent = '\0';
if (size < 3) if (size < 3)
return (0); return (0);
if (last_backslash) if (last_backslash)
*last_backslash = '\0'; *last_backslash = '\0';
return (1); return (1);
@ -365,7 +370,7 @@ int dirscan_isdotdot(DSTAT *statobj)
} }
#ifdef NOTDEF #ifdef NOTDEF
/* The section from here to the bottom of the file contains code that /* The section from here to the bottom of the file contains code that
shows via example how to use the enumerate function. shows via example how to use the enumerate function.
*/ */
@ -401,21 +406,21 @@ int main(int argc,byte **argv)
byte filter[20]; byte filter[20];
byte op; byte op;
rtfs_kernel_init(); rtfs_kernel_init();
argc--; argc--;
argv++; argv++;
if (argc < 2) if (argc < 2)
{ {
goto usage; goto usage;
} }
op = *argv[0]; op = *argv[0];
rtfs_cs_strcpy((byte *)filter,FILTER); rtfs_cs_strcpy((byte *)filter,FILTER);
argc--; argv++; argc--; argv++;
/* Process user options */ /* Process user options */
rtfs_cs_strcpy(src_path,*argv); rtfs_cs_strcpy(src_path,*argv);
argc--; argv++; argc--; argv++;
if (argc) if (argc)
{ {
@ -425,7 +430,7 @@ int main(int argc,byte **argv)
{ {
rtfs_cs_strcpy((byte *)filter,FILTER); rtfs_cs_strcpy((byte *)filter,FILTER);
} }
if (op=='R') if (op=='R')
{ {
rdir(src_path, filter); rdir(src_path, filter);
@ -439,9 +444,9 @@ int main(int argc,byte **argv)
usage: usage:
RTFS_PRINTF("(R)dir or (D)eltree PATH [pattern]\n"); RTFS_PRINTF("(R)dir or (D)eltree PATH [pattern]\n");
} }
/* treeprintnew (src_path, filter, be_verbose); */ /* treeprintnew (src_path, filter, be_verbose); */
} }
@ -459,7 +464,7 @@ int rdir_callback(byte *path, DSTAT *d)
rdir(byte *path, byte *pattern) rdir(byte *path, byte *pattern)
{ {
pc_enumerate(from_path,from_pattern,spath,dpath,path, pc_enumerate(from_path,from_pattern,spath,dpath,path,
(MATCH_DIR|MATCH_VOL|MATCH_FILES), pattern, 99, rdir_callback); (MATCH_DIR|MATCH_VOL|MATCH_FILES), pattern, 99, rdir_callback);
} }
@ -482,19 +487,18 @@ deltree(byte *path)
{ {
int i; int i;
/* First delete all of the files */ /* First delete all of the files */
pc_enumerate(from_path,from_pattern,spath,dpath,path, pc_enumerate(from_path,from_pattern,spath,dpath,path,
(MATCH_FILES), "*",99, delfile_callback); (MATCH_FILES), "*",99, delfile_callback);
i = 0; i = 0;
/* Now delete all of the dirs.. deleting the root of the path won't /* Now delete all of the dirs.. deleting the root of the path won't
work until the tree is empty */ work until the tree is empty */
while(!pc_rmdir(path) && i++ < 50) while(!pc_rmdir(path) && i++ < 50)
{ {
pc_enumerate(from_path,from_pattern,spath,dpath,path, pc_enumerate(from_path,from_pattern,spath,dpath,path,
(MATCH_DIR), "*", 99, deldir_callback); (MATCH_DIR), "*", 99, deldir_callback);
} }
} }
#endif #endif
#endif /* (!INCLUDE_CS_UNICODE) BUGBUG - Not doing ENUM yet */ #endif /* (!INCLUDE_CS_UNICODE) BUGBUG - Not doing ENUM yet */

File diff suppressed because it is too large Load Diff

View File

@ -776,27 +776,36 @@ BOOLEAN _po_ulseek(PC_FILE *pfile, dword offset, dword *new_offset, int origin)
else if (origin == PSEEK_CUR_NEG) /* offset from current file pointer */ else if (origin == PSEEK_CUR_NEG) /* offset from current file pointer */
{ {
file_pointer = pfile->fptr; file_pointer = pfile->fptr;
if (file_pointer > offset) if (file_pointer >= offset)
file_pointer -= offset; file_pointer -= offset;
else else
file_pointer = 0; { /* Seek before beginning of file is an error */
p_errno = PEINVALIDPARMS;
goto errex;
}
} }
else if (origin == PSEEK_END) /* offset from end of file */ else if (origin == PSEEK_END) /* offset from end of file */
{ {
file_pointer = pfile->pobj->finode->fsize; file_pointer = pfile->pobj->finode->fsize;
if (file_pointer > offset) if (file_pointer >= offset)
file_pointer -= offset; file_pointer -= offset;
else else
file_pointer = 0; { /* Seek before beginning of file is an error */
p_errno = PEINVALIDPARMS;
goto errex;
}
} }
else /* Illegal origin */ else /* Illegal origin */
{ {
p_errno = PEINVALIDPARMS; p_errno = PEINVALIDPARMS;
goto errex; goto errex;
} }
if (file_pointer > pfile->pobj->finode->fsize)
if (file_pointer >= pfile->pobj->finode->fsize) { /* Seek past end of file is an error */
p_errno = PEINVALIDPARMS;
goto errex;
}
if (file_pointer == pfile->pobj->finode->fsize)
{ {
file_pointer = pfile->pobj->finode->fsize; file_pointer = pfile->pobj->finode->fsize;
@ -942,29 +951,44 @@ long _po_lseek(PC_FILE *pfile, long offset, int origin) /*__fn__*/
{ {
long ret_val; long ret_val;
int u_origin; int u_origin;
dword new_offset/*, u_offset*/; dword new_offset, u_offset;
/*u_offset = offset;*/ u_offset = (dword) offset;
u_origin = origin; u_origin = origin;
if (origin == PSEEK_CUR) /* offset from current file pointer */ if (origin == PSEEK_SET) /* offset from beginning of file */
{
if (offset < 0)
{
/* Negative seek from beginning is an error */
rtfs_set_errno(PEINVALIDPARMS);
return(-1L);
}
}
else if (origin == PSEEK_CUR) /* offset from current file pointer */
{ {
if (offset < 0) if (offset < 0)
{ {
offset = -offset; offset = -offset;
/*u_offset = (dword) offset;*/ u_offset = (dword) offset;
u_origin = PSEEK_CUR_NEG; u_origin = PSEEK_CUR_NEG;
} }
} }
else if (origin == PSEEK_END) /* offset from end of file */ else if (origin == PSEEK_END) /* offset from end of file */
{ {
if (offset < 0) if (offset <= 0)
{ {
offset = -offset; offset = -offset;
/*u_offset = (dword) offset;*/ u_offset = (dword) offset;
}
else
{
/* Positve seek from end is an error */
rtfs_set_errno(PEINVALIDPARMS);
return(-1L);
} }
} }
if (!_po_ulseek(pfile, offset, &new_offset, u_origin)) if (!_po_ulseek(pfile, u_offset, &new_offset, u_origin))
ret_val = -1L; ret_val = -1L;
else else
ret_val = (long) new_offset; ret_val = (long) new_offset;

View File

@ -137,7 +137,10 @@ BOOLEAN pc_mv(byte *old_name, byte *new_name) /*__apifn__*/
/* Find the parent and make sure it is a directory */ /* Find the parent and make sure it is a directory */
new_parent_obj = pc_fndnode(path); new_parent_obj = pc_fndnode(path);
if (!new_parent_obj || !pc_isadir(new_parent_obj) || pc_isavol(new_parent_obj)) if (!new_parent_obj || !pc_isadir(new_parent_obj) || pc_isavol(new_parent_obj))
{
p_errno = PEINVALIDPATH;
goto errex; goto errex;
}
/* The cluster value old */ /* The cluster value old */

View File

@ -15,7 +15,7 @@
/* */ /* */
void get_format_parameters(dword nblocks, int *psector_p_alloc, int *pnum_root_entries); void get_format_parameters(dword nblocks, int *psector_p_alloc, int *pnum_root_entries);
word pc_fat_size(word nreserved, word cluster_size, word n_fat_copies, word pc_fat_size(word nreserved, word cluster_size, word n_fat_copies,
word root_sectors, dword volume_size, word root_sectors, dword volume_size,
int *nibs_per_entry); int *nibs_per_entry);
@ -71,13 +71,13 @@ void pc_calculate_chs(dword total, dword *cylinders, int *heads, int *secptrack)
Description Description
Queries the drive s associated device driver for a description of the Queries the drive s associated device driver for a description of the
installed media. This information is used by the pc_format_media, installed media. This information is used by the pc_format_media,
pc_partition_media and pc_format_volume routines. The application may pc_partition_media and pc_format_volume routines. The application may
use the results of this call to calculate how it wishes the media to use the results of this call to calculate how it wishes the media to
be partitioned. be partitioned.
Note that the floppy device driver uses a back door to communicate Note that the floppy device driver uses a back door to communicate
with the format routine through the geometry structure. This allows us with the format routine through the geometry structure. This allows us
to not have floppy specific code in the format routine but still use the to not have floppy specific code in the format routine but still use the
exact format parameters that DOS uses when it formats a floppy. exact format parameters that DOS uses when it formats a floppy.
See the following definition of the pgeometry structure: See the following definition of the pgeometry structure:
@ -138,7 +138,7 @@ inval:
/* The geometry consists of cylinders, heads, and sectors /* The geometry consists of cylinders, heads, and sectors
per track. per track.
The ATA spec says that the maximum values for these are The ATA spec says that the maximum values for these are
65536 cylinders, 16 heads, and 255 sectors per track. 65536 cylinders, 16 heads, and 255 sectors per track.
However, the MBR spec says the maximum values are However, the MBR spec says the maximum values are
1023 cylinders, 255 heads, and 63 sectors per track. 1023 cylinders, 255 heads, and 63 sectors per track.
@ -163,9 +163,9 @@ Returns
Returns TRUE if it was able to perform the operation otherwise Returns TRUE if it was able to perform the operation otherwise
it returns FALSE. it returns FALSE.
Note: The the logical drive must be claimed before this routine is Note: The the logical drive must be claimed before this routine is
called and later released by the caller. called and later released by the caller.
errno is set to one of the following errno is set to one of the following
0 - No error 0 - No error
PEINVALIDDRIVEID- Drive component is invalid PEINVALIDDRIVEID- Drive component is invalid
@ -213,7 +213,7 @@ inval:
Description Description
A partition list is provided (a list of partition sizes A partition list is provided (a list of partition sizes
in units of LBA s) by the user. in units of LBA s) by the user.
Returns Returns
Returns TRUE if it was able to perform the operation otherwise Returns TRUE if it was able to perform the operation otherwise
@ -224,7 +224,7 @@ Returns
PEINVALIDDRIVEID- Drive component is invalid PEINVALIDDRIVEID- Drive component is invalid
PEINVALIDPARMS - Inconsistent or missing parameters PEINVALIDPARMS - Inconsistent or missing parameters
PEIOERRORWRITE - Error writing partition table PEIOERRORWRITE - Error writing partition table
An ERTFS system error An ERTFS system error
****************************************************************************/ ****************************************************************************/
BOOLEAN pc_partition_media(byte *path, PDEV_GEOMETRY pgeometry, dword * partition_list) /* __apifn__*/ BOOLEAN pc_partition_media(byte *path, PDEV_GEOMETRY pgeometry, dword * partition_list) /* __apifn__*/
@ -279,7 +279,7 @@ inval:
/* 10-24-2000 - New code to support lba formatting */ /* 10-24-2000 - New code to support lba formatting */
/* The first partition starts at cylinder=0, head=1, sector=1 */ /* The first partition starts at cylinder=0, head=1, sector=1 */
if (pgeometry->dev_geometry_lbas) if (pgeometry->dev_geometry_lbas)
starting_lba = (dword) pgeometry->dev_geometry_secptrack; starting_lba = (dword) pgeometry->dev_geometry_secptrack;
else else
{ {
starting_lba = 0; /* Not used */ starting_lba = 0; /* Not used */
@ -302,9 +302,9 @@ inval:
{ {
/* 10-24-2000 - New code to support lba formatting */ /* 10-24-2000 - New code to support lba formatting */
/* Apparently, we must still align to cylinders even in LBA mode */ /* Apparently, we must still align to cylinders even in LBA mode */
dwTemp = (dword) pgeometry->dev_geometry_heads; dwTemp = (dword) pgeometry->dev_geometry_heads;
dwTemp *= (dword) pgeometry->dev_geometry_secptrack; dwTemp *= (dword) pgeometry->dev_geometry_secptrack;
partition_size = ((partition_size / dwTemp) * dwTemp) - (starting_lba % dwTemp); partition_size = ((partition_size / dwTemp) * dwTemp) - (starting_lba % dwTemp);
} }
else else
{ {
@ -351,13 +351,13 @@ inval:
/* Load the starting CHS */ /* Load the starting CHS */
part.ents[partition_number].s_head = head; part.ents[partition_number].s_head = head;
utemp = (word)((cyl & 0xff) << 8); /* Low 8 bit to hi bite */ utemp = (word)((cyl & 0xff) << 8); /* Low 8 bit to hi bite */
utemp2 = (word)((cyl >> 2) & 0xc0); /* Hi 2 bits to bits 6 + 7 */ utemp2 = (word)((cyl >> 2) & 0xc0); /* Hi 2 bits to bits 6 + 7 */
utemp |= utemp2; utemp |= utemp2;
utemp |= sec; utemp |= sec;
fr_WORD((byte *)&(part.ents[partition_number].s_cyl), utemp); fr_WORD((byte *)&(part.ents[partition_number].s_cyl), utemp);
/* Load the starting LBA */ /* Load the starting LBA */
fr_DWORD((byte *)&(part.ents[partition_number].r_sec), starting_lba); fr_DWORD((byte *)&(part.ents[partition_number].r_sec), starting_lba);
} }
else else
{ {
@ -414,7 +414,7 @@ inval:
/* Load the ending CHS */ /* Load the ending CHS */
part.ents[partition_number].e_head = head; part.ents[partition_number].e_head = head;
utemp = (word)((cyl & 0xff) << 8); /* Low 8 bit to hi bite */ utemp = (word)((cyl & 0xff) << 8); /* Low 8 bit to hi bite */
utemp2 = (word)((cyl >> 2) & 0xc0); /* Hi 2 bits to bits 6 + 7 */ utemp2 = (word)((cyl >> 2) & 0xc0); /* Hi 2 bits to bits 6 + 7 */
utemp |= utemp2; utemp |= utemp2;
utemp |= sec; utemp |= sec;
fr_WORD((byte *)&(part.ents[partition_number].e_cyl), utemp); fr_WORD((byte *)&(part.ents[partition_number].e_cyl), utemp);
@ -426,15 +426,15 @@ inval:
part.ents[partition_number].e_head = (byte) (pgeometry->dev_geometry_heads-1); part.ents[partition_number].e_head = (byte) (pgeometry->dev_geometry_heads-1);
/* Ending cylinder is in the top ten bits, secptrack in lower 6 ?? */ /* Ending cylinder is in the top ten bits, secptrack in lower 6 ?? */
/* Relative sector starting */ /* Relative sector starting */
fr_DWORD((byte *)&(part.ents[partition_number].r_sec), (dword) pgeometry->dev_geometry_secptrack*starting_cylinder); fr_DWORD((byte *)&(part.ents[partition_number].r_sec), (dword) pgeometry->dev_geometry_secptrack*starting_cylinder);
/* Set up for the next partition and use new value to calculate ending cyl */ /* Set up for the next partition and use new value to calculate ending cyl */
starting_cylinder = (word)((word)starting_cylinder + (word) *(partition_list+partition_number)); starting_cylinder = (word)((word)starting_cylinder + (word) *(partition_list+partition_number));
utemp = (word)(((starting_cylinder-1) & 0xff) << 8); /* Low 8 bit to hi bite */ utemp = (word)(((starting_cylinder-1) & 0xff) << 8); /* Low 8 bit to hi bite */
utemp2 = (word)(((starting_cylinder-1) >> 2) & 0xc0); /* Hi 2 bits to bits 6 + 7 */ utemp2 = (word)(((starting_cylinder-1) >> 2) & 0xc0); /* Hi 2 bits to bits 6 + 7 */
utemp |= utemp2; utemp |= utemp2;
utemp |= (word) pgeometry->dev_geometry_secptrack; utemp |= (word) pgeometry->dev_geometry_secptrack;
fr_WORD((byte *)&(part.ents[partition_number].e_cyl), utemp); fr_WORD((byte *)&(part.ents[partition_number].e_cyl), utemp);
/* And partition size */ /* And partition size */
fr_DWORD((byte *)&(part.ents[partition_number].p_size), partition_size); fr_DWORD((byte *)&(part.ents[partition_number].p_size), partition_size);
@ -480,17 +480,17 @@ Description
drive structure is queried to determine if the device is parttioned drive structure is queried to determine if the device is parttioned
or not. If the device is partitioned then the partition table is read or not. If the device is partitioned then the partition table is read
and the volume within the partition is formatted. If it is a non and the volume within the partition is formatted. If it is a non
partitioned device the device is formatted according to the supplied partitioned device the device is formatted according to the supplied
pgeometry parameters. The pgeometry parameter contains the the media pgeometry parameters. The pgeometry parameter contains the the media
size in HCN format. It also contains a size in HCN format. It also contains a
Note: The the logical drive must be claimed before this routine is Note: The the logical drive must be claimed before this routine is
called and later released by the caller. called and later released by the caller.
Returns Returns
Returns TRUE if it was able to perform the operation otherwise Returns TRUE if it was able to perform the operation otherwise
it returns FALSE. it returns FALSE.
errno is set to one of the following errno is set to one of the following
0 - No error 0 - No error
PEINVALIDDRIVEID- Drive component is invalid PEINVALIDDRIVEID- Drive component is invalid
@ -498,8 +498,8 @@ Returns
PEINVALIDMBR - Partitioned device has no master boot record PEINVALIDMBR - Partitioned device has no master boot record
PEINVALIDMBROFFSET - Requested partition has no entry in master boot record PEINVALIDMBROFFSET - Requested partition has no entry in master boot record
PEINVALIDPARMS - Inconsistent or missing parameters PEINVALIDPARMS - Inconsistent or missing parameters
PEIOERRORWRITE - Error writing during format PEIOERRORWRITE - Error writing during format
An ERTFS system error An ERTFS system error
****************************************************************************/ ****************************************************************************/
BOOLEAN pc_format_volume(byte *path, PDEV_GEOMETRY pgeometry) /* __apifn__*/ BOOLEAN pc_format_volume(byte *path, PDEV_GEOMETRY pgeometry) /* __apifn__*/
@ -541,9 +541,9 @@ int nibs_per_entry,partition_status;
if (pgeometry->fmt_parms_valid) if (pgeometry->fmt_parms_valid)
{ {
if( ((pgeometry->fmt.numcyl * pgeometry->fmt.numhead * pgeometry->fmt.secptrk) / pgeometry->fmt.secpalloc) > 0xFFFF) { if( ((pgeometry->fmt.numcyl * pgeometry->fmt.numhead * pgeometry->fmt.secptrk) / pgeometry->fmt.secpalloc) > 0xFFFF) {
return(pc_mkfs32(driveno, &pgeometry->fmt, TRUE)); /* TRUE == RAW IO */ //ctr modified return(pc_mkfs32(driveno, &pgeometry->fmt, TRUE)); /* TRUE == RAW IO */
}else{ }else{
return(pc_mkfs16(driveno, &pgeometry->fmt, TRUE)); /* TRUE == RAW IO */ return(pc_mkfs16(driveno, &pgeometry->fmt, TRUE)); /* TRUE == RAW IO */
} }
} }
@ -557,7 +557,7 @@ int nibs_per_entry,partition_status;
if (partition_status == READ_PARTION_OK) if (partition_status == READ_PARTION_OK)
{ {
partition_size = pdr->partition_size; partition_size = pdr->partition_size;
ltemp = partition_size / ltemp = partition_size /
(dword)(pgeometry->dev_geometry_heads * pgeometry->dev_geometry_secptrack); (dword)(pgeometry->dev_geometry_heads * pgeometry->dev_geometry_secptrack);
n_cyls = (word) ltemp; n_cyls = (word) ltemp;
raw_mode_io = FALSE; raw_mode_io = FALSE;
@ -611,15 +611,10 @@ int nibs_per_entry,partition_status;
fmt.secreserved = (word) 32; fmt.secreserved = (word) 32;
if (pdr->drive_flags & DRIVE_FLAGS_PARTITIONED) if (pdr->drive_flags & DRIVE_FLAGS_PARTITIONED)
{ {
if (pgeometry->dev_geometry_lbas) fmt.numhide = pdr->partition_base;
/* 10-24-2000 - New code to support lba formatting */
fmt.numhide = (unsigned long) 0; /*PS Does not work as fmt.secptrk here */
else
/* 10-24-2000 - This was the original code */
fmt.numhide = (unsigned long) fmt.secptrk;
} }
else else
fmt.numhide = (unsigned long) pgeometry->fmt.numhide; //ctr modified fmt.numhide = (unsigned long) 0;
fmt.secpfat = (word) 0; fmt.secpfat = (word) 0;
fmt.numroot = (word) 0; fmt.numroot = (word) 0;
fmt.mediadesc = (byte) 0xF8; fmt.mediadesc = (byte) 0xF8;
@ -627,8 +622,11 @@ int nibs_per_entry,partition_status;
} }
else else
{ {
if (pdr->drive_flags & DRIVE_FLAGS_PARTITIONED)
fmt.numhide = pdr->partition_base;
else
fmt.numhide = 0;
fmt.secreserved = (word) 1; fmt.secreserved = (word) 1;
fmt.numhide = pgeometry->fmt.numhide; //ctr modified
fmt.secpfat = (word) secpfat; fmt.secpfat = (word) secpfat;
fmt.numroot = (word) root_entries; fmt.numroot = (word) root_entries;
fmt.mediadesc = (byte) 0xF8; fmt.mediadesc = (byte) 0xF8;
@ -644,15 +642,15 @@ int nibs_per_entry,partition_status;
Given a drive number and a format parameter block. Put an MS-DOS Given a drive number and a format parameter block. Put an MS-DOS
file system on the drive: file system on the drive:
The disk MUST already have a low level format. All blocks on the drive The disk MUST already have a low level format. All blocks on the drive
should be intitialize with E5s or zeros. should be intitialize with E5s or zeros.
see pcmkfs in the samples directory. see pcmkfs in the samples directory.
Some common parameters. Note: For other drive types use debug to get the Some common parameters. Note: For other drive types use debug to get the
parameters from block zero after FORMAT has been run. parameters from block zero after FORMAT has been run.
360 720 20M 80M (DRIVE SIZE) 360 720 20M 80M (DRIVE SIZE)
oemname ===== UP TO YOU. ONLY 8 Chars matter. Right filled with spaces oemname ===== UP TO YOU. ONLY 8 Chars matter. Right filled with spaces
secpalloc 2 2 4 8 secpalloc 2 2 4 8
secreserved 1 1 1 1 secreserved 1 1 1 1
numfats 2 2 2 2 numfats 2 2 2 2
@ -674,14 +672,14 @@ See Also:
word pc_fat_size(word nreserved, word cluster_size, word n_fat_copies, word pc_fat_size(word nreserved, word cluster_size, word n_fat_copies,
word root_sectors, dword volume_size, word root_sectors, dword volume_size,
int *nibs_per_entry) /*__fn__*/ int *nibs_per_entry) /*__fn__*/
{ {
dword fat_size; dword fat_size;
dword total_clusters; dword total_clusters;
word entries_per_block; word entries_per_block;
#if (FAT32) #if (FAT32)
if ((root_sectors == 0) || ((volume_size>>11) >= 512))/* FAT32 Format */ if ((root_sectors == 0) || ((volume_size>>11) >= 512))/* FAT32 Format */
{ {
@ -697,12 +695,12 @@ word pc_fat_size(word nreserved, word cluster_size, word n_fat_copies,
total_clusters /= cluster_size; total_clusters /= cluster_size;
/* Calculate the number of fat entries per block in the FAT. If /* Calculate the number of fat entries per block in the FAT. If
< 4087 clusters total the fat entries are 12 bits hence 341 < 4087 clusters total the fat entries are 12 bits hence 341
will fit. else 256 will fit will fit. else 256 will fit
we add in n_fat_copies * 12 here since it take 12 blocks to represent we add in n_fat_copies * 12 here since it take 12 blocks to represent
4087 clusters in 3 nibble form. So we add in the worst case FAT size 4087 clusters in 3 nibble form. So we add in the worst case FAT size
here to enhance the accuracy of our guess of the total clusters. here to enhance the accuracy of our guess of the total clusters.
*/ */
if (total_clusters <= (dword) (4087 + (n_fat_copies * 12)) ) if (total_clusters <= (dword) (4087 + (n_fat_copies * 12)) )
{ {
@ -717,7 +715,7 @@ word pc_fat_size(word nreserved, word cluster_size, word n_fat_copies,
fat_size = (total_clusters + entries_per_block - 1)/entries_per_block; fat_size = (total_clusters + entries_per_block - 1)/entries_per_block;
return((word) fat_size); return((word) fat_size);
} }
/* Choose format parameters based on the number of blocks in the volume */ /* Choose format parameters based on the number of blocks in the volume */
@ -780,4 +778,3 @@ void get_format_parameters(dword nblocks, int *psectors_per_alloc, int *pnum_roo
*pnum_root_entries = num_root_entries; *pnum_root_entries = num_root_entries;
} }

View File

@ -9,16 +9,17 @@
/* APIGFRST.C - Contains user api level source code. /* APIGFRST.C - Contains user api level source code.
The following routines are included: The following routines are included:
pc_gfirst - Get stats on the first file to match a pattern. pc_gfirst - Get stats on the first file to match a pattern.
pc_gnext - Get stats on the next file to match a pattern. pc_gnext - Get stats on the next file to match a pattern.
pc_gdone - Free resources used by pc_gfirst/pc_gnext. pc_gdone - Free resources used by pc_gfirst/pc_gnext.
pc_upstat - Copy directory entry info to a user s stat buffer pc_upstat - Copy directory entry info to a user s stat buffer
*/ */
#include <rtfs.h> #include <rtfs.h>
/*************************************************************************** /***************************************************************************
PC_GFIRST - Get first entry in a directory to match a pattern. PC_GFIRST - Get first entry in a directory to match a pattern.
@ -43,10 +44,11 @@
PEINVALIDDRIVEID- Drive component is invalid PEINVALIDDRIVEID- Drive component is invalid
PEINVALIDPATH - Path specified badly formed. PEINVALIDPATH - Path specified badly formed.
PENOENT - Not found, no match PENOENT - Not found, no match
An ERTFS system error An ERTFS system error
****************************************************************************/ ****************************************************************************/
void pc_upstat(DSTAT *statobj); void pc_upstat(DSTAT *statobj);
BOOLEAN pc_gfirst(DSTAT *statobj, byte *name) /*__apifn__*/ BOOLEAN pc_gfirst(DSTAT *statobj, byte *name) /*__apifn__*/
@ -59,7 +61,6 @@ BOOLEAN pc_gfirst(DSTAT *statobj, byte *name) /*__apifn__*/
CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */ CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */
rtfs_set_errno(0); /* po_gfirst: clear error status */ rtfs_set_errno(0); /* po_gfirst: clear error status */
rtfs_memset((byte *) statobj,0,sizeof(*statobj)); rtfs_memset((byte *) statobj,0,sizeof(*statobj));
/* statobj->pobj = 0; */ /* statobj->pobj = 0; */
/* statobj->pmom = 0; */ /* statobj->pmom = 0; */
@ -95,22 +96,24 @@ BOOLEAN pc_gfirst(DSTAT *statobj, byte *name) /*__apifn__*/
if (statobj->pmom) if (statobj->pmom)
/* Found it. Check access permissions */ /* Found it. Check access permissions */
{ {
if(pc_isadir((DROBJ *)(statobj->pmom))) if(pc_isadir((DROBJ *)(statobj->pmom)))
{ {
/* Now find pattern in the directory */ /* Now find pattern in the directory */
statobj->pobj = (void *) pc_get_inode(0, (DROBJ *)(statobj->pmom), filename, (byte*) fileext, GET_INODE_WILD); statobj->pobj = (void *) pc_get_inode(0, (DROBJ *)(statobj->pmom), filename, (byte*) fileext, GET_INODE_WILD);
if (statobj->pobj) if (statobj->pobj)
{ {
/* And update the stat structure */ /* And update the stat structure */
pc_upstat(statobj); pc_upstat(statobj);
/* remember the drive number. used by gnext et al. */ /* remember the drive number. used by gnext et al. */
statobj->driveno = driveno; statobj->driveno = driveno;
/* 9-20-94 release the FINODE and allocate a dummy. This will keep everyone /* 9-20-94 release the FINODE and allocate a dummy. This will keep everyone
who expects the drobj to own a finode happy but will not leave the who expects the drobj to own a finode happy but will not leave the
finode open which locks out unlink et al */ finode open which locks out unlink et al */
pc_freei(((DROBJ *)(statobj->pobj))->finode); /* Release the current */ pc_freei(((DROBJ *)(statobj->pobj))->finode); /* Release the current */
((DROBJ *)(statobj->pobj))->finode = pc_alloci(); /* 3-07-07 - Change: Remove additional call to pc_alloci(). Was not needed and caused a leak
on a hot swap event when a gfirst is outstanding */
((DROBJ *)(statobj->pobj))->finode = 0;
/* END 9-20-94 */ /* END 9-20-94 */
/* Remember the unique number associated with the drive /* Remember the unique number associated with the drive
mount. If the drive is closed before we call gnext or mount. If the drive is closed before we call gnext or
@ -121,8 +124,8 @@ BOOLEAN pc_gfirst(DSTAT *statobj, byte *name) /*__apifn__*/
} }
else else
{ {
/* pc_gfirst: if statobj->pobj is 0 pc_get_inode() has set errno to PENOENT or /* pc_gfirst: if statobj->pobj is 0 pc_get_inode() has set errno to PENOENT or
to an internal or IO error status to an internal or IO error status
if PENOENT set we will clear errno */ if PENOENT set we will clear errno */
if (get_errno() == PENOENT) if (get_errno() == PENOENT)
rtfs_set_errno(0); /* pc_gfirst: file not found in directory rtfs_set_errno(0); /* pc_gfirst: file not found in directory
@ -157,7 +160,7 @@ BOOLEAN pc_gfirst(DSTAT *statobj, byte *name) /*__apifn__*/
0 - No error 0 - No error
PEINVALIDPARMS - statobj argument is not valid PEINVALIDPARMS - statobj argument is not valid
PENOENT - Not found, no match (normal termination of scan) PENOENT - Not found, no match (normal termination of scan)
An ERTFS system error An ERTFS system error
****************************************************************************/ ****************************************************************************/
BOOLEAN pc_gnext(DSTAT *statobj) /*__apifn__*/ BOOLEAN pc_gnext(DSTAT *statobj) /*__apifn__*/
@ -165,7 +168,7 @@ BOOLEAN pc_gnext(DSTAT *statobj) /*__apifn__*/
DROBJ *nextobj; DROBJ *nextobj;
DDRIVE *pdrive; DDRIVE *pdrive;
CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */ CHECK_MEM(BOOLEAN, 0) /* Make sure memory is initted */
/* see if the drive is still mounted. Do not use pmom et al. since they /* see if the drive is still mounted. Do not use pmom et al. since they
may be purged */ may be purged */
if (!statobj || !statobj->pmom) if (!statobj || !statobj->pmom)
{ {
@ -176,7 +179,7 @@ BOOLEAN pc_gnext(DSTAT *statobj) /*__apifn__*/
return(FALSE); return(FALSE);
pdrive = pc_drno2dr(statobj->driveno); pdrive = pc_drno2dr(statobj->driveno);
if (statobj->drive_opencounter != pdrive->drive_opencounter) if (statobj->drive_opencounter != pdrive->drive_opencounter)
{ { /* Card was removed and re-inserted since pc_gfirst() */
rtfs_set_errno(PEINVALIDPARMS); /* pc_gnext: statobj is not valid */ rtfs_set_errno(PEINVALIDPARMS); /* pc_gnext: statobj is not valid */
release_drive_mount(statobj->driveno);/* Release lock, unmount if aborted */ release_drive_mount(statobj->driveno);/* Release lock, unmount if aborted */
return(FALSE); return(FALSE);
@ -192,11 +195,13 @@ BOOLEAN pc_gnext(DSTAT *statobj) /*__apifn__*/
statobj->pobj = (void *)nextobj; statobj->pobj = (void *)nextobj;
/* And update the stat structure */ /* And update the stat structure */
pc_upstat(statobj); pc_upstat(statobj);
/* 9-20-94 release the FINODE and allocate a dummy. This will keep everyone /* 9-20-94 release the FINODE and allocate a dummy. This will keep everyone
who expects the drobj to own a finode happy but will not leave the who expects the drobj to own a finode happy but will not leave the
finode open which locks out unlink et al */ finode open which locks out unlink et al */
pc_freei(((DROBJ *)(statobj->pobj))->finode); /* Release the current */ pc_freei(((DROBJ *)(statobj->pobj))->finode); /* Release the current */
((DROBJ *)(statobj->pobj))->finode = pc_alloci(); /* 3-07-07 - Change: Remove additional call to pc_alloci(). Was not needed and caused a leak
on a hot swap event when a gfirst is outstanding */
((DROBJ *)(statobj->pobj))->finode = 0;
/* END 9-20-94 */ /* END 9-20-94 */
release_drive_mount(statobj->driveno);/* Release lock, unmount if aborted */ release_drive_mount(statobj->driveno);/* Release lock, unmount if aborted */
return(TRUE); return(TRUE);
@ -220,7 +225,7 @@ BOOLEAN pc_gnext(DSTAT *statobj) /*__apifn__*/
Given a pointer to a DSTAT structure that has been set up by a call to Given a pointer to a DSTAT structure that has been set up by a call to
pc_gfirst() free internal elements used by the statobj. pc_gfirst() free internal elements used by the statobj.
NOTE: You MUST call this function when done searching through a NOTE: You MUST call this function when done searching through a
directory. directory.
Returns Returns
@ -231,13 +236,14 @@ BOOLEAN pc_gnext(DSTAT *statobj) /*__apifn__*/
PEINVALIDPARMS - statobj argument is not valid PEINVALIDPARMS - statobj argument is not valid
****************************************************************************/ ****************************************************************************/
void pc_gdone(DSTAT *statobj) /*__apifn__*/ void pc_gdone(DSTAT *statobj) /*__apifn__*/
{ {
DDRIVE *pdrive; DDRIVE *pdrive;
VOID_CHECK_MEM() /* Make sure memory is initted */ VOID_CHECK_MEM() /* Make sure memory is initted */
/* see if the drive is still mounted. Do not use pmom et al. since they /* see if the drive is still mounted. Do not use pmom et al. since they
may be purged */ may be purged */
/* see if the drive is still mounted. Do not use pmom et al. since they /* see if the drive is still mounted. Do not use pmom et al. since they
may be purged */ may be purged */
if (!statobj || !statobj->pmom) if (!statobj || !statobj->pmom)
{ {
@ -247,12 +253,14 @@ void pc_gdone(DSTAT *statobj) /*__apifn__*/
return; return;
pdrive = pc_drno2dr(statobj->driveno); pdrive = pc_drno2dr(statobj->driveno);
if (statobj->drive_opencounter != pdrive->drive_opencounter) if (statobj->drive_opencounter != pdrive->drive_opencounter)
{ { /* Card was removed and re-inserted since pc_gfirst() */
release_drive_mount(statobj->driveno);/* Release lock, unmount if aborted */ release_drive_mount(statobj->driveno);/* Release lock, unmount if aborted */
return; return;
} }
if (statobj->pobj) if (statobj->pobj)
{
pc_freeobj((DROBJ *)statobj->pobj); pc_freeobj((DROBJ *)statobj->pobj);
}
if (statobj->pmom) if (statobj->pmom)
pc_freeobj((DROBJ *)statobj->pmom); pc_freeobj((DROBJ *)statobj->pmom);
release_drive_mount(statobj->driveno);/* Release lock, unmount if aborted */ release_drive_mount(statobj->driveno);/* Release lock, unmount if aborted */
@ -262,7 +270,7 @@ void pc_gdone(DSTAT *statobj) /*__apifn__*/
PC_UPSTAT - Copy private information to public fields for a DSTAT struc. PC_UPSTAT - Copy private information to public fields for a DSTAT struc.
Description Description
Given a pointer to a DSTAT structure that contains a pointer to an Given a pointer to a DSTAT structure that contains a pointer to an
initialized DROBJ structure, load the public elements of DSTAT with initialized DROBJ structure, load the public elements of DSTAT with
name filesize, date of modification et al. (Called by pc_gfirst & name filesize, date of modification et al. (Called by pc_gfirst &
pc_gnext) pc_gnext)
@ -281,13 +289,13 @@ void pc_upstat(DSTAT *statobj) /*__fn__*/
pobj = (DROBJ *)(statobj->pobj); pobj = (DROBJ *)(statobj->pobj);
pi = pobj->finode; pi = pobj->finode;
copybuff( statobj->fname, pi->fname, 8); copybuff( statobj->fname, pi->fname, 8);
statobj->fname[8] = CS_OP_ASCII('\0'); statobj->fname[8] = CS_OP_ASCII('\0');
copybuff( statobj->fext, pi->fext, 3); copybuff( statobj->fext, pi->fext, 3);
statobj->fext[3] = CS_OP_ASCII('\0'); statobj->fext[3] = CS_OP_ASCII('\0');
/* put null termed file.ext into statobj */ /* put null termed file.ext into statobj */
pc_ascii_mfile((byte *)statobj->filename, (byte *)statobj->fname, pc_ascii_mfile((byte *)statobj->filename, (byte *)statobj->fname,
(byte *)statobj->fext); (byte *)statobj->fext);
statobj->fattribute = pi->fattribute; statobj->fattribute = pi->fattribute;
@ -299,9 +307,7 @@ void pc_upstat(DSTAT *statobj) /*__fn__*/
if (!pc_get_lfn_filename(pobj, (byte *)statobj->lfname)) if (!pc_get_lfn_filename(pobj, (byte *)statobj->lfname))
{ {
statobj->lfname[0] = statobj->lfname[1] = 0; statobj->lfname[0] = statobj->lfname[1] = 0;
pc_cs_mfile((byte *)statobj->lfname, (byte *)statobj->fname, pc_cs_mfile((byte *)statobj->lfname, (byte *)statobj->fname,
(byte *)statobj->fext); (byte *)statobj->fext);
} }
} }

View File

@ -466,6 +466,10 @@ DEV_GEOMETRY geometry;
if (!pc_format_media(drivename, &geometry)) if (!pc_format_media(drivename, &geometry))
return(-1); return(-1);
/* Get media parms again in case the format operation changed the parameters */
if (!pc_get_media_parms(drivename, &geometry))
return(-1);
if (!pc_format_volume(drivename, &geometry)) if (!pc_format_volume(drivename, &geometry))
return(-1); return(-1);
return (0); return (0);

View File

@ -176,7 +176,14 @@ int po_write(PCFD fd, byte *in_buff, int count) /*__apifn__*/
n_clusters = FATOP(pdrive)->fatop_alloc_chain(pdrive, &(pfile->fptr_cluster), n_clusters, TRUE); n_clusters = FATOP(pdrive)->fatop_alloc_chain(pdrive, &(pfile->fptr_cluster), n_clusters, TRUE);
if (!n_clusters) if (!n_clusters)
{ /* Allocchain will set errno to PENOSPC or an IO or internal error */ { /* Allocchain will set errno to PENOSPC or an IO or internal error */
break; /* Handle PENOSPC as a short write - otherwise it is an error that returns -1*/
if (get_errno() == PENOSPC)
break;
else
{
ret_val = (int) -1;
goto return_locked;
}
} }
/* Calculate the last cluster in this chain. */ /* Calculate the last cluster in this chain. */

View File

@ -299,7 +299,6 @@ int index;
} }
/* ******************************************************************** */ /* ******************************************************************** */
/* THIS IS THE MAIN PROGRAM FOR THE TEST SHELL */ /* THIS IS THE MAIN PROGRAM FOR THE TEST SHELL */
/* ******************************************************************** */ /* ******************************************************************** */
@ -457,13 +456,39 @@ int nprinted = 0;
} }
/* EJECT D: */ /* EJECT D: */
BOOLEAN ide_eject_media(int driveno);
void eject_driveno(int driveno)
{
DDRIVE *pdr;
pdr = pc_drno_to_drive_struct(driveno);
if (pdr)
{
pdr->dev_table_perform_device_ioctl(driveno, DEVCTL_REPORT_REMOVE, (void *) 0);
}
}
void eject_drivename(byte *drivename)
{
int driveno;
driveno = pc_parse_raw_drive(drivename);
if (driveno != -1)
eject_driveno(driveno);
}
int doeject(int agc, byte **agv) /*__fn__*/ int doeject(int agc, byte **agv) /*__fn__*/
{ {
RTFS_ARGSUSED_INT(agc); if (agc == 1)
RTFS_ARGSUSED_PVOID((void *)agv); {
RTFS_PRINT_STRING_1(USTRING_TSTSH_02,PRFLG_NL); /* "Not implemented. See ide ioctl... " */ if (!pc_set_default_drive(*agv))
{
RTFS_PRINT_STRING_1(USTRING_TSTSH_03,PRFLG_NL); /* "Set Default Drive Failed" */
return(-1);
}
else
{
eject_drivename(*agv);
}
}
return(0); return(0);
} }
@ -916,7 +941,6 @@ int pc_seedir(byte *path) /*__fn__*/
fcount++; fcount++;
rtfs_print_format_dir(display_buffer, &statobj); rtfs_print_format_dir(display_buffer, &statobj);
/* Get the next */ /* Get the next */
if (!pc_gnext(&statobj)) if (!pc_gnext(&statobj))
break; break;
@ -955,7 +979,6 @@ int docat(int agc, byte **agv) /*__fn__*/
PCFD fd; PCFD fd;
int nread; int nread;
if (agc == 1) if (agc == 1)
{ {
if ((fd = po_open(*agv, (word)(PO_BINARY|PO_RDONLY|PO_BUFFERED),(word) (PS_IWRITE | PS_IREAD) ) ) < 0) if ((fd = po_open(*agv, (word)(PO_BINARY|PO_RDONLY|PO_BUFFERED),(word) (PS_IWRITE | PS_IREAD) ) ) < 0)

View File

@ -506,7 +506,7 @@ BOOLEAN validate_filename(byte * filename, byte * ext)
BOOLEAN pc_cs_malias(byte *alias, byte *input_file, int try) /*__fn__*/ BOOLEAN pc_cs_malias(byte *alias, byte *input_file, int try) /*__fn__*/
{ {
int n,s; int n,s;
byte filename[9],fileext[4]; byte filename[10],fileext[4];
byte *p_in, *p_in_ext, *p_temp, *p_temp_2; byte *p_in, *p_in_ext, *p_temp, *p_temp_2;
int char_len, jis_ext_len; int char_len, jis_ext_len;
@ -581,9 +581,11 @@ BOOLEAN pc_cs_malias(byte *alias, byte *input_file, int try) /*__fn__*/
if (p_in_ext && p_temp>=p_in_ext) /* hit extension ? */ if (p_in_ext && p_temp>=p_in_ext) /* hit extension ? */
break; break;
char_len = jis_char_length(p_temp); char_len = jis_char_length(p_temp);
/* break and use ' ' if 2 bite jis overflows 6 */ /* break and use ' ' if 2 bite jis overflows 8 character limit */
if(s==5&&char_len==2) /* Bug fix 2-1-07 , was if(s==5&&char_len==2) */
if(s==7&&char_len==2)
{ {
filename[7] = ' '; /* shift-jis first bytes clear */
break; break;
} }
else if(*p_temp!=' ' && *p_temp !='.') else if(*p_temp!=' ' && *p_temp !='.')
@ -602,7 +604,9 @@ BOOLEAN pc_cs_malias(byte *alias, byte *input_file, int try) /*__fn__*/
} }
} }
} }
filename[8]=0; /* null terminate filename[] */ /* Null terminate the file at length 8, the alias digits will be right justified in
file name and the result will be copied, stripping out spaces */
filename[8]=0;
pc_ascii_str2upper(filename,filename); pc_ascii_str2upper(filename,filename);
pc_ascii_str2upper(fileext,fileext); pc_ascii_str2upper(fileext,fileext);
@ -620,41 +624,41 @@ BOOLEAN pc_cs_malias(byte *alias, byte *input_file, int try) /*__fn__*/
filename[n]='~'; filename[n]='~';
} }
p_temp_2 = alias; p_temp_2 = alias;
p_temp = filename; p_temp = filename;
/* copy filename[] to alias[], filtering out spaces */ /* copy filename[] to alias[], filtering out spaces */
s = 0; s = 0;
while(*p_temp) while(*p_temp)
{
char_len = jis_char_length(p_temp);
if (s == 7 && char_len == 2)
{ {
char_len = jis_char_length(p_temp); break;
}
if (s == 7 && char_len == 2) if(*p_temp!=' ')
break; {
if(*p_temp!=' ') *p_temp_2++=*p_temp++;
{ if (char_len == 2)
*p_temp_2++=*p_temp++; *p_temp_2++=*p_temp++;
if (char_len == 2) s += char_len;
*p_temp_2++=*p_temp++; if (s == 8)
s += char_len; break;
if (s == 8)
break;
}
else
p_temp++;
} }
if(jis_ext_len != 0) else
p_temp++;
}
if(jis_ext_len != 0)
{
*p_temp_2++='.'; /* insert separating period */
/* copy fileext[] to alias[] */
for(s=0; s < jis_ext_len; s++)
{ {
*p_temp_2++='.'; /* insert separating period */ *p_temp_2++ = fileext[s];
/* copy fileext[] to alias[] */
for(s=0; s < jis_ext_len; s++)
{
*p_temp_2++ = fileext[s];
}
} }
}
*p_temp_2=0; /* null terminate alias[] */ *p_temp_2=0; /* null terminate alias[] */
return(TRUE); return(TRUE);
} }
@ -907,4 +911,3 @@ int l;
} }
#endif #endif

View File

@ -18,10 +18,10 @@
#define INCLUDE_TSTSH_STRINGS 1 #define INCLUDE_TSTSH_STRINGS 1
/* Set this value to 1 if strings are entered as ascii and we require /* Set this value to 1 if strings are entered as ascii and we require
the unicode layer to expand them to 16 bit character strings the unicode layer to expand them to 16 bit character strings
set it to zero if you replace the strrings in the table with set it to zero if you replace the strrings in the table with
true UNICODE true UNICODE
*/ */
typedef struct rtfs_string_table { typedef struct rtfs_string_table {
int string_id; int string_id;
@ -463,7 +463,7 @@ KS_CONSTANT RTFS_STRING_TABLE string_table[] = {
{USTRING_RTFSDEM_14,(byte *)"regress_error was called with error" }, {USTRING_RTFSDEM_14,(byte *)"regress_error was called with error" },
{USTRING_RTFSDEM_15,(byte *)"Performing long file name test" }, {USTRING_RTFSDEM_15,(byte *)"Performing long file name test" },
{USTRING_RTFSDEM_16,(byte *)"Performing buffered file io test" }, {USTRING_RTFSDEM_16,(byte *)"Performing buffered file io test" },
{USTRING_RTFSDEM_17,(byte *)"Performing Large (4Gig)File io test" }, {USTRING_RTFSDEM_17,(byte *)"Performing Large (4Gig)File io test" },
#endif #endif
#endif /* (INCLUDE_RTFSDEM_STRINGS) */ #endif /* (INCLUDE_RTFSDEM_STRINGS) */
#if (INCLUDE_TSTSH_STRINGS) #if (INCLUDE_TSTSH_STRINGS)
@ -636,7 +636,7 @@ KS_CONSTANT RTFS_STRING_TABLE string_table[] = {
{USTRING_TSTSHHELP_19,(byte *)L"DIR PATH" }, {USTRING_TSTSHHELP_19,(byte *)L"DIR PATH" },
{USTRING_TSTSHHELP_20,(byte *)L"DSKSEL D:" }, {USTRING_TSTSHHELP_20,(byte *)L"DSKSEL D:" },
{USTRING_TSTSHHELP_21,(byte *)L"ECHO: [args]" }, {USTRING_TSTSHHELP_21,(byte *)L"ECHO: [args]" },
{USTRING_TSTSHHELP_22,(byte *)L"EJECT (ejects LS-120)" }, {USTRING_TSTSHHELP_22,(byte *)L"EJECT (Trigger Remove Event)" },
{USTRING_TSTSHHELP_23,(byte *)L"FILLFILE PATH PATTERN NTIMES" }, {USTRING_TSTSHHELP_23,(byte *)L"FILLFILE PATH PATTERN NTIMES" },
{USTRING_TSTSHHELP_24,(byte *)L"FORMAT (routine will prompt for arguments)" }, {USTRING_TSTSHHELP_24,(byte *)L"FORMAT (routine will prompt for arguments)" },
{USTRING_TSTSHHELP_25,(byte *)L"GETATTR FILE" }, {USTRING_TSTSHHELP_25,(byte *)L"GETATTR FILE" },
@ -880,7 +880,7 @@ KS_CONSTANT RTFS_STRING_TABLE string_table[] = {
{USTRING_TSTSHHELP_19,(byte *)"DIR PATH" }, {USTRING_TSTSHHELP_19,(byte *)"DIR PATH" },
{USTRING_TSTSHHELP_20,(byte *)"DSKSEL D:" }, {USTRING_TSTSHHELP_20,(byte *)"DSKSEL D:" },
{USTRING_TSTSHHELP_21,(byte *)"ECHO: [args]" }, {USTRING_TSTSHHELP_21,(byte *)"ECHO: [args]" },
{USTRING_TSTSHHELP_22,(byte *)"EJECT (ejects LS-120)" }, {USTRING_TSTSHHELP_22,(byte *)"EJECT (Trigger Remove Event)" },
{USTRING_TSTSHHELP_23,(byte *)"FILLFILE PATH PATTERN NTIMES" }, {USTRING_TSTSHHELP_23,(byte *)"FILLFILE PATH PATTERN NTIMES" },
{USTRING_TSTSHHELP_24,(byte *)"FORMAT (routine will prompt for arguments)" }, {USTRING_TSTSHHELP_24,(byte *)"FORMAT (routine will prompt for arguments)" },
{USTRING_TSTSHHELP_25,(byte *)"GETATTR FILE" }, {USTRING_TSTSHHELP_25,(byte *)"GETATTR FILE" },
@ -964,13 +964,13 @@ KS_CONSTANT RTFS_STRING_TABLE string_table[] = {
{0,(byte *)"Unkown User String" } {0,(byte *)"Unkown User String" }
#endif #endif
}; };
static byte *rtfs_strtab_string(KS_CONSTANT RTFS_STRING_TABLE *ptable, int string_id) static byte *rtfs_strtab_string(KS_CONSTANT RTFS_STRING_TABLE *ptable, int string_id)
{ {
while (ptable->string_id != 0) while (ptable->string_id != 0)
{ {
if (ptable->string_id == string_id) if (ptable->string_id == string_id)
break; break;
ptable++; ptable++;
@ -988,4 +988,3 @@ byte *rtfs_strtab_user_string(int string_id)
{ {
return(rtfs_strtab_string(string_table, string_id)); return(rtfs_strtab_string(string_table, string_id));
} }

View File

@ -10,19 +10,14 @@
#include <rtfs.h> #include <rtfs.h>
#include <rtfsconf.h> #include <rtfsconf.h>
#if (RTFS_DEBUG_PRINT_ON == 1)
#if (CTR_DEF_ENVIRONMENT_DSEMU == 1)
#define PRINTDEBUG osTPrintf
#else
#include <ctr/vlink.h>
#define PRINTDEBUG vlink_dos_printf
#endif
#else
#define PRINTDEBUG i_no_print
static void i_no_print( const char *fmt, ... );
static void i_no_print( const char *fmt, ... ){ return; }
#endif
#if (RTFS_DEBUG_PRINT_ON == 1)
// #define PRINTDEBUG OS_TPrintf
#else
// #define PRINTDEBUG( ...) ((void)0)
#endif
// #define PRINTDEBUG OS_TPrintf
#define PRINTDEBUG( ...) ((void)0)
/*---------------------------------------------------------------------------* /*---------------------------------------------------------------------------*
globalÏ<EFBFBD> globalÏ<EFBFBD>
@ -191,6 +186,11 @@ static void file_get_CHS_params( u32 file_sector_num)
mbytes = (file_sector_num >> 11); mbytes = (file_sector_num >> 11);
while( 1) { while( 1) {
// if( mbytes < 1) {
// file_heads = 1;
// file_secptrack = 8;
// break;
// }
if( mbytes <= 2) { if( mbytes <= 2) {
file_heads = 2; file_heads = 2;
file_secptrack = 16; file_secptrack = 16;

View File

@ -11,7 +11,7 @@
* *
* Description: * Description:
* This file contains porting layer tuning constants for configuring RTFS. * This file contains porting layer tuning constants for configuring RTFS.
* It is included by rtfsconf.h. * It is included by pcconf.h.
* *
****************************************************************************/ ****************************************************************************/
@ -25,26 +25,23 @@
#define KS_CONSTANT const /* See porting reference guide for explanation */ #define KS_CONSTANT const /* See porting reference guide for explanation */
#define KS_FAR /* See porting reference guide for explanation */ #define KS_FAR /* See porting reference guide for explanation */
/* Compile time constants to control device inclusion and includion of
porting layer subroutines */
/* Compile time constants to control device inclusion #define INCLUDE_IDE 0 /* - Include the IDE driver */
See the reference guide for an explanation #define INCLUDE_PCMCIA 0 /* - Include the pcmcia driver */
*/ #define INCLUDE_PCMCIA_SRAM 0 /* - Include the pcmcia static ram card driver */
#define INCLUDE_COMPACT_FLASH 0 /* - Support compact flash (requires IDE and PCMCIA) */
#define INCLUDE_CDROM 0 /* - Support ATAPI CD (requires IDE) */
#define INCLUDE_SD 0 #define INCLUDE_FLASH_FTL 0 /* - Include the linear flash driver */
#define INCLUDE_IDE 0 /* - Include the IDE driver */ #define INCLUDE_ROMDISK 0 /* - Include the rom disk driver */
#define INCLUDE_PCMCIA 0 /* - Include the pcmcia driver */ #define INCLUDE_RAMDISK 0 /* - Include the rom disk driver */
#define INCLUDE_PCMCIA_SRAM 0 /* - Include the pcmcia static ram card driver */ #define INCLUDE_MMCCARD 0 /* - Include the multi media flash card driver */
#define INCLUDE_COMPACT_FLASH 0 /* - Support compact flash (requires IDE and PCMCIA) */ #define INCLUDE_SMARTMEDIA 0 /* - Include the smart media flash card driver */
#define INCLUDE_FLASH_FTL 0 /* - Include the linear flash driver */ #define INCLUDE_FLOPPY 0 /* - Include the floppy disk driver */
#define INCLUDE_ROMDISK 0 /* - Include the rom disk driver */ #define INCLUDE_HOSTDISK 0 /* - Include the host disk disk simulator */
#define INCLUDE_RAMDISK 0 /* - Include the rom disk driver */ #define INCLUDE_WINDEV 0 /* - Include windows direct device access */
#define INCLUDE_MMCCARD 0 /* - Include the multi media flash card driver */ #define INCLUDE_UDMA 0 /* - Include ultra dma support for the ide driver */
#define INCLUDE_SMARTMEDIA 0 /* - Include the smart media flash card driver */ #define INCLUDE_82365_PCMCTRL 0 /* - Include the 82365 pcmcia controller driver */
#define INCLUDE_FLOPPY 0 /* - Include the floppy disk driver */
#define INCLUDE_HOSTDISK 0 /* - Include the host disk disk simulator */
#define INCLUDE_UDMA 0 /* - Include ultra dma support for the ide driver */
#define INCLUDE_82365_PCMCTRL 0 /* - Include the 82365 pcmcia controller driver */
#endif /* __PORTCONF__ */ #endif /* __PORTCONF__ */

View File

@ -433,6 +433,7 @@ character (\n or \r).
void rtfs_port_puts(byte *buffer) void rtfs_port_puts(byte *buffer)
{ {
PRINTDEBUG( "%s\n", buffer); //ctr modified PRINTDEBUG( "%s\n", buffer); //ctr modified
OS_TPrintf( "%s\n", buffer); //ctr modified
/* Use cputs or some other console output function. If you have no console /* Use cputs or some other console output function. If you have no console
output function then leave it blank */ output function then leave it blank */
/* cputs(buffer); */ /* cputs(buffer); */

View File

@ -16,21 +16,22 @@ static void pc_release_blk(BLKBUFFCNTXT *pbuffcntxt, BLKBUFF *pinblk);
static BLKBUFF *pc_allocate_blk(DDRIVE *pdrive, BLKBUFFCNTXT *pbuffcntxt); static BLKBUFF *pc_allocate_blk(DDRIVE *pdrive, BLKBUFFCNTXT *pbuffcntxt);
/* Debugging tools to be removed in he final product */ /* Debugging tools to be removed in he final product */
#define DEBUG_BLOCK_CODE 0 #define DEBUG_BLOCK_CODE 0
#define DEBUG_FAT_CODE 0 #define DEBUG_FAT_CODE 0
void debug_check_blocks(BLKBUFFCNTXT *pbuffcntxt, int numblocks, char *where); void debug_check_blocks(BLKBUFFCNTXT *pbuffcntxt, int numblocks, char *where, dword line);
void debug_check_fat(FATBUFFCNTXT *pfatbuffcntxt, char *where); void debug_check_fat(FATBUFFCNTXT *pfatbuffcntxt, char *where);
void debug_break(char *where, char *message); void debug_break(char *where, dword line, char *message);
#if (DEBUG_BLOCK_CODE) #if (DEBUG_BLOCK_CODE)
#define DEBUG_CHECK_BLOCKS(X,Y,Z) debug_check_blocks(X,Y,X); #define DEBUG_CHECK_BLOCKS(X,Y,Z) debug_check_blocks(X,Y,Z,0);
#else #else
#define DEBUG_CHECK_BLOCKS(X,Y,Z) #define DEBUG_CHECK_BLOCKS(X,Y,Z)
#endif #endif
#if (DEBUG_FAT_CODE) #if (DEBUG_FAT_CODE)
#define DEBUG_CHECK_FAT(X,Y) debug_check_fat(X,Y); #define DEBUG_CHECK_FAT(X,Y) debug_check_fat(X,Y);
#else #else
#define DEBUG_CHECK_FAT(X,Y) #define DEBUG_CHECK_FAT(X,Y)
#endif #endif
#if (!INCLUDE_FAILSAFE_CODE) #if (!INCLUDE_FAILSAFE_CODE)
@ -45,7 +46,7 @@ BOOLEAN block_devio_write(BLKBUFF *pblk)
/* dword blockno; /* dword blockno;
blockno = pblk->blockno;*/ blockno = pblk->blockno;*/
return(devio_write(pblk->pdrive->driveno,pblk->blockno, pblk->data, (int) 1, FALSE)); return(devio_write(pblk->pdrive->driveno,pblk->blockno, pblk->data, (int) 1, FALSE));
} }
BOOLEAN fat_devio_write(DDRIVE *pdrive, FATBUFF *pblk, int fatnumber) BOOLEAN fat_devio_write(DDRIVE *pdrive, FATBUFF *pblk, int fatnumber)
{ {
@ -73,9 +74,9 @@ BOOLEAN fat_devio_read(DDRIVE *pdrive, dword blockno, byte *fat_data);
Description Description
Give back a buffer to the system buffer pool so that it may Give back a buffer to the system buffer pool so that it may
be re-used. If was_err is TRUE this means that the data in the be re-used. If was_err is TRUE this means that the data in the
buffer is invalid so discard the buffer from the buffer pool. buffer is invalid so discard the buffer from the buffer pool.
Returns Returns
Nothing Nothing
@ -88,9 +89,9 @@ void pc_release_buf(BLKBUFF *pblk)
DEBUG_CHECK_BLOCKS(pblk->pdrive->pbuffcntxt, pblk->pdrive->pbuffcntxt->num_blocks, "Release") DEBUG_CHECK_BLOCKS(pblk->pdrive->pbuffcntxt, pblk->pdrive->pbuffcntxt->num_blocks, "Release")
#if (DEBUG_BLOCK_CODE) #if (DEBUG_BLOCK_CODE)
if (!pblk->pdrive->mount_valid) if (!pblk->pdrive->mount_valid)
debug_break("release buf", "Mount not valid"); debug_break("release buf", __LINE__, "Mount not valid");
if (pblk->block_state != DIRBLOCK_COMMITTED && pblk->block_state != DIRBLOCK_UNCOMMITTED) if (pblk->block_state != DIRBLOCK_COMMITTED && pblk->block_state != DIRBLOCK_UNCOMMITTED)
debug_break("release buf", "releasing buffer not in use list"); debug_break("release buf", __LINE__,"releasing buffer not in use list");
#endif #endif
if (pblk->block_state != DIRBLOCK_COMMITTED && pblk->block_state != DIRBLOCK_UNCOMMITTED) if (pblk->block_state != DIRBLOCK_COMMITTED && pblk->block_state != DIRBLOCK_UNCOMMITTED)
@ -99,8 +100,7 @@ void pc_release_buf(BLKBUFF *pblk)
if (pblk->use_count) if (pblk->use_count)
{ {
pblk->use_count -= 1; pblk->use_count -= 1;
if (!pblk->use_count) /* 03-07-07 Changed. No longer increment num_free if usecount goes to zero */
pblk->pdrive->pbuffcntxt->num_free += 1;
} }
OS_RELEASE_FSCRITICAL() OS_RELEASE_FSCRITICAL()
} }
@ -109,10 +109,10 @@ void pc_release_buf(BLKBUFF *pblk)
pc_discard_buf - Put a buffer back on the free list. pc_discard_buf - Put a buffer back on the free list.
Description Description
Check if a buffer is in the buffer pool, unlink it from the Check if a buffer is in the buffer pool, unlink it from the
buffer pool if it is. buffer pool if it is.
Put the buffer on the free list. Put the buffer on the free list.
Returns Returns
Nothing Nothing
@ -137,7 +137,7 @@ BLKBUFFCNTXT *pbuffcntxt;
#endif #endif
if (pblk->block_state == DIRBLOCK_FREE) if (pblk->block_state == DIRBLOCK_FREE)
return; return;
OS_CLAIM_FSCRITICAL() OS_CLAIM_FSCRITICAL()
pbuffcntxt = pblk->pdrive->pbuffcntxt; pbuffcntxt = pblk->pdrive->pbuffcntxt;
DEBUG_CHECK_BLOCKS(pbuffcntxt, pbuffcntxt->num_blocks, "Discard 1") DEBUG_CHECK_BLOCKS(pbuffcntxt, pbuffcntxt->num_blocks, "Discard 1")
@ -147,9 +147,9 @@ BLKBUFFCNTXT *pbuffcntxt;
pc_release_blk(pbuffcntxt, pblk); pc_release_blk(pbuffcntxt, pblk);
#if (DEBUG_BLOCK_CODE) #if (DEBUG_BLOCK_CODE)
if (pblk->pnext && pblk->pnext->pprev != pblk) if (pblk->pnext && pblk->pnext->pprev != pblk)
debug_break("discard buf", "Buffer and populated pool inconsistent"); debug_break("discard buf", __LINE__,"Buffer and populated pool inconsistent");
if (pblk->pprev && pblk->pprev->pnext != pblk) if (pblk->pprev && pblk->pprev->pnext != pblk)
debug_break("discard buf", "Buffer and populated pool inconsistent"); debug_break("discard buf", __LINE__,"Buffer and populated pool inconsistent");
#endif #endif
/* Unlink it from the populated pool double check link integrity */ /* Unlink it from the populated pool double check link integrity */
if (pblk->pnext && pblk->pnext->pprev == pblk) if (pblk->pnext && pblk->pnext->pprev == pblk)
@ -175,7 +175,7 @@ Description
or get it from the buffer pool and return the buffer. or get it from the buffer pool and return the buffer.
Note: After reading, you own the buffer. You must release it by Note: After reading, you own the buffer. You must release it by
calling pc_release_buff() or pc_discard_buff() before it may be calling pc_release_buff() or pc_discard_buff() before it may be
used for other blocks. used for other blocks.
Returns Returns
@ -183,6 +183,8 @@ Description
*****************************************************************************/ *****************************************************************************/
BLKBUFF *pc_read_blk(DDRIVE *pdrive, dword blockno) /*__fn__*/ BLKBUFF *pc_read_blk(DDRIVE *pdrive, dword blockno) /*__fn__*/
{ {
BLKBUFF *pblk; BLKBUFF *pblk;
@ -228,7 +230,7 @@ BLKBUFFCNTXT *pbuffcntxt;
OS_RELEASE_FSCRITICAL() OS_RELEASE_FSCRITICAL()
} }
else else
{ {
/* set errno to IO error unless devio set PEDEVICE */ /* set errno to IO error unless devio set PEDEVICE */
if (!get_errno()) if (!get_errno())
rtfs_set_errno(PEIOERRORREADBLOCK); /* pc_read_blk device read error */ rtfs_set_errno(PEIOERRORREADBLOCK); /* pc_read_blk device read error */
@ -256,6 +258,8 @@ BLKBUFF *pc_scratch_blk(void) /*__fn__*/
BLKBUFF *pblk; BLKBUFF *pblk;
OS_CLAIM_FSCRITICAL() OS_CLAIM_FSCRITICAL()
pblk = pc_allocate_blk(0, &prtfs_cfg->buffcntxt); pblk = pc_allocate_blk(0, &prtfs_cfg->buffcntxt);
if (pblk)
prtfs_cfg->buffcntxt.scratch_alloc_count += 1;
OS_RELEASE_FSCRITICAL() OS_RELEASE_FSCRITICAL()
return (pblk); return (pblk);
} }
@ -270,6 +274,7 @@ void pc_free_scratch_blk(BLKBUFF *pblk)
pbuffcntxt->pfree_blocks = pblk; pbuffcntxt->pfree_blocks = pblk;
pblk->block_state = DIRBLOCK_FREE; pblk->block_state = DIRBLOCK_FREE;
pbuffcntxt->num_free += 1; pbuffcntxt->num_free += 1;
pbuffcntxt->scratch_alloc_count -= 1;
OS_RELEASE_FSCRITICAL() OS_RELEASE_FSCRITICAL()
} }
@ -280,7 +285,7 @@ Description
Allocate and zero a BLKBUFF and add it to the to the buffer pool. Allocate and zero a BLKBUFF and add it to the to the buffer pool.
Note: After initializing you own the buffer. You must release it by Note: After initializing you own the buffer. You must release it by
calling pc_release_buff() or pc_discard_buf() before it may be used calling pc_release_buff() or pc_discard_buf() before it may be used
for other blocks. for other blocks.
Returns Returns
@ -357,7 +362,7 @@ BOOLEAN deleting;
return; return;
pbuffcntxt = pdrive->pbuffcntxt; pbuffcntxt = pdrive->pbuffcntxt;
DEBUG_CHECK_BLOCKS(pbuffcntxt, pbuffcntxt->num_blocks, "Free all 1") DEBUG_CHECK_BLOCKS(pbuffcntxt, pbuffcntxt->num_blocks, "Free all 1")
do do
{ {
deleting = FALSE; deleting = FALSE;
OS_CLAIM_FSCRITICAL() OS_CLAIM_FSCRITICAL()
@ -423,7 +428,7 @@ BLKBUFF *pblk;
if (pblk == pinblk) if (pblk == pinblk)
*(pbuffcntxt->blk_hash_tbl+hash_index) = pinblk->pnext2; *(pbuffcntxt->blk_hash_tbl+hash_index) = pinblk->pnext2;
else else
{ {
while (pblk) while (pblk)
{ {
if (pblk->pnext2==pinblk) if (pblk->pnext2==pinblk)
@ -473,67 +478,87 @@ BLKBUFF *pblk;
/* Allocate a block or re-use an un-committed one */ /* Allocate a block or re-use an un-committed one */
static BLKBUFF *pc_allocate_blk(DDRIVE *pdrive, BLKBUFFCNTXT *pbuffcntxt) static BLKBUFF *pc_allocate_blk(DDRIVE *pdrive, BLKBUFFCNTXT *pbuffcntxt)
{ {
BLKBUFF *pblk, *pblkscan; BLKBUFF *pfreeblk,*puncommitedblk, *pfoundblk, *pblkscan;
int num_free; int populated_but_uncommited;
/* Note: pdrive may be NULL, do not dereference the pointer */
pblk = 0; /* Note: pdrive may be NULL, do not dereference the pointer */
pfreeblk = pfoundblk = puncommitedblk = 0;
populated_but_uncommited = 0;
/* Use blocks that are on the freelist first */
if (pbuffcntxt->pfree_blocks) if (pbuffcntxt->pfree_blocks)
{ {
pblk = pbuffcntxt->pfree_blocks; pfreeblk = pbuffcntxt->pfree_blocks;
pbuffcntxt->pfree_blocks = pblk->pnext; pbuffcntxt->pfree_blocks = pfreeblk->pnext;
pbuffcntxt->num_free -= 1;
} }
else if (pbuffcntxt->ppopulated_blocks)
/* Scan the populated list. Count the number of uncommited blocks to set low water marks
and, if we haven't already allocated a block from the free list, select a replacement block. */
if (pbuffcntxt->ppopulated_blocks)
{ {
/* Find the oldest UNCOMMITED block (deepest into the list) */ int loop_guard = 0;
/* Count UNCOMMITED blocks and find the oldest UNCOMMITED block in the list */
pblkscan = pbuffcntxt->ppopulated_blocks; pblkscan = pbuffcntxt->ppopulated_blocks;
num_free = 0;
while (pblkscan) while (pblkscan)
{ {
if (pblkscan->block_state == DIRBLOCK_UNCOMMITTED && !pblkscan->use_count) if (pblkscan->block_state == DIRBLOCK_UNCOMMITTED && !pblkscan->use_count)
{ {
pblk = pblkscan; puncommitedblk = pblkscan;
num_free += 1; populated_but_uncommited += 1;
} }
pblkscan = pblkscan->pnext; pblkscan = pblkscan->pnext;
/* Guard against endless loop */
if (loop_guard++ > pbuffcntxt->num_blocks)
{
rtfs_set_errno(PEINTERNAL); /* pc_allocate_blk: Internal error*/
return(0);
}
} }
pbuffcntxt->num_free = num_free; /* If we don't already have a free block we'll reuse the oldest uncommitted block so release it */
if (pblk) if (!pfreeblk && puncommitedblk)
{ {
pc_release_blk(pbuffcntxt, pblk); /* Remove it from buffer pool */ pc_release_blk(pbuffcntxt, puncommitedblk); /* Remove it from buffer pool */
/* Unlink it from the populated pool */ /* Unlink it from the populated pool */
if (pblk->pnext) if (puncommitedblk->pnext)
pblk->pnext->pprev = pblk->pprev; puncommitedblk->pnext->pprev = puncommitedblk->pprev;
if (pblk->pprev) if (puncommitedblk->pprev)
pblk->pprev->pnext = pblk->pnext; puncommitedblk->pprev->pnext = puncommitedblk->pnext;
if (pbuffcntxt->ppopulated_blocks == pblk) if (pbuffcntxt->ppopulated_blocks == puncommitedblk)
pbuffcntxt->ppopulated_blocks = pblk->pnext; pbuffcntxt->ppopulated_blocks = puncommitedblk->pnext;
} }
} }
if (pblk) if (pfreeblk)
pfoundblk = pfreeblk;
else
pfoundblk = puncommitedblk;
if (pfoundblk)
{ /* Put in a known state */ { /* Put in a known state */
pbuffcntxt->num_free -= 1; /* 03-07-2007 using a different method to calculate low water mark. Previous method
if (pbuffcntxt->num_free < pbuffcntxt->low_water) undercounted the worst case buffer allocation requirements */
pbuffcntxt->low_water = pbuffcntxt->num_free; if (pbuffcntxt->num_free + populated_but_uncommited < pbuffcntxt->low_water)
pblk->use_count = 0; pbuffcntxt->low_water = pbuffcntxt->num_free + populated_but_uncommited;
pblk->block_state = DIRBLOCK_ALLOCATED; pfoundblk->use_count = 0;
pblk->pdrive = pdrive; pfoundblk->block_state = DIRBLOCK_ALLOCATED;
pfoundblk->pdrive = pdrive;
} }
else else
{ {
pbuffcntxt->num_alloc_failures += 1; pbuffcntxt->num_alloc_failures += 1;
rtfs_set_errno(PERESOURCEBLOCK); /* pc_allocate_blk out of resources */ rtfs_set_errno(PERESOURCEBLOCK); /* pc_allocate_blk out of resources */
} }
return(pblk); return(pfoundblk);
} }
/* Tomo */ /* Tomo */
/* Traverse a cluster chain and make sure that all blocks in the cluster /* Traverse a cluster chain and make sure that all blocks in the cluster
chain are flushed from the buffer pool. This is required when deleting chain are flushed from the buffer pool. This is required when deleting
a directory since it is possible, although unlikely, that blocks used in a directory since it is possible, although unlikely, that blocks used in
the directory may be used in a file. This may cause the buffered the directory may be used in a file. This may cause the buffered
block to be different from on-disk block. block to be different from on-disk block.
Called by pc_rmnode Called by pc_rmnode
*/ */
void pc_flush_chain_blk(DDRIVE *pdrive, CLUSTERTYPE cluster) void pc_flush_chain_blk(DDRIVE *pdrive, CLUSTERTYPE cluster)
{ {
int i; int i;
dword blockno; dword blockno;
@ -565,7 +590,7 @@ BLKBUFF *pblk;
if (cluster == 0) /* clnext detected error */ if (cluster == 0) /* clnext detected error */
break; break;
} }
} }
/* Initialize and populate a block buffer context structure */ /* Initialize and populate a block buffer context structure */
BOOLEAN pc_initialize_block_pool(BLKBUFFCNTXT *pbuffcntxt, int nblkbuffs, BOOLEAN pc_initialize_block_pool(BLKBUFFCNTXT *pbuffcntxt, int nblkbuffs,
@ -582,7 +607,7 @@ BLKBUFF *pblk;
rtfs_memset(pblk,(byte) 0, sizeof(BLKBUFF)); rtfs_memset(pblk,(byte) 0, sizeof(BLKBUFF));
pblk->pnext = pblk+1; pblk->pnext = pblk+1;
} }
rtfs_memset(pblk,(byte) 0, sizeof(BLKBUFF)); rtfs_memset(pblk,(byte) 0, sizeof(BLKBUFF));
/* pblk->pnext = 0; accomplished by memset */ /* pblk->pnext = 0; accomplished by memset */
pbuffcntxt->pfree_blocks = pmem_block_pool; pbuffcntxt->pfree_blocks = pmem_block_pool;
pbuffcntxt->hash_size = blk_hashtble_size; pbuffcntxt->hash_size = blk_hashtble_size;
@ -602,7 +627,7 @@ static void pc_commit_fat_blk(FATBUFFCNTXT *pfatbuffcntxt, FATBUFF *pblk);
void pc_commit_fat_table(FATBUFFCNTXT *pfatbuffcntxt); void pc_commit_fat_table(FATBUFFCNTXT *pfatbuffcntxt);
void pc_sort_committed_blocks(FATBUFFCNTXT *pfatbuffcntxt); void pc_sort_committed_blocks(FATBUFFCNTXT *pfatbuffcntxt);
BOOLEAN pc_flush_fat_blocks(DDRIVE *pdrive) BOOLEAN pc_flush_fat_blocks(DDRIVE *pdrive)
{ {
FATBUFFCNTXT *pfatbuffcntxt; FATBUFFCNTXT *pfatbuffcntxt;
@ -697,12 +722,12 @@ dword b;
#if (INCLUDE_FAILSAFE_CODE) #if (INCLUDE_FAILSAFE_CODE)
/* If in the primary cache and the new flag is write but the old /* If in the primary cache and the new flag is write but the old
flag was not write then we will need to journal the block */ flag was not write then we will need to journal the block */
if ((usage_flags & 0x80000000ul) && (!(b & 0x80000000ul))) if ((usage_flags & 0x80000000ul) && (!(b & 0x80000000ul)))
if (pro_failsafe_journal_full(pdrive)) if (pro_failsafe_journal_full(pdrive))
return(0); /* Failsafe sets errno */ return(0); /* Failsafe sets errno */
#endif #endif
if (usage_flags) /* bit 31 0x80000000ul is write bit 29 0x20000000ul is lock */ if (usage_flags) /* bit 31 0x80000000ul is write bit 29 0x20000000ul is lock */
*(pfatbuffcntxt->mapped_blocks+hash_index) |= usage_flags; *(pfatbuffcntxt->mapped_blocks+hash_index) |= usage_flags;
return (*(pfatbuffcntxt->mapped_data+hash_index)); return (*(pfatbuffcntxt->mapped_data+hash_index));
} }
else else
@ -729,7 +754,7 @@ dword b;
#if (INCLUDE_FAILSAFE_CODE) #if (INCLUDE_FAILSAFE_CODE)
else else
{ {
/* If in the primary cache but uncommitted, if it will /* If in the primary cache but uncommitted, if it will
switch to committed now then we will have to journal the block */ switch to committed now then we will have to journal the block */
if (usage_flags & 0x80000000ul) if (usage_flags & 0x80000000ul)
{ {
@ -815,7 +840,7 @@ swap_write_error:
if (pblk == *(pfatbuffcntxt->fat_blk_hash_tbl+temp_hash_index)) if (pblk == *(pfatbuffcntxt->fat_blk_hash_tbl+temp_hash_index))
*(pfatbuffcntxt->fat_blk_hash_tbl+temp_hash_index) = pblk->pnext2; *(pfatbuffcntxt->fat_blk_hash_tbl+temp_hash_index) = pblk->pnext2;
else else
{ {
pblkscan = *(pfatbuffcntxt->fat_blk_hash_tbl+temp_hash_index); pblkscan = *(pfatbuffcntxt->fat_blk_hash_tbl+temp_hash_index);
while (pblkscan) while (pblkscan)
{ {
@ -833,14 +858,14 @@ swap_write_error:
DEBUG_CHECK_FAT(pfatbuffcntxt, "Map 5") DEBUG_CHECK_FAT(pfatbuffcntxt, "Map 5")
} }
} }
else else
{ /* the free list already had a block available for us */ { /* the free list already had a block available for us */
pfatbuffcntxt->stat_secondary_cache_loads += 1; pfatbuffcntxt->stat_secondary_cache_loads += 1;
} }
pblk = pfatbuffcntxt->pfree_blocks; pblk = pfatbuffcntxt->pfree_blocks;
if (!pblk) if (!pblk)
{ {
/* No blocks available. We tried to flush the secondary and /* No blocks available. We tried to flush the secondary and
that didn't come up with any so we're completely out */ that didn't come up with any so we're completely out */
rtfs_set_errno(PERESOURCEFATBLOCK); rtfs_set_errno(PERESOURCEFATBLOCK);
return(0); return(0);
@ -867,7 +892,7 @@ swap_write_error:
*(pfatbuffcntxt->mapped_data+hash_index) = pblk->fat_data; *(pfatbuffcntxt->mapped_data+hash_index) = pblk->fat_data;
DEBUG_CHECK_FAT(pfatbuffcntxt, "Map 7") DEBUG_CHECK_FAT(pfatbuffcntxt, "Map 7")
#if (INCLUDE_FAILSAFE_CODE) #if (INCLUDE_FAILSAFE_CODE)
/* We are coming from the FREE state, but write is /* We are coming from the FREE state, but write is
set so journal the buffer */ set so journal the buffer */
if (usage_flags & 0x80000000ul) if (usage_flags & 0x80000000ul)
{ {
@ -888,7 +913,7 @@ swap_write_error:
BOOLEAN pc_initialize_fat_block_pool(FATBUFFCNTXT *pfatbuffcntxt, BOOLEAN pc_initialize_fat_block_pool(FATBUFFCNTXT *pfatbuffcntxt,
int fat_buffer_size, FATBUFF *pfat_buffers, int fat_buffer_size, FATBUFF *pfat_buffers,
int fat_hashtbl_size, FATBUFF **pfat_hash_table, int fat_hashtbl_size, FATBUFF **pfat_hash_table,
byte **pfat_primary_cache, dword *pfat_primary_index) byte **pfat_primary_cache, dword *pfat_primary_index)
{ {
dword t; dword t;
@ -959,7 +984,7 @@ static void pc_commit_fat_blk(FATBUFFCNTXT *pfatbuffcntxt, FATBUFF *pblk)
{ {
#if (DEBUG_FAT_CODE) #if (DEBUG_FAT_CODE)
if (pblk->fat_block_state != FATBLOCK_UNCOMMITTED) if (pblk->fat_block_state != FATBLOCK_UNCOMMITTED)
debug_break("commit fat block", "Not un-committed"); debug_break("commit fat block", __LINE__,"Not un-committed");
#endif #endif
/* Remove from the uncommitted list */ /* Remove from the uncommitted list */
if (pblk->pnext) if (pblk->pnext)
@ -991,7 +1016,7 @@ FATBUFF *pblk;
/* Move from uncommitted list to committed list */ /* Move from uncommitted list to committed list */
pblk = pc_find_fat_blk(pfatbuffcntxt, (b & 0x0ffffffful)); pblk = pc_find_fat_blk(pfatbuffcntxt, (b & 0x0ffffffful));
if (pblk) /* This should not fail */ if (pblk) /* This should not fail */
pc_commit_fat_blk(pfatbuffcntxt, pblk); pc_commit_fat_blk(pfatbuffcntxt, pblk);
b |= 0x40000000ul; /* set commited flag in primary */ b |= 0x40000000ul; /* set commited flag in primary */
*(pfatbuffcntxt->mapped_blocks+i) = b; *(pfatbuffcntxt->mapped_blocks+i) = b;
} }
@ -1001,7 +1026,7 @@ void pc_sort_committed_blocks(FATBUFFCNTXT *pfatbuffcntxt)
{ {
FATBUFF *pblk, *pprev, *psorted_list, *psort, *pblk_source_scan; FATBUFF *pblk, *pprev, *psorted_list, *psort, *pblk_source_scan;
/* The first element is the root of the sorted list, we begin from the /* The first element is the root of the sorted list, we begin from the
next element scanning foreward and inserting in sorted order */ next element scanning foreward and inserting in sorted order */
psorted_list = pfatbuffcntxt->pcommitted_blocks; /* pfatbuffcntxt->pcommitted_blocks is guaranteed not null */ psorted_list = pfatbuffcntxt->pcommitted_blocks; /* pfatbuffcntxt->pcommitted_blocks is guaranteed not null */
@ -1048,9 +1073,12 @@ FATBUFF *pblk, *pprev, *psorted_list, *psort, *pblk_source_scan;
} }
#if (DEBUG_BLOCK_CODE || DEBUG_FAT_CODE) #if (DEBUG_BLOCK_CODE || DEBUG_FAT_CODE)
void debug_break(char *where, char *message) void debug_break(char *where, dword line, char *message)
{ {
printf("%s: %s\n", where, message); if (line)
printf("%s (%d): %s\n", where, line, message);
else
printf("%s: %s\n", where, message);
} }
#endif #endif
@ -1127,32 +1155,41 @@ int numblocks;
#endif /* DEBUG_FAT_CODE */ #endif /* DEBUG_FAT_CODE */
#if (DEBUG_BLOCK_CODE) #if (DEBUG_BLOCK_CODE)
void debug_check_blocks(BLKBUFFCNTXT *pbuffcntxt, int numblocks, char *where) void debug_check_blocks(BLKBUFFCNTXT *pbuffcntxt, int numblocks, char *where, dword line)
{ {
BLKBUFF *pblk; BLKBUFF *pblk;
BLKBUFF *pblk_prev; BLKBUFF *pblk_prev;
int nb = 0; int nb = 0;
int nfreelist = 0;
int npopulatedlist = 0;
int i; int i;
pblk = pbuffcntxt->pfree_blocks; pblk = pbuffcntxt->pfree_blocks;
while (pblk) while (pblk)
{ {
nb += 1; nb += 1;
if (nb > numblocks) if (nb > numblocks)
debug_break(where, "Bad freelist"); debug_break(where,line, "Bad freelist");
pblk = pblk->pnext; pblk = pblk->pnext;
} }
nfreelist = nb;
pblk = pbuffcntxt->ppopulated_blocks; pblk = pbuffcntxt->ppopulated_blocks;
if (pblk && pblk->pprev) if (pblk && pblk->pprev)
debug_break(where, "Bad populated root"); debug_break(where,line, "Bad populated root");
while (pblk) while (pblk)
{ {
npopulatedlist += 1;
nb += 1; nb += 1;
if (nb > numblocks) if (nb > numblocks)
debug_break(where, "Bad populated list"); debug_break(where, line, "Bad populated list");
pblk = pblk->pnext; pblk = pblk->pnext;
} }
/* Add in outstanding scratch allocates */
nb += pbuffcntxt->scratch_alloc_count;
if (nb != numblocks) if (nb != numblocks)
debug_break(where, "Leak"); debug_break(where, line, "Leak");
if (pbuffcntxt->ppopulated_blocks) if (pbuffcntxt->ppopulated_blocks)
{ {
@ -1161,7 +1198,7 @@ int i;
while (pblk) while (pblk)
{ {
if (pblk->pprev != pblk_prev) if (pblk->pprev != pblk_prev)
debug_break(where, "Bad link in populated list"); debug_break(where, line, "Bad link in populated list");
pblk_prev = pblk; pblk_prev = pblk;
pblk = pblk->pnext; pblk = pblk->pnext;
} }
@ -1173,16 +1210,111 @@ int i;
while (pblk) while (pblk)
{ {
if (i != (int) (pblk->blockno&pbuffcntxt->hash_mask)) if (i != (int) (pblk->blockno&pbuffcntxt->hash_mask))
debug_break(where, "Block in wrong hash slot"); debug_break(where, line, "Block in wrong hash slot");
nb += 1; nb += 1;
if (nb > numblocks) if (nb > numblocks)
debug_break(where, "Loop in hash table"); debug_break(where, line, "Loop in hash table");
pblk = pblk->pnext2; pblk = pblk->pnext2;
} }
} }
} }
/* Diagnostic to display list list contents for FINODE and DROBJ pools.
display_free_lists(char *in_where)
Prints:
FINODES on FREE list, FINODES on in use list.
Drobj structures on freelist,
drob structure count marked free by scanning the drobj pool sequentially
BLKBUFF buffer free count, and low water count
BLKBUFF buffers counted on populated list
BLKBUFF buffers counted on free list
If populated count and free list don't add up the remainder will be scratch
buffers.
To Do: Add counters for scratch buffer allocation and frees.
Useful for validating that no leaks are occuring.
Requires printf
*/
void display_free_lists(char *in_where)
{
FINODE *pfi;
DROBJ *pobj;
struct blkbuff *pblk;
int j, i, objcount, finodecount,populated_block_count,free_list_count;
objcount = finodecount = i = populated_block_count = free_list_count = 0;
pfi = prtfs_cfg->mem_finode_freelist;
while (pfi)
{
i++;
pfi = pfi->pnext;
}
finodecount = 0;
pfi = prtfs_cfg->inoroot;
while (pfi)
{
finodecount++;
pfi = pfi->pnext;
}
printf("%-10.10s:INODES free:%4.4d in-use:%4.4d total:%4.4d \n", in_where, i,finodecount,prtfs_cfg->cfg_NFINODES);
i = 0;
pobj = prtfs_cfg->mem_drobj_freelist;
while (pobj)
{
i++;
pobj = (DROBJ *) pobj->pdrive;
}
pobj = prtfs_cfg->mem_drobj_pool;
objcount = 0;
for (j = 0; j < prtfs_cfg->cfg_NDROBJS; j++, pobj++)
{
if (!pobj->is_free)
objcount += 1;
}
printf("%-10.10s:DROBJS free:%4.4d in-use:%4.4d total:%4.4d \n", in_where, i,objcount, prtfs_cfg->cfg_NDROBJS);
pblk = prtfs_cfg->buffcntxt.ppopulated_blocks; /* uses pnext/pprev */
populated_block_count = 0;
while (pblk)
{
populated_block_count += 1;
pblk = pblk->pnext;
}
printf("%-10.10s:BLKBUFS free:%4.4d in-use:%4.4d low w:%4.4d scratch:%4.4d total:%4.4d \n",in_where,
prtfs_cfg->buffcntxt.num_free,
populated_block_count,
prtfs_cfg->buffcntxt.low_water,
prtfs_cfg->buffcntxt.scratch_alloc_count,
prtfs_cfg->buffcntxt.num_blocks);
pblk = prtfs_cfg->buffcntxt.pfree_blocks;
free_list_count = 0;
while (pblk)
{
free_list_count += 1;
pblk = pblk->pnext;
}
if (free_list_count != prtfs_cfg->buffcntxt.num_free)
{
printf("%-10.10s:Error num_freelist == %d but %d elements on the freelist\n",in_where, prtfs_cfg->buffcntxt.num_free, free_list_count);
}
}
/* May be called to detect buffer pool leaks */
void check_blocks(DDRIVE *pdrive, char *prompt, dword line)
{
debug_check_blocks(pdrive->pbuffcntxt, pdrive->pbuffcntxt->num_blocks, prompt, line);
}
#endif /* (DEBUG_BLOCK_CODE) */ #endif /* (DEBUG_BLOCK_CODE) */

View File

@ -899,6 +899,7 @@ struct fsblockmap *newpbm;
if (!pfscntxt->blockmap_freelist) if (!pfscntxt->blockmap_freelist)
{ {
error = 0; error = 0;
replacement_block = fs_block_map_scan(pfscntxt,blockno,&error); replacement_block = fs_block_map_scan(pfscntxt,blockno,&error);
if (error) /* fs_block_map_scan set errno */ if (error) /* fs_block_map_scan set errno */
return(0); return(0);

View File

@ -166,10 +166,11 @@ int fs_test(byte *path)
} }
#if (DO_INDEX_TEST) #if (DO_INDEX_TEST)
#define BIG_TEST_SIZE (4 * (CFG_NUM_INDEX_BUFFERS * 128)) /* #define BIG_TEST_SIZE (4 * (CFG_NUM_INDEX_BUFFERS * 128)) */
#define BIG_TEST_SIZE 4096
dword map_check[BIG_TEST_SIZE]; dword map_check[BIG_TEST_SIZE];
static BOOLEAN fs_test_map_cache(dword num_to_map); static BOOLEAN fs_test_map_cache(dword num_to_map);
static BOOLEAN _fs_test_map_cache(dword num_to_map, BOOLEAN random_fill); static BOOLEAN _fs_test_map_cache(dword num_to_map, int fill_op);
static BOOLEAN fs_test_index_errors(void); static BOOLEAN fs_test_index_errors(void);
BOOLEAN fs_test_indexing_main(byte *path) BOOLEAN fs_test_indexing_main(byte *path)
@ -179,6 +180,11 @@ struct fsblockmap *save_freelist;
fs_test_nvio_delete_fsfile(path); fs_test_nvio_delete_fsfile(path);
if (!open_index_test(path, FS_MODE_AUTORECOVER, TEST_BLOCKMAPSIZE, 0)) if (!open_index_test(path, FS_MODE_AUTORECOVER, TEST_BLOCKMAPSIZE, 0))
return(FALSE); return(FALSE);
if (test_fscontext.num_remap_blocks > BIG_TEST_SIZE)
{
FSDEBUG("INDEX TEST: BIG_TEST_SIZE too small to run index test. recompile")
return(FALSE);
}
/* Test mapping with all fitting in cache */ /* Test mapping with all fitting in cache */
FSDEBUG("INDEX TEST: Test mapping with cache > # journaled blocks") FSDEBUG("INDEX TEST: Test mapping with cache > # journaled blocks")
if (!fs_test_map_cache(test_fscontext.blockmap_size-1)) if (!fs_test_map_cache(test_fscontext.blockmap_size-1))
@ -1614,7 +1620,10 @@ return_error:
fs_test_rm_file(path, filename); fs_test_rm_file(path, filename);
return(0); return(0);
} }
if (pc_get_file_extents(fd, 1, &seginfo, FALSE) != 1) /* if (pc_get_file_extents(fd, 1, &seginfo, FALSE) != 1)
Use raw block numbers since we are comparing with the partition base
*/
if (pc_get_file_extents(fd, 1, &seginfo, TRUE) != 1)
goto return_error; goto return_error;
po_close(fd); po_close(fd);
return(seginfo.block); return(seginfo.block);

View File

@ -1,6 +1,162 @@
=================================================================
Functional changes between version 4.4zb versus version 4.4za (March 16, 2007)
=================================================================
Bug fixes:
Fixed a finode structure memory leak that could occur if a removal event occured
under certain conditions. The bug has been present since 1994.
Fixed a bug that was under reporting block buffer freelist low water mark values.
The bug was only in the calculation of the low water mark and did not cause any
runtime errors.
Fixed a problem with FAT32 info block access routines that ran unnecessarily
slowly and could read beyond the end of a buffer.
Features enhancements:
Implemented a shell command to simulate a card removal
Added a new display_free_lists() diagnostic routine to print current usage
stats. This routine may be called to monitor buffer usage.
Changes by file:
apigfrst.c - Fixed a bug that caused a leak of one finode structure if a card removal
event occured with an outstanding call to pc_gfirst() without a completed call
pc_gdone().
prblock.c - Fixed a bug that was causing an error in the calculation that produced incorrect
block buffer freelist low water mark values. The bug was only in the calculation of
the low water mark and did not cause any runtime errors.
rtfs.h - Modified the blkbuffcntxt structure to maintain a count of outstanding scratch
buffer allocations. This is used to correctly calculate low water usage and
for diagnostics.
prblock.c - Modified block diagnostic routines that is enabled by compiling with DEBUG_BLOCK_CODE
enabled in prblock.c
.. Include line numbers in diagnostics
.. Added a new dignostic
display_free_lists(char *comment_string)
this routine prints usage stats about DROBJ, FINODE and BLKBUFF structures.
It can be called to display snapshot of resource usage and to detect leaks.
rtfat32.c - Modified code that accesses the on disk FAT32 info structure. The structure is now
accessed at byte offset 484 in the info block. Prvious code was wasting cycles and
scanning the info block for the info block signature.
appcmdsh.c - Reprogrammed the shell's EJECT command to send a media removal event to
the specified drive id's device handler. This will trigger a remove event
for removable media device drivers.
appcmdsh.c - Implemented a callable routine named eject_driveno() that software can call to simulate
simulate a card removal. Useful for measuring the affects of card removals at specific
times
apiinit.c - Configure the host disk device driver as removable so it can process EJECT commands
from the command shell.
=================================================================
Functional changes between version 4.4za versus version 4.4y (February 16, 2007)
=================================================================
Note Version 44z was an unpublished interim release.
Bug Fixes:
.. rtfatxx.c - Changed fatxx_clnext() detect chain termination if the cluster value
is greater than xff7, xfff7 or xffffff7 for fat12, 16 , 32 respectively.
The current code detected only xfff, xffff and xfffffff as terminators.
.. rtkernfn.c Fixed a bug in rtfs_get_system_user(). If NUMUSERS is greater than
one and we are reclaiming the default user (0), because not enough
user structures are avaliable, make sure the current working directory objects are
freed and the finode access counts are reduced
.. rtfat32.c Added defensive code to check for a valid start hint from the info block.
if it is out of range set it to the first cluster in the FAT. Eliminates a possible
error trap if start hint in the info block is incorrect.
.. rtfat32.c Modified the info block flush routine to update the infoblock start hint with the
previous start hint read from the info block. This forces the start hint to be 3 always on
volume that have been formatted and written to by RTFS only.
.. prfstest.c - Minor bug fixes
.. csjis.c Fixed bug in JIS version of pc_cs_malias(). Was causing an error if the 8th character in the
filename was a 2 byte character sequence.
.. Bug in pc_emumerate - Added test to eliminate possible endless loop
.. po_write - Fixed error processing on cluster allocation failure. The code was always returning
a short write status, the number of bytes written, when the cluster allocation failed. This was
assuming that the underlying code failed because it detected disk full, not because of some other
error. The change tests the value of errno and if it is not set to PENOSPC, it return -1.
apifilmv.c - Fixed an error that was in some cases leaving errno at zero and returning an error status.
Now this condition sets ERRNO to PEINVALIDPATH;
.. Changed how hidden sectors are handled by the format utilities. Previous support
for hidden sectors was incorrect. The new method is correct. Hidden sectors are
ignored completely except during the format procedure when the bpb hidden sector
fields are set to the starting block of the partition.
apifrmat.c pc_format_volume changed the logic to set set numhide in the format
control structure to be the starting block number of the current partition.
apifrmat.c Obscure change that allows device drivers to specify format parameters for
32 bit formats. Previously supported only fat16/fat12 because the feature
was intended for floppy disks, to match IBM PC formats.
rtfat16.c - Changed the way hidden sectors are used in format
rtfat32.c - Changed the way hidden sectors are used in format
rtlowl.c - Fixed bug that was only initializig the low 16 bits of the
pdr->numhide, information field. This field is not used by RTFS.
New features:
.. Added a new device driver to Rtfs. The windev device is only available for the
windows emulation environment. The windev driver accesses block devices directly on
a windows platform using raw block accesses.
portconf.h - Added INCLUDE_WINDEV conditional constant.
drwindev.c - Source code for the direct block access driver
apiinit.c - Added code to mount a windev device if INCLUDE_WINDEV is
enabled in portconf.h
.. Include a new special purpose fast file move function.
apifastmv.c - New file containing pc_fast_mv().
pc_fast_mv - Move a file to a filename in another subdirectoy when you know
the destination filename does not already exist in that directory.
(designed for moving multiple files from one subdirectory to another
subdirectory that is initially empty.)
=================================================================
Functional changes between version 4.4y versus version 4.4x (November 3, 2006)
=================================================================
apifilio.c
Fixed parameter passing in seek functions to fix changes in beginning of
file and end of file processing that was introduced with po_ulseek in version
44v.
apiint.c
winhdisk.c
Added minor changes to these files forcing routines to query the device drive
again for media parms after a low level format. This was done in order to
support device drivers that may change media parameters during a low level format.
Functional changes between version 4.4x versus version 4.4ws (August 25, 2006) Functional changes between version 4.4x versus version 4.4ws (August 25, 2006)
================================================================= =================================================================
winhdisk,c - Removed some unreferenced performance diagnostic code that was winhdisk.c - Removed some unreferenced performance diagnostic code that was
inadverdantly placed in the file. inadverdantly placed in the file.
appcmdsh.c - Modified optional macro DISPLAY_ERRNO() to use RTFS print appcmdsh.c - Modified optional macro DISPLAY_ERRNO() to use RTFS print
routines instead of printf. routines instead of printf.

View File

@ -1205,6 +1205,7 @@ Returns
Nothing Nothing
****************************************************************************/ ****************************************************************************/
void pc_free_all_i( DDRIVE *pdrive) /*__fn__*/ void pc_free_all_i( DDRIVE *pdrive) /*__fn__*/
{ {
FINODE *pfi; FINODE *pfi;

View File

@ -137,7 +137,6 @@ BOOLEAN pc_mkfs16(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
ltotsecs = pfmt->numcyl; ltotsecs = pfmt->numcyl;
ltotsecs *= pfmt->secptrk; ltotsecs *= pfmt->secptrk;
ltotsecs *= pfmt->numhead; ltotsecs *= pfmt->numhead;
ltotsecs -= pfmt->numhide; //ctr modified
if (ltotsecs > 0xffffL) if (ltotsecs > 0xffffL)
{ {
@ -157,7 +156,7 @@ BOOLEAN pc_mkfs16(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
/* number heads */ /* number heads */
fr_WORD ( &(b[26]), pfmt->numhead); /*X*/ fr_WORD ( &(b[26]), pfmt->numhead); /*X*/
/* number hidden sectors */ /* number hidden sectors */
fr_WORD ( &(b[28]), pfmt->numhide); /*X*/ //ctr modified fr_DWORD ( &(b[28]), pfmt->numhide);
/* number of duplicate fats */ /* number of duplicate fats */
b[16] = pfmt->numfats; b[16] = pfmt->numfats;
fr_WORD ( &(b[22]), (word)pfmt->secpfat); /*X*/ fr_WORD ( &(b[22]), (word)pfmt->secpfat); /*X*/
@ -231,7 +230,7 @@ BOOLEAN pc_mkfs16(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
} }
if (!devio_write_format(driveno, (dword) 0 + pfmt->numhide, &(b[0]), 1, use_raw) ) if (!devio_write_format(driveno, 0 , &(b[0]), 1, use_raw) )
{ {
goto errex; goto errex;
} }
@ -246,7 +245,7 @@ BOOLEAN pc_mkfs16(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
if (fausize == 4) if (fausize == 4)
b[3] = (byte) 0xff; b[3] = (byte) 0xff;
blockno = pfmt->numhide + pfmt->secreserved + (i * pfmt->secpfat); //ctr modified blockno = pfmt->secreserved + (i * pfmt->secpfat);
for ( j = 0; j < pfmt->secpfat; j++) for ( j = 0; j < pfmt->secpfat; j++)
{ {
/* WRITE */ /* WRITE */
@ -260,7 +259,7 @@ BOOLEAN pc_mkfs16(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
} }
/* Now write the root sectors */ /* Now write the root sectors */
blockno = pfmt->numhide + pfmt->secreserved + pfmt->numfats * pfmt->secpfat; //ctr modified blockno = pfmt->secreserved + pfmt->numfats * pfmt->secpfat;
rtfs_memset(&b[0], 0, 512); rtfs_memset(&b[0], 0, 512);
for ( j = 0; j < (pfmt->numroot/INOPBLOCK) ; j++) for ( j = 0; j < (pfmt->numroot/INOPBLOCK) ; j++)
{ {

View File

@ -13,7 +13,7 @@
CLUSTERTYPE fatxx_clalloc(DDRIVE *pdr, CLUSTERTYPE clhint); CLUSTERTYPE fatxx_clalloc(DDRIVE *pdr, CLUSTERTYPE clhint);
CLUSTERTYPE fatxx_clgrow(DDRIVE *pdr, CLUSTERTYPE clno); CLUSTERTYPE fatxx_clgrow(DDRIVE *pdr, CLUSTERTYPE clno);
#if (FAT32) #if (FAT32)
struct fat32_info { struct fat32_info {
dword fs_sig; /* Signature of FAT32 (0x61417272) */ dword fs_sig; /* Signature of FAT32 (0x61417272) */
@ -31,21 +31,21 @@ BOOLEAN pc_init_drv_fat_info(DDRIVE *pdr, struct pcblk0 *pbl0)
pdr->numfats = pbl0->numfats; /* Number of fat copies */ pdr->numfats = pbl0->numfats; /* Number of fat copies */
if (pdr->secpfat == 0L) if (pdr->secpfat == 0L)
pdr->secpfat = pbl0->secpfat2; pdr->secpfat = pbl0->secpfat2;
if (pbl0->flags & NOFATMIRROR) if (pbl0->flags & NOFATMIRROR)
{ {
pdr->fatblock = (BLOCKT) pbl0->secreserved + pdr->fatblock = (BLOCKT) pbl0->secreserved +
((pbl0->flags & ACTIVEFAT) * pdr->secpfat); ((pbl0->flags & ACTIVEFAT) * pdr->secpfat);
pdr->numfats = 1; pdr->numfats = 1;
} }
else else
pdr->fatblock = (BLOCKT) pbl0->secreserved; pdr->fatblock = (BLOCKT) pbl0->secreserved;
/* The first block of the root is just past the fat copies */ /* The first block of the root is just past the fat copies */
pdr->firstclblock = pdr->fatblock + pdr->secpfat * pdr->numfats; pdr->firstclblock = pdr->fatblock + pdr->secpfat * pdr->numfats;
/* DM: 7-6-99: BUG FIX: */ /* DM: 7-6-99: BUG FIX: */
pdr->rootblock = (pbl0->rootbegin-2) * pdr->secpalloc + pdr->firstclblock; pdr->rootblock = (pbl0->rootbegin-2) * pdr->secpalloc + pdr->firstclblock;
/* WRONG: pdr->rootblock = pbl0->rootbegin-2 + pdr->firstclblock; */ /* WRONG: pdr->rootblock = pbl0->rootbegin-2 + pdr->firstclblock; */
/* Calculate the largest index in the file allocation table. /* Calculate the largest index in the file allocation table.
Total # block in the cluster area)/Blockpercluster == s total Total # block in the cluster area)/Blockpercluster == s total
Number of clusters. Entries 0 & 1 are reserved so the highest Number of clusters. Entries 0 & 1 are reserved so the highest
@ -55,7 +55,7 @@ BOOLEAN pc_init_drv_fat_info(DDRIVE *pdr, struct pcblk0 *pbl0)
{ {
/* Make sure the calculated index doesn't overflow the fat sectors */ /* Make sure the calculated index doesn't overflow the fat sectors */
dword max_index; dword max_index;
/* For FAT32 Each block of the fat holds 128 entries so the maximum index is /* For FAT32 Each block of the fat holds 128 entries so the maximum index is
(pdr->secpfat * 128)-1; */ (pdr->secpfat * 128)-1; */
max_index = (dword) pdr->secpfat; max_index = (dword) pdr->secpfat;
max_index *= 128; max_index *= 128;
@ -63,15 +63,20 @@ BOOLEAN pc_init_drv_fat_info(DDRIVE *pdr, struct pcblk0 *pbl0)
if (pdr->maxfindex > max_index) if (pdr->maxfindex > max_index)
pdr->maxfindex = max_index; pdr->maxfindex = max_index;
} }
/* Create a hint for where we should write file data. We do this /* Create a hint for where we should write file data. We do this
because directories are allocated in one cluster chunks while because directories are allocated in one cluster chunks while
file may allocate larger chunks. We Try to put directory file may allocate larger chunks. We Try to put directory
data at the beginning of the disk in a seperate region so we data at the beginning of the disk in a seperate region so we
do not break the contiguous space further out */ do not break the contiguous space further out */
pdr->known_free_clusters = pbl0->free_alloc; pdr->known_free_clusters = pbl0->free_alloc;
pdr->free_contig_base = pbl0->next_alloc; pdr->free_contig_base = pbl0->next_alloc;
/* 2-10-2007 - Added defensive code to check for a valid start hint. If it is out of range set it to
the first cluster in the FAT */
if (pdr->free_contig_base < 2 || pdr->free_contig_base >= pdr->maxfindex)
pdr->free_contig_base = 2;
pdr->free_contig_pointer = pdr->free_contig_base; pdr->free_contig_pointer = pdr->free_contig_base;
pdr->infosec = pbl0->infosec; pdr->infosec = pbl0->infosec;
pdr->fasize = 8; pdr->fasize = 8;
@ -79,21 +84,21 @@ BOOLEAN pc_init_drv_fat_info(DDRIVE *pdr, struct pcblk0 *pbl0)
} }
CLUSTERTYPE pc_get_parent_cluster(DDRIVE *pdrive, DROBJ *pobj) /* __fatfn__ */ CLUSTERTYPE pc_get_parent_cluster(DDRIVE *pdrive, DROBJ *pobj) /* __fatfn__ */
{ {
if ((pdrive->fasize == 8) && if ((pdrive->fasize == 8) &&
(pobj->blkinfo.my_frstblock == pdrive->rootblock)) (pobj->blkinfo.my_frstblock == pdrive->rootblock))
return(0); return(0);
else else
return(pc_sec2cluster(pdrive,pobj->blkinfo.my_frstblock)); return(pc_sec2cluster(pdrive,pobj->blkinfo.my_frstblock));
} }
/* Grab a cluster for a new directory entry. /* Grab a cluster for a new directory entry.
To minimize fragmentation give a hint where to start looking for new To minimize fragmentation give a hint where to start looking for new
clusters based on the position of the parent directory */ clusters based on the position of the parent directory */
CLUSTERTYPE pc_alloc_dir(DDRIVE *pdrive, DROBJ *pmom) /* __fatfn__ */ CLUSTERTYPE pc_alloc_dir(DDRIVE *pdrive, DROBJ *pmom) /* __fatfn__ */
{ {
CLUSTERTYPE clbase,cluster; CLUSTERTYPE clbase,cluster;
if ( pdrive->fasize != 8 && pc_isroot(pmom)) if ( pdrive->fasize != 8 && pc_isroot(pmom))
clbase = 0; clbase = 0;
else else
clbase = pc_finode_cluster(pmom->pdrive,pmom->finode); clbase = pc_finode_cluster(pmom->pdrive,pmom->finode);
@ -105,7 +110,7 @@ CLUSTERTYPE clbase,cluster;
CLUSTERTYPE pc_grow_dir(DDRIVE *pdrive, DROBJ *pobj) /* __fatfn__ */ CLUSTERTYPE pc_grow_dir(DDRIVE *pdrive, DROBJ *pobj) /* __fatfn__ */
{ {
CLUSTERTYPE tmpcl, cluster; CLUSTERTYPE tmpcl, cluster;
if ( pdrive->fasize != 8 && pc_isroot(pobj)) if ( pdrive->fasize != 8 && pc_isroot(pobj))
{ {
rtfs_set_errno(PENOSPC); rtfs_set_errno(PENOSPC);
cluster = 0; cluster = 0;
@ -129,7 +134,7 @@ void pc_truncate_dir(DDRIVE *pdrive, DROBJ *pobj, CLUSTERTYPE cluster) /* __fatf
tmpcl = pc_sec2cluster(pdrive, pdrive->rootblock); tmpcl = pc_sec2cluster(pdrive, pdrive->rootblock);
FATOP(pdrive)->fatop_cl_truncate_dir(pdrive, tmpcl, cluster); FATOP(pdrive)->fatop_cl_truncate_dir(pdrive, tmpcl, cluster);
} }
else else
FATOP(pdrive)->fatop_cl_truncate_dir(pdrive, pc_finode_cluster(pdrive,pobj->finode), cluster); FATOP(pdrive)->fatop_cl_truncate_dir(pdrive, pc_finode_cluster(pdrive,pobj->finode), cluster);
} }
@ -161,18 +166,18 @@ BOOLEAN pc_mkfs32(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
for (i=0;i<pfmt->secreserved;i++) for (i=0;i<pfmt->secreserved;i++)
{ {
/* WRITE */ /* WRITE */
if (!devio_write_format(driveno, pfmt->numhide + (dword) i, &(b[0]), 1, use_raw) ) //ctr modified if (!devio_write_format(driveno, (dword) i, &(b[0]), 1, use_raw) )
{ {
goto errex; goto errex;
} }
} }
#if (INCLUDE_FAT32_BOOT_CODE) #if (INCLUDE_FAT32_BOOT_CODE)
copybuff(&b[0],&FAT32_BOOT_CODE[512],512); copybuff(&b[0],&FAT32_BOOT_CODE[512],512);
if (!devio_write_format(driveno, pfmt->numhide + (dword) 8, &(b[0]), 1, use_raw) ) //ctr modified if (!devio_write_format(driveno, (dword) 8, &(b[0]), 1, use_raw) )
{ {
goto errex; goto errex;
} }
if (!devio_write_format(driveno, pfmt->numhide + (dword) 2, &(b[0]), 1, use_raw) ) //ctr modified if (!devio_write_format(driveno, (dword) 2, &(b[0]), 1, use_raw) )
{ {
goto errex; goto errex;
} }
@ -204,14 +209,14 @@ BOOLEAN pc_mkfs32(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
fr_WORD ( &(b[17]), pfmt->numroot); /*X*/ fr_WORD ( &(b[17]), pfmt->numroot); /*X*/
/* total sectors in the volume */ /* total sectors in the volume */
/* Set totsecs to 0 if size > 64k. This triggers sensing huge 4.0 /* Set totsecs to 0 if size > 64k. This triggers sensing huge 4.0
partitions. */ partitions. */
ltotsecs = pfmt->numcyl; ltotsecs = pfmt->numcyl;
ltotsecs *= pfmt->secptrk; ltotsecs *= pfmt->secptrk;
ltotsecs *= pfmt->numhead; ltotsecs *= pfmt->numhead;
ltotsecs -= pfmt->numhide;
if (ltotsecs > 0xffffL) if (ltotsecs > 0xffffL)
{ {
/* HUGE partition the 3.xx totsecs field is zeroed */ /* HUGE partition the 3.xx totsecs field is zeroed */
@ -253,7 +258,7 @@ BOOLEAN pc_mkfs32(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
/* HUGE partition */ /* HUGE partition */
fr_DWORD ( &(b[32]), ltotsecs); /*X*/ fr_DWORD ( &(b[32]), ltotsecs); /*X*/
} }
else else
{ {
fr_DWORD ( &(b[32]), 0L); /*X*/ fr_DWORD ( &(b[32]), 0L); /*X*/
} }
@ -261,13 +266,13 @@ BOOLEAN pc_mkfs32(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
fr_DWORD( &(b[0x43]), pfmt->binary_volume_label); fr_DWORD( &(b[0x43]), pfmt->binary_volume_label);
pc_cppad( &(b[0x47]), (byte*)pfmt->text_volume_label, 11); pc_cppad( &(b[0x47]), (byte*)pfmt->text_volume_label, 11);
pc_cppad( &(b[0x52]), (byte*)"FAT32",8); pc_cppad( &(b[0x52]), (byte*)"FAT32",8);
fr_WORD(&(b[0x01fe]), (word)0xaa55); fr_WORD(&(b[0x01fe]), (word)0xaa55);
/* Count the size of the area managed by the fat. */ /* Count the size of the area managed by the fat. */
ldata_area = ltotsecs; ldata_area = ltotsecs;
ldata_area -= pfmt->numfats * pfmt->secpfat; ldata_area -= pfmt->numfats * pfmt->secpfat;
ldata_area -= pfmt->secreserved; ldata_area -= pfmt->secreserved;
/* Note: numroot must be an even multiple op INOPBLOCK */ /* Note: numroot must be an even multiple op INOPBLOCK */
ldata_area -= pfmt->numroot/INOPBLOCK; ldata_area -= pfmt->numroot/INOPBLOCK;
@ -275,7 +280,7 @@ BOOLEAN pc_mkfs32(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
lnclusters = ldata_area/pfmt->secpalloc; lnclusters = ldata_area/pfmt->secpalloc;
fausize = 8; fausize = 8;
/* Check the FAT. /* Check the FAT.
if ( (nibbles needed) > (nibbles if fatblocks) if ( (nibbles needed) > (nibbles if fatblocks)
trouble; trouble;
*/ */
@ -303,8 +308,8 @@ BOOLEAN pc_mkfs32(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
rtfs_set_errno(PEINVALIDPARMS); rtfs_set_errno(PEINVALIDPARMS);
goto errex; goto errex;
} }
if (!devio_write_format(driveno, (dword) 0 + pfmt->numhide, &(b[0]), 1, use_raw) ) if (!devio_write_format(driveno, 0, &(b[0]), 1, use_raw) )
{ {
goto errex; goto errex;
} }
@ -316,11 +321,11 @@ BOOLEAN pc_mkfs32(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
fr_DWORD( &(b[0x01ec]), (dword)0x00000003); fr_DWORD( &(b[0x01ec]), (dword)0x00000003);
fr_WORD( &(b[0x01fe]), (word)0xaa55); fr_WORD( &(b[0x01fe]), (word)0xaa55);
if (!devio_write_format(driveno, pfmt->numhide + (dword) 7, &(b[0]), 1, use_raw) ) //ctr modified if (!devio_write_format(driveno, (dword) 7, &(b[0]), 1, use_raw) )
{ {
goto errex; goto errex;
} }
if (!devio_write_format(driveno, pfmt->numhide + (dword) 1, &(b[0]), 1, use_raw) ) //ctr modified if (!devio_write_format(driveno, (dword) 1, &(b[0]), 1, use_raw) )
{ {
goto errex; goto errex;
} }
@ -334,7 +339,7 @@ BOOLEAN pc_mkfs32(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
b[2] = (byte) 0xff; b[2] = (byte) 0xff;
j = (word) fausize; j = (word) fausize;
if (j==8) j=12; if (j==8) j=12;
while(j > 3) while(j > 3)
{ {
if (j%4 == 0 && fausize == 8) if (j%4 == 0 && fausize == 8)
b[--j] = (byte) 0x0f; b[--j] = (byte) 0x0f;
@ -342,7 +347,7 @@ BOOLEAN pc_mkfs32(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
b[--j] = (byte) 0xff; b[--j] = (byte) 0xff;
} }
blockno = pfmt->numhide + pfmt->secreserved + (i * pfmt->secpfat); //ctr modified blockno = pfmt->secreserved + (i * pfmt->secpfat);
for ( j = 0; j < pfmt->secpfat; j++) for ( j = 0; j < pfmt->secpfat; j++)
{ {
/* WRITE */ /* WRITE */
@ -354,9 +359,9 @@ BOOLEAN pc_mkfs32(int driveno, FMTPARMS *pfmt, BOOLEAN use_raw)
rtfs_memset(&b[0], 0, 512); rtfs_memset(&b[0], 0, 512);
} }
} }
/* Now write the root sectors */ /* Now write the root sectors */
blockno = pfmt->numhide + pfmt->secreserved + pfmt->numfats * pfmt->secpfat; //ctr modified blockno = pfmt->secreserved + pfmt->numfats * pfmt->secpfat;
rtfs_memset(&b[0], 0, 512); rtfs_memset(&b[0], 0, 512);
/* Bug fix 11-22-99 use <pfmt->secpalloc instead of 8 */ /* Bug fix 11-22-99 use <pfmt->secpalloc instead of 8 */
for(k=0;k<pfmt->secpalloc;k++) /* Is 8 blocks per cluster? */ for(k=0;k<pfmt->secpalloc;k++) /* Is 8 blocks per cluster? */
@ -387,10 +392,9 @@ void pc_pfinode_cluster(DDRIVE *pdr, FINODE *finode, CLUSTERTYPE value) /*__fatf
} }
BOOLEAN pc_gblk0_32(word driveno, struct pcblk0 *pbl0, byte *b) /*__fn__*/ BOOLEAN pc_gblk0_32(word driveno, struct pcblk0 *pbl0, byte *b) /*__fn__*/
{ {
word i;
if (pbl0->numroot == 0) if (pbl0->numroot == 0)
{ {
pbl0->secpfat2 = to_DWORD(b+0x24); pbl0->secpfat2 = to_DWORD(b+0x24);
pbl0->flags = to_WORD(b+0x28); pbl0->flags = to_WORD(b+0x28);
pbl0->fs_version = to_WORD(b+0x2a); pbl0->fs_version = to_WORD(b+0x2a);
pbl0->rootbegin = to_DWORD(b+0x2c); pbl0->rootbegin = to_DWORD(b+0x2c);
@ -401,8 +405,9 @@ BOOLEAN pc_gblk0_32(word driveno, struct pcblk0 *pbl0, byte *b)
{ {
return(FALSE); return(FALSE);
} }
for (i=0; to_DWORD((void *)b) != FSINFOSIG && i<512; b++,i++); /* 3-07-02 - Remove scan to find INFOSIG. Access at offset 484. */
pbl0->free_alloc = to_DWORD((void *)&((struct fat32_info *)b)->free_alloc); b += 484;
pbl0->free_alloc = to_DWORD((void *)&((struct fat32_info *)b)->free_alloc);
pbl0->next_alloc = to_DWORD((void *)&((struct fat32_info *)b)->next_alloc); pbl0->next_alloc = to_DWORD((void *)&((struct fat32_info *)b)->next_alloc);
} }
return(TRUE); return(TRUE);
@ -422,7 +427,6 @@ BOOLEAN pc_validate_partition_type(byte p_type)
BOOLEAN fat_flushinfo(DDRIVE *pdr) /*__fn__*/ BOOLEAN fat_flushinfo(DDRIVE *pdr) /*__fn__*/
{ {
byte *pf; byte *pf;
int j;
BLKBUFF *buf; BLKBUFF *buf;
if (pdr->fasize == 8) if (pdr->fasize == 8)
@ -436,9 +440,14 @@ BOOLEAN fat_flushinfo(DDRIVE *pdr) /*__fn__
} }
/* Merge in the new values */ /* Merge in the new values */
pf = buf->data; /* Now we do not have to use the stack */ pf = buf->data; /* Now we do not have to use the stack */
for (j=0; to_DWORD(pf)!=FSINFOSIG && j<512; pf++,j++); /* 3-07-02 - Remove scan to find INFOSIG. Access at offset 484. */
pf += 484;
fr_DWORD((byte *) (&((struct fat32_info *)pf)->free_alloc), pdr->known_free_clusters ); fr_DWORD((byte *) (&((struct fat32_info *)pf)->free_alloc), pdr->known_free_clusters );
fr_DWORD((byte *) (&((struct fat32_info *)pf)->next_alloc), pdr->free_contig_pointer ); /* fr_DWORD((byte *) (&((struct fat32_info *)pf)->next_alloc), pdr->free_contig_pointer ); */
/* 2-10-2007 - put free_contig_base in allocation hint field. This forces cluster
allocations to initially scan from the base of the FAT for free clusters rather
than from the previous "most likely" location */
fr_DWORD((byte *) (&((struct fat32_info *)pf)->next_alloc), pdr->free_contig_base );
/* Use write_blk, to take advantage of the failsafe cache */ /* Use write_blk, to take advantage of the failsafe cache */
if (!pc_write_blk(buf)) if (!pc_write_blk(buf))
{ {
@ -462,7 +471,7 @@ byte * fatxx_pfswap(DDRIVE *pdr, CLUSTERTYPE index, BOOLEAN for_write);
BOOLEAN fatxx_pfpdword(DDRIVE *pdr, dword index, dword *pvalue) /*__fatfn__*/ BOOLEAN fatxx_pfpdword(DDRIVE *pdr, dword index, dword *pvalue) /*__fatfn__*/
{ {
dword *ppage; dword *ppage;
dword offset; dword offset;
/* Make sure we have access to the page. Mark it for writing */ /* Make sure we have access to the page. Mark it for writing */
ppage = (dword *)fatxx_pfswap(pdr,index,TRUE); ppage = (dword *)fatxx_pfswap(pdr,index,TRUE);
@ -482,7 +491,7 @@ BOOLEAN fatxx_pfpdword(DDRIVE *pdr, dword index, dword *pvalue) /*__fat
BOOLEAN fatxx_pfgdword(DDRIVE *pdr, dword index, dword *value) /*__fatfn__*/ BOOLEAN fatxx_pfgdword(DDRIVE *pdr, dword index, dword *value) /*__fatfn__*/
{ {
dword *ppage; dword *ppage;
dword offset; dword offset;
/* Make sure we have access to the page. Do not Mark it for writing */ /* Make sure we have access to the page. Do not Mark it for writing */
ppage = (dword *)fatxx_pfswap(pdr,index,FALSE); ppage = (dword *)fatxx_pfswap(pdr,index,FALSE);
@ -499,4 +508,3 @@ BOOLEAN fatxx_pfgdword(DDRIVE *pdr, dword index, dword *value) /*__fatf
#endif #endif

View File

@ -6,7 +6,7 @@
* This code may not be redistributed in source or linkable object form * This code may not be redistributed in source or linkable object form
* without the consent of its author. * without the consent of its author.
*/ */
/* RTFATXX.C - Low level File allocation table management functions. /* RTFATXX.C - Low level File allocation table management functions.
Routines in this file include: Routines in this file include:
@ -24,7 +24,7 @@
fatxx_pfaxx - Put a value to the FAT. fatxx_pfaxx - Put a value to the FAT.
fatxx_pfswap - Swap a block of the FAT into the cache. fatxx_pfswap - Swap a block of the FAT into the cache.
fatxx_fword - Get or put a value from the swap cache. fatxx_fword - Get or put a value from the swap cache.
*/ */
@ -53,7 +53,7 @@ BOOLEAN fatxx_pfgdword(DDRIVE *pdr, dword index, dword *value);
return the number of contiguous clusters reserved. return the number of contiguous clusters reserved.
If pstart_cluster points to a valid cluster and dolink is true If pstart_cluster points to a valid cluster and dolink is true
then link the new chain to it. then link the new chain to it.
Returns Returns
Returns the number of contiguous clusters found. Or zero on an error. Returns the number of contiguous clusters found. Or zero on an error.
pstart_cluster contains the address of the start of the chain on pstart_cluster contains the address of the start of the chain on
@ -74,7 +74,7 @@ CLUSTERTYPE fatxx_alloc_chain(DDRIVE *pdr, CLUSTERTYPE *pstart_cluster, CLUSTERT
is_error = 0; is_error = 0;
start_cluster = *pstart_cluster; start_cluster = *pstart_cluster;
if (start_cluster && if (start_cluster &&
( (start_cluster < 2) || (start_cluster > pdr->maxfindex) ) ) ( (start_cluster < 2) || (start_cluster > pdr->maxfindex) ) )
{ {
rtfs_set_errno(PEINVALIDCLUSTER); /* fatxx_alloc_chain: bad cluster value internal error */ rtfs_set_errno(PEINVALIDCLUSTER); /* fatxx_alloc_chain: bad cluster value internal error */
@ -82,7 +82,7 @@ CLUSTERTYPE fatxx_alloc_chain(DDRIVE *pdr, CLUSTERTYPE *pstart_cluster, CLUSTERT
} }
/* If the user provided a cluster we find the next cluster beyond that /* If the user provided a cluster we find the next cluster beyond that
one. Otherwise we look at the disk structure and find the next one. Otherwise we look at the disk structure and find the next
free cluster in the free cluster region after the current best guess free cluster in the free cluster region after the current best guess
of the region. If that fails we look to the beginning of the region of the region. If that fails we look to the beginning of the region
and if that fails we look in the non-contiguous region. */ and if that fails we look in the non-contiguous region. */
@ -108,9 +108,9 @@ CLUSTERTYPE fatxx_alloc_chain(DDRIVE *pdr, CLUSTERTYPE *pstart_cluster, CLUSTERT
if (!clno) if (!clno)
{ {
/* NEW */ /* NEW */
if (!start_cluster || start_cluster >= pdr->free_contig_pointer) if (!start_cluster || start_cluster >= pdr->free_contig_pointer)
{ {
/* search from free_contig_pointer to start_cluster or maxfindex whichever /* search from free_contig_pointer to start_cluster or maxfindex whichever
is less */ is less */
clno = fatxx_find_free_cluster(pdr, pdr->free_contig_pointer, last_cluster, &is_error); clno = fatxx_find_free_cluster(pdr, pdr->free_contig_pointer, last_cluster, &is_error);
if (is_error) /* Error reading fat */ if (is_error) /* Error reading fat */
@ -124,7 +124,7 @@ CLUSTERTYPE fatxx_alloc_chain(DDRIVE *pdr, CLUSTERTYPE *pstart_cluster, CLUSTERT
{ {
/* NEW */ /* NEW */
if (!start_cluster || start_cluster > pdr->free_contig_base) if (!start_cluster || start_cluster > pdr->free_contig_base)
/* search from free_contig_base to start_cluster or free_contig_pointer whichever /* search from free_contig_base to start_cluster or free_contig_pointer whichever
is less */ is less */
clno = fatxx_find_free_cluster(pdr, pdr->free_contig_base, last_cluster, &is_error); clno = fatxx_find_free_cluster(pdr, pdr->free_contig_base, last_cluster, &is_error);
if (is_error) /* Error reading fat */ if (is_error) /* Error reading fat */
@ -206,7 +206,7 @@ CLUSTERTYPE value;
*is_error = 0; *is_error = 0;
for (i = startpt; i < endpt; i++) for (i = startpt; i < endpt; i++)
{ {
if ( !fatxx_faxx(pdr, i, &value) ) if ( !fatxx_faxx(pdr, i, &value) )
{ {
*is_error = 1; *is_error = 1;
return(0); return(0);
@ -224,9 +224,9 @@ CLUSTERTYPE value;
PC_CLALLOC - Reserve and return the next free cluster on a drive PC_CLALLOC - Reserve and return the next free cluster on a drive
Description Description
Given a DDRIVE, mark the next available cluster in the file allocation Given a DDRIVE, mark the next available cluster in the file allocation
table as used and return the associated cluster number. Clhint provides table as used and return the associated cluster number. Clhint provides
a means of selecting clusters that are near eachother. This should a means of selecting clusters that are near eachother. This should
reduce fragmentation. reduce fragmentation.
NOTE: This routine is used to allocate single cluster chunks for NOTE: This routine is used to allocate single cluster chunks for
@ -234,9 +234,9 @@ CLUSTERTYPE value;
two regions. The first region is where single clusters chunks two regions. The first region is where single clusters chunks
used in directory files come from. These are allocated by this used in directory files come from. These are allocated by this
routine only. Data file clusters are allocated by fatxx_alloc_chain. routine only. Data file clusters are allocated by fatxx_alloc_chain.
THE DISK IS NOT REALLY PARTITIONED. If this routine runs out of THE DISK IS NOT REALLY PARTITIONED. If this routine runs out of
space in the first region it grabs a cluster from the second space in the first region it grabs a cluster from the second
region. region.
Returns Returns
Return a new cluster number or 0 if the disk is full. Return a new cluster number or 0 if the disk is full.
@ -295,7 +295,7 @@ CLUSTERTYPE fatxx_clalloc(DDRIVE *pdr, CLUSTERTYPE clhint) /
by allocating a new cluster and linking clno to it. If clno is zero by allocating a new cluster and linking clno to it. If clno is zero
assume it is the start of a new file and allocate a new cluster. assume it is the start of a new file and allocate a new cluster.
Note: The chain is traversed to the end before linking in the new Note: The chain is traversed to the end before linking in the new
cluster. The new cluster terminates the chain. cluster. The new cluster terminates the chain.
Returns Returns
Return a new cluster number or 0 if the disk is full. Return a new cluster number or 0 if the disk is full.
@ -320,7 +320,7 @@ CLUSTERTYPE fatxx_clgrow(DDRIVE *pdr, CLUSTERTYPE clno) /
nextcluster = fatxx_clnext(pdr , clno); nextcluster = fatxx_clnext(pdr , clno);
while (nextcluster != 0xffffffff && ++range_check < MAX_CLUSTERS_PER_DIR) while (nextcluster != 0xffffffff && ++range_check < MAX_CLUSTERS_PER_DIR)
{ {
if (!nextcluster) /* fatxx_clnext - set errno */ if (!nextcluster) /* fatxx_clnext - set errno */
return (0); return (0);
clno = nextcluster; clno = nextcluster;
nextcluster = fatxx_clnext(pdr , clno); nextcluster = fatxx_clnext(pdr , clno);
@ -356,15 +356,15 @@ CLUSTERTYPE fatxx_clgrow(DDRIVE *pdr, CLUSTERTYPE clno) /
***************************************************************************/ ***************************************************************************/
/* Return a cluster to the free list */ /* Return a cluster to the free list */
/* Note: The caller locks the fat before calling this routine */ /* Note: The caller locks the fat before calling this routine */
BOOLEAN fatxx_clrelease_dir(DDRIVE *pdr, CLUSTERTYPE clno) /*__fatfn__*/ BOOLEAN fatxx_clrelease_dir(DDRIVE *pdr, CLUSTERTYPE clno) /*__fatfn__*/
{ {
int current_errno; int current_errno;
/* This is a cleanup routine, an earlier event is the interesting errno /* This is a cleanup routine, an earlier event is the interesting errno
to the application, so we restore errno if we fail */ to the application, so we restore errno if we fail */
current_errno = get_errno(); current_errno = get_errno();
/* No need to check clno value, pfaxx will catch it */ /* No need to check clno value, pfaxx will catch it */
/* Do not catch any lower level errors here. You will catch them soon enough */ /* Do not catch any lower level errors here. You will catch them soon enough */
@ -513,8 +513,8 @@ CLUSTERTYPE fatxx_cl_truncate_dir(DDRIVE *pdr, CLUSTERTYPE cluster, CLUSTERTYPE
{ /* Don't set errno in this function, it is a cleanup */ { /* Don't set errno in this function, it is a cleanup */
return (0); return (0);
} }
/* This is a cleanup routine, an earlier event is the interesting errno /* This is a cleanup routine, an earlier event is the interesting errno
to the application, so we restore errno if we fail */ to the application, so we restore errno if we fail */
current_errno = get_errno(); current_errno = get_errno();
nextcluster = fatxx_clnext(pdr , cluster); nextcluster = fatxx_clnext(pdr , cluster);
@ -553,16 +553,16 @@ CLUSTERTYPE fatxx_cl_truncate_dir(DDRIVE *pdr, CLUSTERTYPE cluster, CLUSTERTYPE
/****************************************************************************** /******************************************************************************
PC_PFAXXTERM - Write a terminating value to the FAT at clno. PC_PFAXXTERM - Write a terminating value to the FAT at clno.
Description Description
Given a DDRIVE,cluster number and value. Write the value 0xffffffff or Given a DDRIVE,cluster number and value. Write the value 0xffffffff or
0xffff in the fat at clusterno. Handle 32, 16 and 12 bit fats correctly. 0xffff in the fat at clusterno. Handle 32, 16 and 12 bit fats correctly.
Returns Returns
FALSE if an io error occurred during fat swapping, else TRUE FALSE if an io error occurred during fat swapping, else TRUE
*****************************************************************************/ *****************************************************************************/
/* Given a clno & fatval Put the value in the table at the index (clno) */ /* Given a clno & fatval Put the value in the table at the index (clno) */
/* Note: The caller locks the fat before calling this routine */ /* Note: The caller locks the fat before calling this routine */
BOOLEAN fatxx_pfaxxterm(DDRIVE *pdr, CLUSTERTYPE clno) /*__fatfn__*/ BOOLEAN fatxx_pfaxxterm(DDRIVE *pdr, CLUSTERTYPE clno) /*__fatfn__*/
@ -573,11 +573,11 @@ BOOLEAN fatxx_pfaxxterm(DDRIVE *pdr, CLUSTERTYPE clno) /*__fatfn_
else else
#endif #endif
return(fatxx_pfaxx(pdr, clno, 0xffff)); return(fatxx_pfaxx(pdr, clno, 0xffff));
} }
/****************************************************************************** /******************************************************************************
PC_PFAXX - Write a value to the FAT at clno. PC_PFAXX - Write a value to the FAT at clno.
Description Description
Given a DDRIVE,cluster number and value. Write the value in the fat Given a DDRIVE,cluster number and value. Write the value in the fat
at clusterno. Handle 16 and 12 bit fats correctly. at clusterno. Handle 16 and 12 bit fats correctly.
@ -586,7 +586,7 @@ BOOLEAN fatxx_pfaxxterm(DDRIVE *pdr, CLUSTERTYPE clno) /*__fatfn_
No if an io error occurred during fat swapping, else TRUE. No if an io error occurred during fat swapping, else TRUE.
*****************************************************************************/ *****************************************************************************/
/* Given a clno & fatval Put the value in the table at the index (clno) */ /* Given a clno & fatval Put the value in the table at the index (clno) */
/* Note: The caller locks the fat before calling this routine */ /* Note: The caller locks the fat before calling this routine */
BOOLEAN fatxx_pfaxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE value) /*__fatfn__*/ BOOLEAN fatxx_pfaxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE value) /*__fatfn__*/
@ -631,9 +631,9 @@ BOOLEAN fatxx_pfaxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE value)
/* /*
| W0 | W1 | W2 | | W0 | W1 | W2 |
A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1 A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
xx xx xx xx xx xx
*/ */
else if (offset == 1) /* (B1 B2 << 4) | B0 */ else if (offset == 1) /* (B1 B2 << 4) | B0 */
{ {
/* Hi nibble of b[1] is lo nibble of value */ /* Hi nibble of b[1] is lo nibble of value */
@ -653,9 +653,9 @@ BOOLEAN fatxx_pfaxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE value)
/* /*
| W0 | W1 | W2 | | W0 | W1 | W2 |
A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1 A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
xx xx xx xx xx xx
*/ */
else if (offset == 2) /*(C2 << 8) | C1 C2 */ else if (offset == 2) /*(C2 << 8) | C1 C2 */
{ {
/* b[1] = low byte of value */ /* b[1] = low byte of value */
@ -677,8 +677,8 @@ BOOLEAN fatxx_pfaxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE value)
A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1 A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
xx xx xx xx xx xx
*/ */
else if (offset == 3) /* (D2 D1) << 4 | D0 */ else if (offset == 3) /* (D2 D1) << 4 | D0 */
{ {
/* Hi nibble b[0] == low nible of value */ /* Hi nibble b[0] == low nible of value */
u.wrdbuf[0] &= 0x0f; u.wrdbuf[0] &= 0x0f;
@ -716,10 +716,10 @@ BOOLEAN fatxx_pfaxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE value)
/*************************************************************************** /***************************************************************************
PC_CLNEXT - Return the next cluster in a cluster chain PC_CLNEXT - Return the next cluster in a cluster chain
Description Description
Given a DDRIVE and a cluster number, return the next cluster in the Given a DDRIVE and a cluster number, return the next cluster in the
chain containing clno. Return 0 on end of chain. chain containing clno. Return 0 on end of chain.
Returns Returns
@ -749,20 +749,27 @@ CLUSTERTYPE fatxx_clnext(DDRIVE *pdr, CLUSTERTYPE clno)
{ {
_Oxffffffful = 0x0ffffffful; _Oxffffffful = 0x0ffffffful;
nxt &= _Oxffffffful; nxt &= _Oxffffffful;
if ( nxt == 0x0ffffffful ) /* Bug fix 2-01-2007 - fatxx_clnext() changed to detect terminate
nxt = 0xffffffff; /* end of chain */ on cluster value > xxfff7. Was expecting xxffff */
if ( (nxt > 0x0ffffff7ul) && (nxt <= 0x0ffffffful) )
nxt = 0xffffffff;
} }
else else
#endif #endif
{ {
#if (FAT32) #if (FAT32)
if ( (nxt >= (CLUSTERTYPE)0xfff7) && (nxt <= (CLUSTERTYPE)0xffff) ) /* Bug fix 2-01-2007 - fatxx_clnext() changed to detect terminate
on cluster value > xxfff7. Was expecting xxffff */
if ( (nxt > (CLUSTERTYPE)0xfff7) && (nxt <= (CLUSTERTYPE)0xffff) )
#else #else
/* If fat32 is not defined the nxt is always <= 0xffff. picky compilers /* If fat32 is not defined the nxt is always <= 0xffff. picky compilers
notice this and emit a warning */ notice this and emit a warning */
if (nxt >= (CLUSTERTYPE)0xfff7) /* Bug fix 2-01-2007 - fatxx_clnext() changed to detect terminate
on cluster value > xxfff7. Was expecting xxffff */
if (nxt > (CLUSTERTYPE)0xfff7)
#endif #endif
nxt = 0xffffffff; /* end of chain */ nxt = 0xffffffff; /* end of chain */
} }
if (nxt != 0xffffffff && (nxt < 2 || nxt > pdr->maxfindex) ) if (nxt != 0xffffffff && (nxt < 2 || nxt > pdr->maxfindex) )
{ {
@ -780,10 +787,10 @@ CLUSTERTYPE fatxx_clnext(DDRIVE *pdr, CLUSTERTYPE clno)
(the next cluster in a chain.) Handle 16 and 12 bit fats correctly. (the next cluster in a chain.) Handle 16 and 12 bit fats correctly.
Returns Returns
Returns the the value at clno. In pvalue. Returns the the value at clno. In pvalue.
If any error occured while FAT swapping return FALSE else return TRUE. If any error occured while FAT swapping return FALSE else return TRUE.
***************************************************************************/ ***************************************************************************/
/* Retrieve a value from the fat */ /* Retrieve a value from the fat */
BOOLEAN fatxx_faxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE *pvalue) /*__fatfn__*/ BOOLEAN fatxx_faxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE *pvalue) /*__fatfn__*/
{ {
@ -827,9 +834,9 @@ BOOLEAN fatxx_faxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE *pvalue)
/* /*
| W0 | W1 | W2 | | W0 | W1 | W2 |
A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1 A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
xx xx xx xx xx xx
*/ */
else if (offset == 1) /* (B1 B2 << 4) | B0 */ else if (offset == 1) /* (B1 B2 << 4) | B0 */
{ {
/* BYTE 2 == High byte Byte 1 high nibb == low nib */ /* BYTE 2 == High byte Byte 1 high nibb == low nib */
@ -843,7 +850,7 @@ BOOLEAN fatxx_faxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE *pvalue)
/* /*
| W0 | W1 | W2 | | W0 | W1 | W2 |
A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1 A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
xx xx xx xx xx xx
*/ */
else if (offset == 2) /*(C2 << 8) | C1 C2 */ else if (offset == 2) /*(C2 << 8) | C1 C2 */
{ {
@ -859,8 +866,8 @@ BOOLEAN fatxx_faxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE *pvalue)
A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1 A1 A0 B0 A2 B2 B1 C1 C0 D0 C2 D2 D1
xx xx xx xx xx xx
*/ */
else if (offset == 3) /* (D2 D1) << 4 | D0 */ else if (offset == 3) /* (D2 D1) << 4 | D0 */
{ {
result = u.wrdbuf[1]; result = u.wrdbuf[1];
result <<= 4; result <<= 4;
@ -877,7 +884,7 @@ BOOLEAN fatxx_faxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE *pvalue)
return (FALSE); return (FALSE);
#else #else
if ( fatxx_pfgdword( pdr, clno, (dword *) &u.wrdbuf[0] )) if ( fatxx_pfgdword( pdr, clno, (dword *) &u.wrdbuf[0] ))
result = (CLUSTERTYPE) to_DWORD(&u.wrdbuf[0]); result = (CLUSTERTYPE) to_DWORD(&u.wrdbuf[0]);
else else
return (FALSE); return (FALSE);
#endif #endif
@ -904,7 +911,7 @@ BOOLEAN fatxx_faxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE *pvalue)
Starting at start_cluster return the number of contiguous clusters Starting at start_cluster return the number of contiguous clusters
allocated in the chain containing start_cluster or n_clusters, allocated in the chain containing start_cluster or n_clusters,
whichever is less. whichever is less.
Returns Returns
Returns the number of contiguous clusters found. Or zero on an error. Returns the number of contiguous clusters found. Or zero on an error.
This function should always return at least one. (start_cluster). Unless This function should always return at least one. (start_cluster). Unless
@ -915,7 +922,7 @@ BOOLEAN fatxx_faxx(DDRIVE *pdr, CLUSTERTYPE clno, CLUSTERTYPE *pvalue)
the first cluster in the next segment of the chain. the first cluster in the next segment of the chain.
. If we are still in a section it contains . If we are still in a section it contains
the next cluster in the current segment of the chain. the next cluster in the current segment of the chain.
. If we are at the end of the chain it contains the last cluster . If we are at the end of the chain it contains the last cluster
in the chain. in the chain.
****************************************************************************/ ****************************************************************************/
@ -930,8 +937,8 @@ CLUSTERTYPE fatxx_get_chain(DDRIVE *pdr, CLUSTERTYPE start_cluster, CLUSTERTYPE
value = 0; value = 0;
clno = start_cluster; clno = start_cluster;
n_contig = 1; n_contig = 1;
*pnext_cluster = 0; *pnext_cluster = 0;
/* Get each FAT entry. If its value points to the next contiguous entry /* Get each FAT entry. If its value points to the next contiguous entry
continue. Otherwise we have reached the end of the contiguous chain. continue. Otherwise we have reached the end of the contiguous chain.
At which point we return the number of contig s found and by reference At which point we return the number of contig s found and by reference
@ -939,11 +946,11 @@ CLUSTERTYPE fatxx_get_chain(DDRIVE *pdr, CLUSTERTYPE start_cluster, CLUSTERTYPE
*/ */
*end_of_chain = 0; *end_of_chain = 0;
for (;;) for (;;)
{ {
next_cluster = fatxx_clnext(pdr, clno); next_cluster = fatxx_clnext(pdr, clno);
if (!next_cluster) /* clnext detected an error */ if (!next_cluster) /* clnext detected an error */
return(0); return(0);
/* check for end markers set next cluster to the last /* check for end markers set next cluster to the last
cluster in the chain if we are at the end */ cluster in the chain if we are at the end */
if (next_cluster == 0xffffffff) /* clnext detected end */ if (next_cluster == 0xffffffff) /* clnext detected end */
{ {
@ -969,16 +976,16 @@ CLUSTERTYPE fatxx_get_chain(DDRIVE *pdr, CLUSTERTYPE start_cluster, CLUSTERTYPE
} }
/*************************************************************************** /***************************************************************************
PC_FATSW - Map in a page of the FAT PC_FATSW - Map in a page of the FAT
****************************************************************************/ ****************************************************************************/
/* Swap in the page containing index */ /* Swap in the page containing index */
/* Note: The caller locks the fat before calling this routine */ /* Note: The caller locks the fat before calling this routine */
byte * fatxx_pfswap(DDRIVE *pdr, CLUSTERTYPE index, BOOLEAN for_write) /*__fatfn__*/ byte * fatxx_pfswap(DDRIVE *pdr, CLUSTERTYPE index, BOOLEAN for_write) /*__fatfn__*/
{ {
dword block_offset_in_fat; dword block_offset_in_fat;
dword flags; dword flags;
if (pdr->fasize == 8) if (pdr->fasize == 8)
block_offset_in_fat = (dword)(index >> 7); block_offset_in_fat = (dword)(index >> 7);
else else
@ -997,7 +1004,7 @@ byte * fatxx_pfswap(DDRIVE *pdr, CLUSTERTYPE index, BOOLEAN for_write) /
BOOLEAN fatxx_fword(DDRIVE *pdr, CLUSTERTYPE index, word *pvalue, BOOLEAN putting) /*__fatfn__*/ BOOLEAN fatxx_fword(DDRIVE *pdr, CLUSTERTYPE index, word *pvalue, BOOLEAN putting) /*__fatfn__*/
{ {
word *ppage; word *ppage;
word offset; word offset;
/* Make sure we have access to the page. Mark it for writing (if a put) */ /* Make sure we have access to the page. Mark it for writing (if a put) */
ppage = (word *)fatxx_pfswap(pdr,index,putting); ppage = (word *)fatxx_pfswap(pdr,index,putting);
@ -1020,8 +1027,6 @@ FAT_DRIVER fatxx_d;
static BOOLEAN init_fat(DDRIVE *pdr) static BOOLEAN init_fat(DDRIVE *pdr)
{ {
FAT_DRIVER *pfd; FAT_DRIVER *pfd;
/* int driveno;
driveno = pdr->driveno;*/
pfd = &fatxx_d; pfd = &fatxx_d;
pfd->fatop_alloc_chain = fatxx_alloc_chain; pfd->fatop_alloc_chain = fatxx_alloc_chain;
pfd->fatop_clnext = fatxx_clnext; pfd->fatop_clnext = fatxx_clnext;
@ -1068,4 +1073,3 @@ BOOLEAN init_fat12(DDRIVE *pdr)
} }

View File

@ -2,9 +2,9 @@
* rtkernfn.c - Miscelaneous portable functions * rtkernfn.c - Miscelaneous portable functions
* *
* ERTFS portable process management and other functions. * ERTFS portable process management and other functions.
* This file is portable but it requires interaction with the * This file is portable but it requires interaction with the
* porting layer functions in portrtfs.c. * porting layer functions in portrtfs.c.
* *
* Copyright EBS Inc. 1987-2003 * Copyright EBS Inc. 1987-2003
* All rights reserved. * All rights reserved.
* This code may not be redistributed in source or linkable object form * This code may not be redistributed in source or linkable object form
@ -33,7 +33,7 @@ BOOLEAN rtfs_resource_init(void) /*__fn__*/
PRTFS_SYSTEM_USER rtfs_get_system_user(void) PRTFS_SYSTEM_USER rtfs_get_system_user(void)
{ {
int i; int i,j;
dword t; dword t;
t = rtfs_port_get_taskid(); t = rtfs_port_get_taskid();
@ -58,6 +58,17 @@ return_it:
} }
/* We are out of user structures so use element 0 */ /* We are out of user structures so use element 0 */
i = 0; i = 0;
/* Bug fix 02-01-2007 - If we are using the default user (0), make sure the
current working directory objects are freed and the finode access counts
are reduced */
for(j = 0; j < prtfs_cfg->cfg_NDRIVES; j++)
{
if(prtfs_cfg->rtfs_user_table[i].lcwd[j])
{
pc_freeobj((DROBJ *) prtfs_cfg->rtfs_user_table[i].lcwd[j]);
prtfs_cfg->rtfs_user_table[i].lcwd[j] = 0;
}
}
goto return_it; goto return_it;
} }
@ -84,10 +95,10 @@ PRTFS_SYSTEM_USER s;
* *
* This routine is called by RTFS when it closes a drive. * This routine is called by RTFS when it closes a drive.
* The routine must release the current directory object for that drive * The routine must release the current directory object for that drive
* for each user. If a user does not have a CWD for the drive it should * for each user. If a user does not have a CWD for the drive it should
* not call pc_freeobj. * not call pc_freeobj.
* *
* In the reference port we cycle through our array of user structures * In the reference port we cycle through our array of user structures
* to provide the enumeration. Other implementations are equally valid. * to provide the enumeration. Other implementations are equally valid.
*/ */
@ -118,24 +129,24 @@ int i;
/* int rtfs_set_driver_errno() - set device driver errno for the calling task /* int rtfs_set_driver_errno() - set device driver errno for the calling task
Saves driver errno for the calling task in array based on callers taskid. Saves driver errno for the calling task in array based on callers taskid.
Note: This routine must not be called from the interrupt service layer Note: This routine must not be called from the interrupt service layer
Returns nothing Returns nothing
*/ */
void rtfs_set_driver_errno(dword error) /*__fn__*/ void rtfs_set_driver_errno(dword error) /*__fn__*/
{ {
rtfs_get_system_user()->rtfs_driver_errno = error; rtfs_get_system_user()->rtfs_driver_errno = error;
} }
/* ********************************************************************
dword rtfs_get_driver_errno() - get device driver errno for the calling task
Returns device driver errno for the calling task in array based on /* ********************************************************************
callers taskid.
dword rtfs_get_driver_errno() - get device driver errno for the calling task
Returns device driver errno for the calling task in array based on
callers taskid.
*/ */
dword rtfs_get_driver_errno(void) /*__fn__*/ dword rtfs_get_driver_errno(void) /*__fn__*/
@ -146,9 +157,9 @@ dword rtfs_get_driver_errno(void) /*__fn__*/
/* int rtfs_set_errno() - set errno for the calling task /* int rtfs_set_errno() - set errno for the calling task
Saves errno for the calling task in array based on callers taskid. Saves errno for the calling task in array based on callers taskid.
Returns -1 Returns -1
*/ */
int rtfs_set_errno(int error) /*__fn__*/ int rtfs_set_errno(int error) /*__fn__*/
{ {
@ -156,12 +167,12 @@ int rtfs_set_errno(int error) /*__fn__*/
return(-1); return(-1);
} }
/* ********************************************************************
int get_errno() - get errno for the calling task
Returns errno for the calling task in array based on callers taskid. /* ********************************************************************
int get_errno() - get errno for the calling task
Returns errno for the calling task in array based on callers taskid.
*/ */
int get_errno(void) /*__fn__*/ int get_errno(void) /*__fn__*/
@ -177,19 +188,19 @@ void pc_report_error(int error_number) /*__fn__*/
RTFS_PRINT_LONG_1((dword) error_number, PRFLG_NL); RTFS_PRINT_LONG_1((dword) error_number, PRFLG_NL);
} }
/* This routine will be called if an IO error occurs. It must return /* This routine will be called if an IO error occurs. It must return
either CRITICAL_ERROR_ABORT to have the operation aborted and either CRITICAL_ERROR_ABORT to have the operation aborted and
the drive to be unmounted or CRITICAL_ERROR_RETRY to force a retry the drive to be unmounted or CRITICAL_ERROR_RETRY to force a retry
of the operation. of the operation.
This routine prompts the user to Abort or Retry. If console input This routine prompts the user to Abort or Retry. If console input
is not implemented it return Abort. This routine may be modified is not implemented it return Abort. This routine may be modified
to take corrective action (such as ask the user to reinsert the media) to take corrective action (such as ask the user to reinsert the media)
before return Retry or Abort before return Retry or Abort
*/ */
KS_CONSTANT int med_st[] = KS_CONSTANT int med_st[] =
{ {
USTRING_SYS_NULL, /* "" */ USTRING_SYS_NULL, /* "" */
USTRING_CRITERR_02, /* "BAD_FORMAT" */ USTRING_CRITERR_02, /* "BAD_FORMAT" */
USTRING_CRITERR_03, /* "CRERR_NO_CARD" */ USTRING_CRITERR_03, /* "CRERR_NO_CARD" */
@ -217,7 +228,7 @@ BOOLEAN needs_flush;
needs_flush = FALSE; needs_flush = FALSE;
RTFS_PRINT_STRING_1(USTRING_CRITERR_07,0); /* "Media status == " */ RTFS_PRINT_STRING_1(USTRING_CRITERR_07,0); /* "Media status == " */
RTFS_PRINT_STRING_1(med_st[media_status],PRFLG_NL); RTFS_PRINT_STRING_1(med_st[media_status],PRFLG_NL);
RTFS_PRINT_STRING_2(USTRING_CRITERR_08, pdr->volume_label, PRFLG_NL); /* "Volume == " */ RTFS_PRINT_STRING_2(USTRING_CRITERR_08, pdr->volume_label, PRFLG_NL); /* "Volume == " */
if (needs_flush) if (needs_flush)
@ -231,7 +242,7 @@ BOOLEAN needs_flush;
CS_OP_ASSIGN_ASCII(p,'A'); CS_OP_ASSIGN_ASCII(p,'A');
CS_OP_INC_PTR(p); CS_OP_INC_PTR(p);
CS_OP_TERM_STRING(p); CS_OP_TERM_STRING(p);
return (CRITICAL_ERROR_ABORT); /* ctr modified */ return( CRITICAL_ERROR_ABORT); /* ctr modified */
// for (;;) // for (;;)
// { // {
// /* "Type A to abort R to Retry" */ // /* "Type A to abort R to Retry" */
@ -247,7 +258,7 @@ BOOLEAN needs_flush;
PC_NUM_DRIVES - Return total number of drives in the system PC_NUM_DRIVES - Return total number of drives in the system
Description Description
This routine returns the number of drives in the system This routine returns the number of drives in the system
Returns Returns
The number The number
@ -261,7 +272,7 @@ int pc_num_drives(void) /* __fn__ */
PC_NUSERFILES - Return total number of uses allowed in the system PC_NUSERFILES - Return total number of uses allowed in the system
Description Description
This routine returns the number of user in the system This routine returns the number of user in the system
Returns Returns
The number The number
@ -275,7 +286,7 @@ int pc_num_users(void) /* __fn__ */
PC_NUSERFILES - Return total number of userfiles alloed in the system PC_NUSERFILES - Return total number of userfiles alloed in the system
Description Description
This routine returns the number of user files in the system This routine returns the number of user files in the system
Returns Returns
The number The number
@ -318,7 +329,7 @@ BOOLEAN pc_validate_driveno(int driveno) /* __fn__ */
memory management this way to provide maximum flexibility for embedded memory management this way to provide maximum flexibility for embedded
system developers. In the reference port we use malloc to allocate the system developers. In the reference port we use malloc to allocate the
various chunks of memory we need, but we could just have easily comiled various chunks of memory we need, but we could just have easily comiled
the tables into the BSS section of the program. the tables into the BSS section of the program.
Use whatever method makes sense in you system. Use whatever method makes sense in you system.
@ -359,18 +370,18 @@ BOOLEAN pc_memory_init(void) /*__
return(FALSE); return(FALSE);
/* Initialize buffer pools for each drive */ /* Initialize buffer pools for each drive */
for (pdrive=prtfs_cfg->mem_drives_structures,i = 0; for (pdrive=prtfs_cfg->mem_drives_structures,i = 0;
i < prtfs_cfg->cfg_NDRIVES; i++, pdrive++) i < prtfs_cfg->cfg_NDRIVES; i++, pdrive++)
{ {
/* Use the globally shared block buffer pool. /* Use the globally shared block buffer pool.
this can be overriden through the API to assign a private buffer pool to the drive */ this can be overriden through the API to assign a private buffer pool to the drive */
pdrive->pbuffcntxt = &prtfs_cfg->buffcntxt; pdrive->pbuffcntxt = &prtfs_cfg->buffcntxt;
/* Initialize the fat block buffer array */ /* Initialize the fat block buffer array */
if (!pc_initialize_fat_block_pool( if (!pc_initialize_fat_block_pool(
&pdrive->fatcontext, &pdrive->fatcontext,
prtfs_cfg->cfg_FAT_BUFFER_SIZE[i], prtfs_cfg->fat_buffers[i], prtfs_cfg->cfg_FAT_BUFFER_SIZE[i], prtfs_cfg->fat_buffers[i],
prtfs_cfg->cfg_FAT_HASHTBL_SIZE[i], prtfs_cfg->fat_hash_table[i], prtfs_cfg->cfg_FAT_HASHTBL_SIZE[i], prtfs_cfg->fat_hash_table[i],
prtfs_cfg->fat_primary_cache[i], prtfs_cfg->fat_primary_index[i])) prtfs_cfg->fat_primary_cache[i], prtfs_cfg->fat_primary_index[i]))
return(FALSE); return(FALSE);
@ -380,7 +391,7 @@ BOOLEAN pc_memory_init(void) /*__
DROBJ memory allocator routine. */ DROBJ memory allocator routine. */
pobj = prtfs_cfg->mem_drobj_freelist = prtfs_cfg->mem_drobj_pool; pobj = prtfs_cfg->mem_drobj_freelist = prtfs_cfg->mem_drobj_pool;
pobj->is_free = TRUE; pobj->is_free = TRUE;
for (i = 0,j = 1; i < prtfs_cfg->cfg_NDROBJS-1; i++, j++) for (i = 0,j = 1; i < prtfs_cfg->cfg_NDROBJS-1; i++, j++)
{ {
pobj = prtfs_cfg->mem_drobj_freelist + j; pobj = prtfs_cfg->mem_drobj_freelist + j;
pobj->is_free = TRUE; pobj->is_free = TRUE;
@ -389,10 +400,10 @@ BOOLEAN pc_memory_init(void) /*__
prtfs_cfg->mem_drobj_freelist[prtfs_cfg->cfg_NDROBJS-1].pdrive = 0; prtfs_cfg->mem_drobj_freelist[prtfs_cfg->cfg_NDROBJS-1].pdrive = 0;
/* Make a NULL terminated FINODE freelist using /* Make a NULL terminated FINODE freelist using
pnext as the link. This linked freelist is used by the FINODE pnext as the link. This linked freelist is used by the FINODE
memory allocator routine */ memory allocator routine */
pfi = prtfs_cfg->mem_finode_freelist = prtfs_cfg->mem_finode_pool; pfi = prtfs_cfg->mem_finode_freelist = prtfs_cfg->mem_finode_pool;
for (i = 0; i < prtfs_cfg->cfg_NFINODES-1; i++) for (i = 0; i < prtfs_cfg->cfg_NFINODES-1; i++)
{ {
pfi->is_free = TRUE; pfi->is_free = TRUE;
pfi++; pfi++;
@ -432,7 +443,7 @@ DROBJ *preturn;
if (!pobj->is_free) if (!pobj->is_free)
{ {
pobj->is_free = TRUE; pobj->is_free = TRUE;
/* Free it by putting it at the head of the freelist /* Free it by putting it at the head of the freelist
NOTE: pdrive is used to link the freelist */ NOTE: pdrive is used to link the freelist */
pobj->pdrive = (DDRIVE *) prtfs_cfg->mem_drobj_freelist; pobj->pdrive = (DDRIVE *) prtfs_cfg->mem_drobj_freelist;
prtfs_cfg->mem_drobj_freelist = pobj; prtfs_cfg->mem_drobj_freelist = pobj;
@ -519,4 +530,3 @@ BLKBUFF *pfile_buffer;
return(preturn); return(preturn);
} }

View File

@ -161,7 +161,14 @@ BOOLEAN pc_i_dskopen(int driveno) /*__fn__*/
pdr->secreserved = bl0.secreserved; /* sectors reserved */ pdr->secreserved = bl0.secreserved; /* sectors reserved */
pdr->secptrk = bl0.secptrk; /* sectors per track */ pdr->secptrk = bl0.secptrk; /* sectors per track */
pdr->numhead = bl0.numhead; /* number of heads */ pdr->numhead = bl0.numhead; /* number of heads */
pdr->numhide =bl0.numhide; /* # hidden sectors */ {
dword ltemp;
pdr->numhide =bl0.numhide; /* # hidden sectors */
ltemp = bl0.numhide2;
ltemp <<= 16;
pdr->numhide |= ltemp;
}
copybuff(pdr->volume_label, &bl0.vollabel[0], 11); copybuff(pdr->volume_label, &bl0.vollabel[0], 11);
pdr->volume_label[11] = 0; pdr->volume_label[11] = 0;

View File

@ -1,8 +1,8 @@
/* /*
* rttermin.c - Portable portion of terminal IO routines * rttermin.c - Portable portion of terminal IO routines
* *
* EBS - ERTFS * EBS - ERTFS
* *
* Copyright EBS Inc. 1987-2003 * Copyright EBS Inc. 1987-2003
* All rights reserved. * All rights reserved.
* This code may not be redistributed in source or linkable object form * This code may not be redistributed in source or linkable object form
@ -11,24 +11,24 @@
* *
* Module description: * Module description:
* This file contains terminal IO routines used by the sample programs * This file contains terminal IO routines used by the sample programs
* and by routines that print diagnostics. * and by routines that print diagnostics.
* *
* *
* The rest of the routines in this module are portable with the possible * The rest of the routines in this module are portable with the possible
* exception of these two routines: * exception of these two routines:
* *
* void rtfs_print_format_dir * void rtfs_print_format_dir
* void rtfs_print_format_stat * void rtfs_print_format_stat
* *
* These routines may require porting if sprintf() is not available to you. * These routines may require porting if sprintf() is not available to you.
* They are called only by the test shell prgram (tstsh.c) and are used to create attractive * They are called only by the test shell prgram (tstsh.c) and are used to create attractive
* formatted output for the DIR and STAT commands. They rely on sprintf to format the output * formatted output for the DIR and STAT commands. They rely on sprintf to format the output
* to provide a system specific console output routine. A define is provided * to provide a system specific console output routine. A define is provided
* in this file named SYS_SUPPORTS_SPRINTF, if this is set to one the routines format the output * in this file named SYS_SUPPORTS_SPRINTF, if this is set to one the routines format the output
* using sprintf, otherwise they print a fixd string. If sprintf is not available to you set * using sprintf, otherwise they print a fixd string. If sprintf is not available to you set
* SYS_SUPPORTS_SPRINTF to zero. * SYS_SUPPORTS_SPRINTF to zero.
*
* *
*
* The following portable routines are also provided in this file. * The following portable routines are also provided in this file.
* *
* rtfs_print_string_1(int stringid,int flags) * rtfs_print_string_1(int stringid,int flags)
@ -36,29 +36,29 @@
* *
* These two routines are used to print string values to the console. They are portable, * These two routines are used to print string values to the console. They are portable,
* relying on the routine rtfs_port_puts(() to provide a system specific console output routine. * relying on the routine rtfs_port_puts(() to provide a system specific console output routine.
* If no output is desired define the macros RTFS_PRINT_STRING_1 and RTFS_PRINT_STRING_2 as * If no output is desired define the macros RTFS_PRINT_STRING_1 and RTFS_PRINT_STRING_2 as
* no-ops in portterm.h. * no-ops in portterm.h.
* *
* rtfs_print_long_1 * rtfs_print_long_1
* *
* This routine is used to print long integers values to the console. It relies on * This routine is used to print long integers values to the console. It relies on
* rtfs_port_puts(() to provide a system specific console output routine. If no output * rtfs_port_puts(() to provide a system specific console output routine. If no output
* is desired define the macro RTFS_PRINT_LONG_1 as a no-op in portterm.h. * is desired define the macro RTFS_PRINT_LONG_1 as a no-op in portterm.h.
* *
* *
* rtfs_print_prompt_user() - * rtfs_print_prompt_user() -
* *
* This routine is called when the ERTFS demo programs and critical error handlr routine * This routine is called when the ERTFS demo programs and critical error handlr routine
* requires console input from the user. It takes as input a prompt id (this is a numeric * requires console input from the user. It takes as input a prompt id (this is a numeric
* handle to the prompt strings in the prompts string table prompt_table[] * handle to the prompt strings in the prompts string table prompt_table[]
* in portstr.c and the address of a buffer where to place the console * in portstr.c and the address of a buffer where to place the console
* input. * input.
* *
* This routine displays the prompt by calling rtfs_print_one_string() and then * This routine displays the prompt by calling rtfs_print_one_string() and then
* calls the target specific routine tm_gets_rtfs() to recieve the console * calls the target specific routine tm_gets_rtfs() to recieve the console
* input. * input.
* *
* Note: If in your system console input is not available you may still * Note: If in your system console input is not available you may still
* use the demo and test applications by modifying this routine so that * use the demo and test applications by modifying this routine so that
* it returns specific strings to simulate user input. The values to return * it returns specific strings to simulate user input. The values to return
* must be relevant to the value of prompt_id. Here are several prompt_id * must be relevant to the value of prompt_id. Here are several prompt_id
@ -66,12 +66,12 @@
* *
* *
* UPROMPT_CRITERR - This is the prompt_id argument when a drive IO error * UPROMPT_CRITERR - This is the prompt_id argument when a drive IO error
* occurs. You should return "A" in the return buffer. This will cause the * occurs. You should return "A" in the return buffer. This will cause the
* IO operation to fail and return an error to the API. * IO operation to fail and return an error to the API.
* *
* UPROMPT_TSTSH - If you returned "S" for UPROMPT_RTFSDEM1 then this * UPROMPT_TSTSH - If you returned "S" for UPROMPT_RTFSDEM1 then this
* prompt will be called after the test shell starts and repeatedly * prompt will be called after the test shell starts and repeatedly
* thereafter. Return strings for this prompt as if you were typing * thereafter. Return strings for this prompt as if you were typing
* input to the command shell. * input to the command shell.
* *
* For example a sequence of strings might fill. * For example a sequence of strings might fill.
@ -82,7 +82,7 @@
* *
* If you do not wish to use the interactive test programs you need * If you do not wish to use the interactive test programs you need
* not implement this function. * not implement this function.
* If sprintf is not available to you set SYS_SUPPORTS_SPRINTF to zero. * If sprintf is not available to you set SYS_SUPPORTS_SPRINTF to zero.
*/ */
#define SYS_SUPPORTS_SPRINTF 0 #define SYS_SUPPORTS_SPRINTF 0
#include <rtfs.h> #include <rtfs.h>
@ -139,13 +139,13 @@ void rtfs_print_format_dir(byte *display_buffer, DSTAT *statobj)
dirstr = (byte *)"<DIR>"; dirstr = (byte *)"<DIR>";
else else
dirstr = (byte *)" "; dirstr = (byte *)" ";
p = display_buffer; p = display_buffer;
*p = 0; *p = 0;
sprintf((char *)p,"%-8s.", (char *)&(statobj->fname[0])); sprintf((char *)p,"%-8s.", (char *)&(statobj->fname[0]));
sprintf((char *)gotoeos(p),"%-3s", (char *)&(statobj->fext[0])); sprintf((char *)gotoeos(p),"%-3s", (char *)&(statobj->fext[0]));
// sprintf((char *)gotoeos(p)," %10lu ", statobj->fsize); /* sprintf((char *)gotoeos(p)," %10lu ", statobj->fsize); */
sprintf((char *)gotoeos(p)," %10u ", statobj->fsize); sprintf((char *)gotoeos(p)," %10u ", statobj->fsize);
sprintf((char *)gotoeos(p),"%5s", dirstr); sprintf((char *)gotoeos(p),"%5s", dirstr);
@ -163,7 +163,7 @@ void rtfs_print_format_dir(byte *display_buffer, DSTAT *statobj)
{ {
/* For vfat systems display the attributes and the long file name /* For vfat systems display the attributes and the long file name
seperately. This is a trick since the attribute are ASCII and the seperately. This is a trick since the attribute are ASCII and the
LFN is UNICODE. If we print seperately we will see them both correctly */ LFN is UNICODE. If we print seperately we will see them both correctly */
sprintf((char *)gotoeos(p), " - "); sprintf((char *)gotoeos(p), " - ");
rtfs_print_one_string(display_buffer, 0); rtfs_print_one_string(display_buffer, 0);
rtfs_print_one_string(statobj->lfname,PRFLG_NL); rtfs_print_one_string(statobj->lfname,PRFLG_NL);
@ -197,7 +197,7 @@ byte *p;
void rtfs_print_one_string(byte *pstr,int flags) void rtfs_print_one_string(byte *pstr,int flags)
{ {
rtfs_port_puts(CS_OP_FORMAT_OUTPUT(pstr)); rtfs_port_puts(CS_OP_FORMAT_OUTPUT(pstr));
if (flags & PRFLG_NL) if (flags & PRFLG_NL)
rtfs_port_puts((byte *)"\n"); rtfs_port_puts((byte *)"\n");
@ -212,11 +212,11 @@ int digit;
byte *olddest = dest; byte *olddest = dest;
byte * p; byte * p;
p = &(buffer[32]); p = &(buffer[32]);
*p = '\0'; *p = '\0';
/* Convert num to a string going from dest[31] backwards */ /* Convert num to a string going from dest[31] backwards */
/* Nasty little ItoA algorithm */ /* Nasty little ItoA algorithm */
do do
{ {
@ -232,4 +232,3 @@ byte * p;
while((*dest++=*p++)!='\0'); while((*dest++=*p++)!='\0');
return (olddest); return (olddest);
} }

View File

@ -54,6 +54,7 @@ Summary
*/ */
void pc_calculate_chs(dword total, dword *cylinders, int *heads, int *secptrack);
#define DEFAULT_HOST_DISK_SIZE 10240 /* 5M, FAT16 */ #define DEFAULT_HOST_DISK_SIZE 10240 /* 5M, FAT16 */
@ -61,9 +62,6 @@ Summary
#define WINDOWS_HOSTDISK_SPRINTF sprintf #define WINDOWS_HOSTDISK_SPRINTF sprintf
void calculate_hcn(long n_blocks, PDEV_GEOMETRY pgeometry);
#define MAXSEGMENTS_PER_UNIT 16 #define MAXSEGMENTS_PER_UNIT 16
#define MAX_UNITS 8 #define MAX_UNITS 8
struct file64 { struct file64 {
@ -166,7 +164,6 @@ DWORD size, s;
return((dword)size); return((dword)size);
} }
BOOLEAN hostdisk_io_64(int unit, dword block, void *buffer, word _count, BOOLEAN reading) /*__fn__*/ BOOLEAN hostdisk_io_64(int unit, dword block, void *buffer, word _count, BOOLEAN reading) /*__fn__*/
{ {
dword segment_number; dword segment_number;
@ -177,12 +174,6 @@ dword nbytes,nblocks;
byte *bbuffer; byte *bbuffer;
bbuffer = (byte *) buffer; bbuffer = (byte *) buffer;
count = (dword) _count; count = (dword) _count;
// if (reading)
// printf("%d,", block);
//else
// printf("%d;", block);
//if (block < 2000)
// printf("\n");
while (count) while (count)
{ {
segment_number = block/BLOCKS_PER_GIG; segment_number = block/BLOCKS_PER_GIG;
@ -315,7 +306,7 @@ DDRIVE *pdr;
gc.dev_geometry_lbas = size_64bit_volume(pdr->logical_unit_number); gc.dev_geometry_lbas = size_64bit_volume(pdr->logical_unit_number);
if (!gc.dev_geometry_lbas) if (!gc.dev_geometry_lbas)
return(-1); return(-1);
calculate_hcn(gc.dev_geometry_lbas, &gc); pc_calculate_chs(gc.dev_geometry_lbas, &gc.dev_geometry_cylinders, &gc.dev_geometry_heads, &gc.dev_geometry_secptrack);
copybuff(pargs, &gc, sizeof(gc)); copybuff(pargs, &gc, sizeof(gc));
return (0); return (0);
} }
@ -402,8 +393,7 @@ DDRIVE *pdr;
/* Update caller's idea of geometry */ /* Update caller's idea of geometry */
pgc->dev_geometry_lbas = l; pgc->dev_geometry_lbas = l;
calculate_hcn(pgc->dev_geometry_lbas, pgc); pc_calculate_chs(pgc->dev_geometry_lbas, &pgc->dev_geometry_cylinders, &pgc->dev_geometry_heads, &pgc->dev_geometry_secptrack);
return(0); return(0);
} }
break; break;
@ -448,5 +438,4 @@ DDRIVE *pdr;
} }
#endif /* (INCLUDE_HOSTDISK) */ #endif /* (INCLUDE_HOSTDISK) */

View File

@ -11,7 +11,7 @@
* *
* Description: * Description:
* This file contains porting layer tuning constants for configuring RTFS. * This file contains porting layer tuning constants for configuring RTFS.
* It is included by rtfsconf.h. * It is included by pcconf.h.
* *
****************************************************************************/ ****************************************************************************/
@ -25,26 +25,23 @@
#define KS_CONSTANT const /* See porting reference guide for explanation */ #define KS_CONSTANT const /* See porting reference guide for explanation */
#define KS_FAR /* See porting reference guide for explanation */ #define KS_FAR /* See porting reference guide for explanation */
/* Compile time constants to control device inclusion and includion of
porting layer subroutines */
/* Compile time constants to control device inclusion #define INCLUDE_IDE 0 /* - Include the IDE driver */
See the reference guide for an explanation #define INCLUDE_PCMCIA 0 /* - Include the pcmcia driver */
*/ #define INCLUDE_PCMCIA_SRAM 0 /* - Include the pcmcia static ram card driver */
#define INCLUDE_COMPACT_FLASH 0 /* - Support compact flash (requires IDE and PCMCIA) */
#define INCLUDE_CDROM 0 /* - Support ATAPI CD (requires IDE) */
#define INCLUDE_SD 0 #define INCLUDE_FLASH_FTL 0 /* - Include the linear flash driver */
#define INCLUDE_IDE 0 /* - Include the IDE driver */ #define INCLUDE_ROMDISK 0 /* - Include the rom disk driver */
#define INCLUDE_PCMCIA 0 /* - Include the pcmcia driver */ #define INCLUDE_RAMDISK 0 /* - Include the rom disk driver */
#define INCLUDE_PCMCIA_SRAM 0 /* - Include the pcmcia static ram card driver */ #define INCLUDE_MMCCARD 0 /* - Include the multi media flash card driver */
#define INCLUDE_COMPACT_FLASH 0 /* - Support compact flash (requires IDE and PCMCIA) */ #define INCLUDE_SMARTMEDIA 0 /* - Include the smart media flash card driver */
#define INCLUDE_FLASH_FTL 0 /* - Include the linear flash driver */ #define INCLUDE_FLOPPY 0 /* - Include the floppy disk driver */
#define INCLUDE_ROMDISK 0 /* - Include the rom disk driver */ #define INCLUDE_HOSTDISK 0 /* - Include the host disk disk simulator */
#define INCLUDE_RAMDISK 0 /* - Include the rom disk driver */ #define INCLUDE_WINDEV 0 /* - Include windows direct device access */
#define INCLUDE_MMCCARD 0 /* - Include the multi media flash card driver */ #define INCLUDE_UDMA 0 /* - Include ultra dma support for the ide driver */
#define INCLUDE_SMARTMEDIA 0 /* - Include the smart media flash card driver */ #define INCLUDE_82365_PCMCTRL 0 /* - Include the 82365 pcmcia controller driver */
#define INCLUDE_FLOPPY 0 /* - Include the floppy disk driver */
#define INCLUDE_HOSTDISK 0 /* - Include the host disk disk simulator */
#define INCLUDE_UDMA 0 /* - Include ultra dma support for the ide driver */
#define INCLUDE_82365_PCMCTRL 0 /* - Include the 82365 pcmcia controller driver */
#endif /* __PORTCONF__ */ #endif /* __PORTCONF__ */

View File

@ -383,7 +383,6 @@ typedef struct ddrive {
etc are valid */ etc are valid */
BOOLEAN mount_abort; /* True if error handler requests abort */ BOOLEAN mount_abort; /* True if error handler requests abort */
int drive_opencounter; /* Value of global opencounter when we mounted */ int drive_opencounter; /* Value of global opencounter when we mounted */
dword volume_serialno; /* Volume serial number block 0 */ dword volume_serialno; /* Volume serial number block 0 */
byte volume_label[14]; /* Volume entry from block 0 */ byte volume_label[14]; /* Volume entry from block 0 */
int bytespcluster; /* */ int bytespcluster; /* */
@ -626,6 +625,7 @@ typedef struct blkbuffcntxt {
struct blkbuff *pfree_blocks; /* uses pnext */ struct blkbuff *pfree_blocks; /* uses pnext */
int num_blocks; int num_blocks;
int num_free; int num_free;
int scratch_alloc_count;
int low_water; int low_water;
int num_alloc_failures; int num_alloc_failures;
int hash_size; int hash_size;
@ -795,7 +795,6 @@ typedef struct fmtparms {
#define VOID_CHECK_MEM() if (!prtfs_cfg) {return;} #define VOID_CHECK_MEM() if (!prtfs_cfg) {return;}
#define IS_AVOLORDIR(X) ((X->isroot) || (X->finode->fattribute & AVOLUME|ADIRENT)) #define IS_AVOLORDIR(X) ((X->isroot) || (X->finode->fattribute & AVOLUME|ADIRENT))
/* File RTFSINIT.C: */ /* File RTFSINIT.C: */
BOOLEAN pc_ertfs_init(void); BOOLEAN pc_ertfs_init(void);
@ -1187,7 +1186,6 @@ typedef struct dev_geometry {
#define DEVCTL_FLUSH 7 #define DEVCTL_FLUSH 7
/*----------------------------------*/ /*----------------------------------*/
typedef struct dev_geometry *PDEV_GEOMETRY; typedef struct dev_geometry *PDEV_GEOMETRY;
@ -1390,7 +1388,7 @@ extern RTFS_CFG *prtfs_cfg;
#include "prfs.h" #include "prfs.h"
#endif /* INCLUDE_FAILSAFE_CODE */ #endif /* INCLUDE_FAILSAFE_CODE */
/* Include RTFS Pro features */ /* Include RTFS Pro features */
#include "rtfspro.h" //twl modified #include <rtfspro.h>
#include "attach.h" //ctr modified #include "attach.h" //ctr modified