blob: d6e603ea90dab96974058f3b14f254aa45e107e8 (
plain) (
tree)
|
|
/*
* MSDOS Initialization support routine implementation
*
* Copyright (C) 2001 OKTET Ltd., St.-Petersburg, Russia
* Author: Eugeny S. Mints <Eugeny.Mints@oktet.ru>
*
* The license and distribution terms for this file may be
* found in the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
* @(#) $Id$
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <rtems.h>
#include <rtems/libio_.h>
#include "fat.h"
#include "fat_fat_operations.h"
#include "fat_file.h"
#include "msdos.h"
/* msdos_initialize_support --
* MSDOS filesystem initialization
*
* PARAMETERS:
* temp_mt_entry - mount table entry
* op_table - filesystem operations table
* file_handlers - file operations table
* directory_handlers - directory operations table
*
* RETURNS:
* RC_OK and filled temp_mt_entry on success, or -1 if error occured
* (errno set apropriately)
*
*/
int
msdos_initialize_support(
rtems_filesystem_mount_table_entry_t *temp_mt_entry,
rtems_filesystem_operations_table *op_table,
rtems_filesystem_file_handlers_r *file_handlers,
rtems_filesystem_file_handlers_r *directory_handlers
)
{
int rc = RC_OK;
rtems_status_code sc = RTEMS_SUCCESSFUL;
msdos_fs_info_t *fs_info = NULL;
fat_file_fd_t *fat_fd = NULL;
unsigned32 cl_buf_size;
fs_info = (msdos_fs_info_t *)calloc(1, sizeof(msdos_fs_info_t));
if (!fs_info)
set_errno_and_return_minus_one(ENOMEM);
temp_mt_entry->fs_info = fs_info;
rc = fat_init_volume_info(temp_mt_entry);
if (rc != RC_OK)
{
free(fs_info);
return rc;
}
fs_info->file_handlers = file_handlers;
fs_info->directory_handlers = directory_handlers;
/*
* open fat-file which correspondes to root directory
* (so inode number 0x00000010 is always used for root directory)
*/
rc = fat_file_open(temp_mt_entry, FAT_ROOTDIR_CLUSTER_NUM, 0, &fat_fd);
if (rc != RC_OK)
{
fat_shutdown_drive(temp_mt_entry);
free(fs_info);
return rc;
}
/* again: unfortunately "fat-file" is just almost fat file :( */
fat_fd->fat_file_type = FAT_DIRECTORY;
fat_fd->size_limit = MSDOS_MAX_DIR_LENGHT;
fat_fd->info_cln = FAT_ROOTDIR_CLUSTER_NUM;
fat_fd->info_ofs = 0;
fat_fd->cln = fs_info->fat.vol.rdir_cl;
fat_fd->map.file_cln = 0;
fat_fd->map.disk_cln = fat_fd->cln;
/* if we have FAT12/16 */
if ( fat_fd->cln == 0 )
{
fat_fd->fat_file_size = fs_info->fat.vol.rdir_size;
cl_buf_size = (fs_info->fat.vol.bpc > fs_info->fat.vol.rdir_size) ?
fs_info->fat.vol.bpc :
fs_info->fat.vol.rdir_size;
}
else
{
rc = fat_file_size(temp_mt_entry, fat_fd);
if ( rc != RC_OK )
{
fat_file_close(temp_mt_entry, fat_fd);
fat_shutdown_drive(temp_mt_entry);
free(fs_info);
return rc;
}
cl_buf_size = fs_info->fat.vol.bpc;
}
fs_info->cl_buf = (char *)calloc(cl_buf_size, sizeof(char));
if (fs_info->cl_buf == NULL)
{
fat_file_close(temp_mt_entry, fat_fd);
fat_shutdown_drive(temp_mt_entry);
free(fs_info);
set_errno_and_return_minus_one(ENOMEM);
}
sc = rtems_semaphore_create(3,
1,
RTEMS_BINARY_SEMAPHORE | RTEMS_FIFO,
0,
&fs_info->vol_sema);
if (sc != RTEMS_SUCCESSFUL)
{
fat_file_close(temp_mt_entry, fat_fd);
fat_shutdown_drive(temp_mt_entry);
free(fs_info->cl_buf);
free(fs_info);
set_errno_and_return_minus_one( EIO );
}
temp_mt_entry->mt_fs_root.node_access = fat_fd;
temp_mt_entry->mt_fs_root.handlers = directory_handlers;
temp_mt_entry->mt_fs_root.ops = op_table;
return rc;
}
|