AmigaChromeA new chapter for the Amiga

API docs / Autodocs / acscsi.doc

API · Autodoc

acscsi.device autodoc

acscsi.device: units, the ACSIORequest extension, every command it accepts

acscsi.device/--background--

   PURPOSE
        acscsi.device is the Exec device for the AmigaChrome ACStorage
        Zorro-II board. It finds the board, reports volume geometry, and
        carries the folder operations that ACFS needs to the host.

        It is not a block device. An AmigaChrome hard disk is a folder on
        the host, and the device's private commands name files and
        directories by path. There is no CMD_READ or CMD_WRITE of sectors;
        TD_GETGEOMETRY exists only so that tools which ask for geometry get
        a plausible answer.

   UNITS
        Unit numbers are the same on every guest OS and match the host:

            0 - 7   DH0: - DH7:
            8       BOOT:

        ACSCSI_UNIT_DH0, ACSCSI_UNIT_DH1 and ACSCSI_UNIT_BOOT are defined
        in <acscsi.h>. OpenDevice() accepts any unit below ACSCSI_MAX_UNITS
        (9). Opening a unit does not check that a folder is behind it;
        the first command does.

   IO REQUEST
        The private commands use the extended request ACSIORequest from
        <acscsi.h>. Allocate it with CreateIORequest(port,
        sizeof(struct ACSIORequest)) and open the device with it:

            struct ACSIORequest {
                struct IOStdReq io;
                CONST_STRPTR path;    /* volume-relative path, UTF-8 */
                CONST_STRPTR path2;   /* second path (RENAME only) */
                ULONG offset;         /* byte offset, start index or size */
                ULONG flags;          /* ACSIOF_CREATE, ACSIOF_TRUNCATE */
                ULONG actual;         /* extra result (LIST: next index) */
                LONG result;          /* ACSRESULT_xxx, see below */
            };

        Paths are relative to the root of the unit's volume, use '/' as
        the separator and have no leading slash or volume name. "" is the
        root. The caller owns the path strings until the request returns.

   ERRORS
        Two fields report failure, and they mean different things.

        io_Error is the transport: 0 when the command reached the host and
        came back, otherwise an Exec or trackdisk error (IOERR_BADLENGTH,
        IOERR_BADADDRESS, IOERR_NOCMD, IOERR_OPENFAIL, TDERR_NotSpecified
        for a timeout or a board fault).

        result is the filesystem outcome when io_Error is 0:

            ACSRESULT_OK            0   done
            ACSRESULT_NOT_FOUND     1   no such file or directory
            ACSRESULT_EXISTS        2   target already exists
            ACSRESULT_NOT_EMPTY     3   directory is not empty
            ACSRESULT_IN_USE        4   host has the object open
            ACSRESULT_ACCESS        5   permission denied
            ACSRESULT_READ_ONLY     6   volume is read-only
            ACSRESULT_INVALID_NAME  7   name is not legal on the host
            ACSRESULT_NO_SPACE      8   host disk full
            ACSRESULT_WRONG_TYPE    9   file where a directory was needed,
                                        or the other way round
            ACSRESULT_RANGE        10   offset or size out of range
            ACSRESULT_IO           11   host I/O error
            ACSRESULT_PROTOCOL     12   malformed request or reply

        A command that fails with result != 0 still sets io_Error to 0, so
        check result after every private command.

   NOTES
        All commands complete synchronously inside BeginIO(). Use DoIO().
        AbortIO() does nothing and returns IOERR_NOCMD.

        The device polls the board and waits with Delay(1) between polls,
        so it needs dos.library.

   SEE ALSO
        acfs-handler/--background--, acstorage/--background--,
        <acscsi.h>, <acstorage.h>

acscsi.device/ACSCMD_DELETE

   NAME
        ACSCMD_DELETE -- delete a file or an empty directory

   IO REQUEST
        io_Message      mn_ReplyPort initialized
        io_Device       set by OpenDevice()
        io_Unit         set by OpenDevice()
        io_Command      ACSCMD_DELETE
        path            object to delete

   RESULTS
        io_Error        0 or a transport error
        result          ACSRESULT_xxx; NOT_EMPTY for a directory with
                        anything in it

   NOTES
        The device does not know about AmigaDOS locks. ACFS refuses the
        delete itself when a lock or open file is inside path.

   SEE ALSO
        ACSCMD_MKDIR, acfs-handler/ACTION_DELETE_OBJECT

