Files
CherryUSB/platform/threadx/usbh_msc_filex.c

299 lines
15 KiB
C
Raw Normal View History

/***************************************************************************
* Copyright (c) 2024 Microsoft Corporation
*
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* https://opensource.org/licenses/MIT.
*
* SPDX-License-Identifier: MIT
**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/** */
/** FileX Component */
/** */
/** RAM Disk Driver */
/** */
/**************************************************************************/
/**************************************************************************/
/* Include necessary system files. */
#include "fx_api.h"
#include "usbh_core.h"
#include "usbh_msc.h"
/* The RAM driver relies on the fx_media_format call to be made prior to
the fx_media_open call. The following call will format the default
32KB RAM drive, with a sector size of 128 bytes per sector.
fx_media_format(&ram_disk,
_fx_usbh_msc_driver, // Driver entry
NULL, // RAM disk memory pointer
media_memory, // Media buffer pointer
sizeof(media_memory), // Media buffer size
"MY_RAM_DISK", // Volume Name
2, // Number of FATs
128, // Directory Entries
0, // Hidden sectors
256, // Total sectors
128, // Sector size
1, // Sectors per cluster
1, // Heads
1); // Sectors per track
*/
VOID _fx_usbh_msc_driver(FX_MEDIA *media_ptr);
/**************************************************************************/
/* */
/* FUNCTION RELEASE */
/* */
/* _fx_ram_driver PORTABLE C */
/* 6.1.5 */
/* AUTHOR */
/* */
/* William E. Lamie, Microsoft Corporation */
/* */
/* DESCRIPTION */
/* */
/* This function is the entry point to the generic RAM disk driver */
/* that is delivered with all versions of FileX. The format of the */
/* RAM disk is easily modified by calling fx_media_format prior */
/* to opening the media. */
/* */
/* This driver also serves as a template for developing FileX drivers */
/* for actual devices. Simply replace the read/write sector logic with */
/* calls to read/write from the appropriate physical device */
/* */
/* FileX RAM/FLASH structures look like the following: */
/* */
/* Physical Sector Contents */
/* */
/* 0 Boot record */
/* 1 FAT Area Start */
/* +FAT Sectors Root Directory Start */
/* +Directory Sectors Data Sector Start */
/* */
/* */
/* INPUT */
/* */
/* media_ptr Media control block pointer */
/* */
/* OUTPUT */
/* */
/* None */
/* */
/* CALLS */
/* */
/* _fx_utility_memory_copy Copy sector memory */
/* _fx_utility_16_unsigned_read Read 16-bit unsigned */
/* */
/* CALLED BY */
/* */
/* FileX System Functions */
/* */
/* RELEASE HISTORY */
/* */
/* DATE NAME DESCRIPTION */
/* */
/* 05-19-2020 William E. Lamie Initial Version 6.0 */
/* 09-30-2020 William E. Lamie Modified comment(s), */
/* resulting in version 6.1 */
/* 03-02-2021 William E. Lamie Modified comment(s), */
/* resulting in version 6.1.5 */
/* */
/**************************************************************************/
VOID _fx_usbh_msc_driver(FX_MEDIA *media_ptr)
{
struct usbh_msc *msc_class;
int ret;
/* There are several useful/important pieces of information contained in
the media structure, some of which are supplied by FileX and others
are for the driver to setup. The following is a summary of the
necessary FX_MEDIA structure members:
FX_MEDIA Member Meaning
fx_media_driver_request FileX request type. Valid requests from
FileX are as follows:
FX_DRIVER_READ
FX_DRIVER_WRITE
FX_DRIVER_FLUSH
FX_DRIVER_ABORT
FX_DRIVER_INIT
FX_DRIVER_BOOT_READ
FX_DRIVER_RELEASE_SECTORS
FX_DRIVER_BOOT_WRITE
FX_DRIVER_UNINIT
fx_media_driver_status This value is RETURNED by the driver.
If the operation is successful, this
field should be set to FX_SUCCESS for
before returning. Otherwise, if an
error occurred, this field should be
set to FX_IO_ERROR.
fx_media_driver_buffer Pointer to buffer to read or write
sector data. This is supplied by
FileX.
fx_media_driver_logical_sector Logical sector FileX is requesting.
fx_media_driver_sectors Number of sectors FileX is requesting.
The following is a summary of the optional FX_MEDIA structure members:
FX_MEDIA Member Meaning
fx_media_driver_info Pointer to any additional information
or memory. This is optional for the
driver use and is setup from the
fx_media_open call. The RAM disk uses
this pointer for the RAM disk memory
itself.
fx_media_driver_write_protect The DRIVER sets this to FX_TRUE when
media is write protected. This is
typically done in initialization,
but can be done anytime.
fx_media_driver_free_sector_update The DRIVER sets this to FX_TRUE when
it needs to know when clusters are
released. This is important for FLASH
wear-leveling drivers.
fx_media_driver_system_write FileX sets this flag to FX_TRUE if the
sector being written is a system sector,
e.g., a boot, FAT, or directory sector.
The driver may choose to use this to
initiate error recovery logic for greater
fault tolerance.
fx_media_driver_data_sector_read FileX sets this flag to FX_TRUE if the
sector(s) being read are file data sectors,
i.e., NOT system sectors.
fx_media_driver_sector_type FileX sets this variable to the specific
type of sector being read or written. The
following sector types are identified:
FX_UNKNOWN_SECTOR
FX_BOOT_SECTOR
FX_FAT_SECTOR
FX_DIRECTORY_SECTOR
FX_DATA_SECTOR
*/
/* Process the driver request specified in the media control block. */
switch (media_ptr->fx_media_driver_request) {
case FX_DRIVER_READ: {
msc_class = (struct usbh_msc *)media_ptr->fx_media_driver_info;
ret = usbh_msc_scsi_read10(msc_class, media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors, media_ptr->fx_media_driver_buffer,
media_ptr->fx_media_driver_sectors);
if (ret < 0) {
media_ptr->fx_media_driver_status = FX_IO_ERROR;
return;
}
printf("read success\r\n");
/* Successful driver request. */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_WRITE: {
msc_class = (struct usbh_msc *)media_ptr->fx_media_driver_info;
ret = usbh_msc_scsi_write10(msc_class, media_ptr->fx_media_driver_logical_sector + media_ptr->fx_media_hidden_sectors,
media_ptr->fx_media_driver_buffer, media_ptr->fx_media_driver_sectors);
if (ret < 0) {
media_ptr->fx_media_driver_status = FX_IO_ERROR;
return;
}
/* Successful driver request. */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_FLUSH: {
/* Return driver success. */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_ABORT: {
/* Return driver success. */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_INIT: {
msc_class = usbh_find_class_instance(media_ptr->fx_media_name);
if (!msc_class) {
USB_LOG_ERR("No instance found for %s", media_ptr->fx_media_name);
media_ptr->fx_media_driver_status = FX_MEDIA_INVALID;
return;
}
if (usbh_msc_scsi_init(msc_class) < 0) {
media_ptr->fx_media_driver_status = FX_MEDIA_INVALID;
return;
}
media_ptr->fx_media_driver_info = msc_class;
/* Successful driver request. */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_UNINIT: {
/* There is nothing to do in this case for the RAM driver. For actual
devices some shutdown processing may be necessary. */
/* Successful driver request. */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_BOOT_READ: {
msc_class = (struct usbh_msc *)media_ptr->fx_media_driver_info;
ret = usbh_msc_scsi_read10(msc_class, 0, media_ptr->fx_media_driver_buffer, 1);
if (ret < 0) {
media_ptr->fx_media_driver_status = FX_IO_ERROR;
return;
}
/* Successful driver request. */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
case FX_DRIVER_BOOT_WRITE: {
msc_class = (struct usbh_msc *)media_ptr->fx_media_driver_info;
ret = usbh_msc_scsi_write10(msc_class, 0, media_ptr->fx_media_driver_buffer, 1);
if (ret < 0) {
media_ptr->fx_media_driver_status = FX_IO_ERROR;
return;
}
/* Successful driver request. */
media_ptr->fx_media_driver_status = FX_SUCCESS;
break;
}
default: {
/* Invalid driver request. */
media_ptr->fx_media_driver_status = FX_IO_ERROR;
break;
}
}
}