acscsi.device/ACSCMD_LIST

   NAME
        ACSCMD_LIST -- read one page of a directory

   FUNCTION
        Fills an array of ACSDirEntry with entries from the directory at
        path, starting at entry index offset. Call again with offset set
        to the returned next index until it is 0xffffffff.

   IO REQUEST
        io_Message      mn_ReplyPort initialized
        io_Device       set by OpenDevice()
        io_Unit         set by OpenDevice()
        io_Command      ACSCMD_LIST
        io_Data         array of ACSDirEntry
        io_Length       size of the array in bytes; capacity is
                        io_Length / sizeof(ACSDirEntry)
        path            directory to list, "" for the root
        offset          index of the first entry wanted, 0 to start

   RESULTS
        io_Error        0, IOERR_BADADDRESS, IOERR_BADLENGTH, or a
                        transport error
        io_Actual       bytes filled: entries * sizeof(ACSDirEntry)
        actual          index to pass as offset next time, or
                        0xffffffff when the listing is complete
        result          ACSRESULT_xxx

            typedef struct ACSDirEntry {
                ULONG type;          /* 1 = file, 2 = directory */
                ULONG size;
                ULONG mtime;
                char  name[256];     /* NUL-terminated, UTF-8 */
            } ACSDirEntry;

   NOTES
        The host does not hold the listing between calls. If the directory
        changes between pages, entries can be skipped or repeated.

   SEE ALSO
        ACSCMD_STAT, acfs-handler/ACTION_EXAMINE_NEXT

acscsi.device/ACSCMD_MKDIR

   NAME
        ACSCMD_MKDIR -- create one directory

   IO REQUEST
        io_Message      mn_ReplyPort initialized
        io_Device       set by OpenDevice()
        io_Unit         set by OpenDevice()
        io_Command      ACSCMD_MKDIR
        path            directory to create; its parent must exist

   RESULTS
        io_Error        0 or a transport error
        result          ACSRESULT_xxx; EXISTS if anything is already there

   SEE ALSO
        ACSCMD_DELETE, acfs-handler/ACTION_CREATE_DIR

acscsi.device/ACSCMD_READ_FILE

   NAME
        ACSCMD_READ_FILE -- read bytes from a file

   FUNCTION
        Reads up to io_Length bytes from the file at path, starting at
        byte offset. The device splits large reads into mailbox-sized
        transfers; the caller sees one request.

   IO REQUEST
        io_Message      mn_ReplyPort initialized
        io_Device       set by OpenDevice()
        io_Unit         set by OpenDevice()
        io_Command      ACSCMD_READ_FILE
        io_Data         destination buffer
        io_Length       bytes wanted
        path            file to read
        offset          byte offset in the file

   RESULTS
        io_Error        0, IOERR_BADADDRESS, or a transport error
        io_Actual       bytes read; less than io_Length at end of file
        result          ACSRESULT_xxx

   NOTES
        There is no open file on the host side. Each request names the
        path again, so a file renamed or deleted on the host between reads
        fails with ACSRESULT_NOT_FOUND.

   SEE ALSO
        ACSCMD_WRITE_FILE, acstorage/ACSTORAGE_CMD_READ_FILE

acscsi.device/ACSCMD_RENAME

   NAME
        ACSCMD_RENAME -- rename or move an object on one volume

   IO REQUEST
        io_Message      mn_ReplyPort initialized
        io_Device       set by OpenDevice()
        io_Unit         set by OpenDevice()
        io_Command      ACSCMD_RENAME
        path            current path
        path2           new path, on the same unit

   RESULTS
        io_Error        0, IOERR_BADADDRESS, or a transport error
        result          ACSRESULT_xxx; EXISTS if path2 is taken

   NOTES
        A rename that changes only the case of a name is allowed.

   SEE ALSO
        acfs-handler/ACTION_RENAME_OBJECT

acscsi.device/ACSCMD_SET_SIZE

   NAME
        ACSCMD_SET_SIZE -- truncate or extend a file

   IO REQUEST
        io_Message      mn_ReplyPort initialized
        io_Device       set by OpenDevice()
        io_Unit         set by OpenDevice()
        io_Command      ACSCMD_SET_SIZE
        path            file to resize
        offset          new size in bytes

   RESULTS
        io_Error        0 or a transport error
        result          ACSRESULT_xxx

   SEE ALSO
        acfs-handler/ACTION_SET_FILE_SIZE

acscsi.device/ACSCMD_STAT

   NAME
        ACSCMD_STAT -- get the type, size and date of one path

   IO REQUEST
        io_Message      mn_ReplyPort initialized
        io_Device       set by OpenDevice()
        io_Unit         set by OpenDevice()
        io_Command      ACSCMD_STAT
        io_Data         pointer to an ACSStat
        io_Length       sizeof(ACSStat)
        path            object to examine, "" for the volume root

   RESULTS
        io_Error        0, IOERR_BADLENGTH, or a transport error
        io_Actual       sizeof(ACSStat) on success
        result          ACSRESULT_OK or ACSRESULT_NOT_FOUND, among others

            typedef struct ACSStat {
                ULONG type;     /* 1 = file, 2 = directory */
                ULONG size;     /* bytes; 0 for a directory */
                ULONG mtime;    /* seconds since 1 Jan 1970, host time */
            } ACSStat;

   NOTES
        The host resolves names without regard to case, as AmigaDOS does.

   SEE ALSO
        ACSCMD_LIST, acstorage/ACSTORAGE_CMD_STAT

acscsi.device/ACSCMD_VOLUME_INFO

   NAME
        ACSCMD_VOLUME_INFO -- describe the unit's volume

   FUNCTION
        Returns the label, flags, boot priority and synthetic geometry of
        the folder behind this unit. The label and boot priority come from
        the volume's .amigachrome-volume.json on the host.

   IO REQUEST
        io_Message      mn_ReplyPort initialized
        io_Device       set by OpenDevice()
        io_Unit         set by OpenDevice()
        io_Command      ACSCMD_VOLUME_INFO
        io_Data         pointer to an ACSVolumeInfo
        io_Length       sizeof(ACSVolumeInfo), 92 bytes

   RESULTS
        io_Error        0, IOERR_BADLENGTH, or a transport error
        io_Actual       sizeof(ACSVolumeInfo) on success
        result          ACSRESULT_xxx

            typedef struct ACSVolumeInfo {
                ULONG flags;           /* ACSTORAGE_VOLUME_FLAG_xxx */
                LONG  bootPriority;
                ULONG blockSize;
                ULONG cylinders;
                ULONG heads;
                ULONG sectorsPerTrack;
                ULONG lbaSectors;
                char  label[64];       /* NUL-terminated */
            } ACSVolumeInfo;

        flags may contain ACSTORAGE_VOLUME_FLAG_BOOTABLE (1) and
        ACSTORAGE_VOLUME_FLAG_READONLY (2).

   NOTES
        The layout is checked at compile time on m68k: lbaSectors at
        offset 24, label at offset 28, total size 92.

   SEE ALSO
        TD_GETGEOMETRY, acstorage/ACSTORAGE_CMD_VOLUME_INFO

acscsi.device/ACSCMD_WRITE_FILE

   NAME
        ACSCMD_WRITE_FILE -- write bytes to a file

   FUNCTION
        Writes io_Length bytes to the file at path, starting at byte
        offset. With ACSIOF_CREATE a missing file is created first. With
        ACSIOF_TRUNCATE the file is cut to zero length before the first
        byte is written. A write with io_Length 0 still reaches the host,
        which is how an empty file is created.

   IO REQUEST
        io_Message      mn_ReplyPort initialized
        io_Device       set by OpenDevice()
        io_Unit         set by OpenDevice()
        io_Command      ACSCMD_WRITE_FILE
        io_Data         source buffer
        io_Length       bytes to write
        path            file to write
        offset          byte offset in the file
        flags           0, or ACSIOF_CREATE and/or ACSIOF_TRUNCATE

   RESULTS
        io_Error        0, IOERR_BADADDRESS, or a transport error
        io_Actual       io_Length on success
        result          ACSRESULT_xxx; READ_ONLY, NO_SPACE and NOT_FOUND
                        (no ACSIOF_CREATE) are the usual failures

   NOTES
        A large write is split into several board commands. If one fails
        part way, the earlier parts are already on the host and io_Actual
        is 0.

   SEE ALSO
        ACSCMD_READ_FILE, ACSCMD_SET_SIZE

acscsi.device/CMD_CLEAR

   NAME
        CMD_CLEAR, CMD_UPDATE, CMD_FLUSH -- accepted, do nothing

   FUNCTION
        The device keeps no buffers, so these standard commands return at
        once with io_Error 0. They are accepted so that generic tools and
        handlers that send them do not fail.

   IO REQUEST
        io_Message      mn_ReplyPort initialized
        io_Device       set by OpenDevice()
        io_Unit         set by OpenDevice()
        io_Command      CMD_CLEAR, CMD_UPDATE or CMD_FLUSH

   RESULTS
        io_Error        0

acscsi.device/TD_GETGEOMETRY

   NAME
        TD_GETGEOMETRY -- return a synthetic drive geometry

   FUNCTION
        Fills a struct DriveGeometry from the unit's volume information.
        The numbers are synthetic values the host reports so that tools
        that expect a disk see one; they do not describe real blocks.

   IO REQUEST
        io_Message      mn_ReplyPort initialized
        io_Device       set by OpenDevice()
        io_Unit         set by OpenDevice()
        io_Command      TD_GETGEOMETRY
        io_Data         pointer to a struct DriveGeometry
        io_Length       sizeof(struct DriveGeometry)

   RESULTS
        io_Error        0, IOERR_BADLENGTH if io_Length is too small,
                        or a transport error
        io_Actual       sizeof(struct DriveGeometry) on success

        dg_SectorSize, dg_Cylinders, dg_Heads, dg_TrackSectors and
        dg_TotalSectors come from ACSCMD_VOLUME_INFO. dg_DeviceType is
        DG_DIRECT_ACCESS and dg_BufMemType is MEMF_PUBLIC.

   SEE ALSO
        ACSCMD_VOLUME_INFO, devices/trackdisk.h