Chapter 47. Usage

The user API for disk devices is the same as that for serial devices except that cyg_io_bread() and cyg_io_bwrite() are used for data transfers instead of cyg_io_read() and cyg_io_write().

// Write data to a block device
Cyg_ErrNo cyg_io_bwrite(
    cyg_io_handle_t handle,
    const void *buf,
    cyg_uint32 *len,
    cyg_uint32 pos )

This function sends data to a device. The size of data to send is contained in *len and the actual size sent will be returned in the same place. This value must be a count of 512 byte sectors. The pos specifies the position on the disk to which the data will be written. It is a linear sector number.

// Read data from a block device
Cyg_ErrNo cyg_io_bread(
    cyg_io_handle_t handle,
    void *buf,
    cyg_uint32 *len,
    cyg_uint32 pos )

This function receives data from a device. The desired size of data to receive is contained in *len and the actual size obtained will be returned in the same place. This value must be a count of 512 byte sectors. The pos specifies the position on the disk from which the data will be read. It is a linear sector number.

Disk devices are named in the same way as other devices, thus "/dev/hd0" would name the first hard disk. The exact names used for any disk are usually part of the configuration for the target-specific device driver.

Disk devices may be partitioned using a standard DOS partition table. If this is the case then an additional element to the device name specifies the partition to be used. Thus "/dev/hd0/1" specifies partition 1, "/dev/hd0/2" partition 2, "/dev/hd0/3" partition 3 and "/dev/hd0/4" partition 4. The special name "/dev/hd0/0" specifies the entire disk without honoring the partition table. This is only really useful for accessing the master boot record in sector zero, to change the partitioning. Any other kind of access may corrupt the disk.

Application code may also install a disk event callback function. It does this using the CYG_IO_SET_CONFIG_DISK_EVENT configuration option using the cyg_io_set_config(). The buffer should point to an instance of the following structure:

typedef void disk_channel_event_t( cyg_uint32 event, cyg_uint32 devno, CYG_ADDRWORD data );

struct  cyg_disk_event_t
{
    disk_channel_event_t        *event;         // Event callback function
    CYG_ADDRWORD                event_data;     // Event callback user data
};

// Codes for disk_channel_event_t event argument.
#define CYG_DISK_EVENT_CONNECT          0x01
#define CYG_DISK_EVENT_DISCONNECT       0x02

The function should be installed on the base disk device driver (i.e. "/dev/hd0" rather than "/dev/hd0/0" ) and will be called when certain events occur. At present these are restricted to CONNECT and DISCONNECT events when a new disk is attached to, or detached from, the disk controller. Support for this depends on the ability of the underlying hardware device driver being able to detect these events.

A successful lookup of the base disk device driver does not necessarily imply that removeable media is present at that time. Hardware drivers supporting removeable media will typically indicate a successful lookup, irrespective of the presence of a physical disk.

The reason for this is that the call to cyg_io_set_config() for the CYG_IO_SET_CONFIG_DISK_EVENT operation may quite reasonably occur when no physical media is present, so the lookup must succeed in order to obtain a valid I/O handle. That handle is, however, unusable for operations other than CYG_IO_SET_CONFIG_DISK_EVENT.

The context in which the callback is made depends on the implementation of the disk driver. It cannot be assumed that it will occur in a context in which it is safe to make complex calls. It should be assumed that the call is being made from DSR context, where blocking kernel calls may not be made. In general the function should record the details of the call and pass off control to a worker thread. See the automounter in the FILEIO package for an example of how this can be done.

When hardware drivers notice the CYG_IO_SET_CONFIG_DISK_EVENT call, they should immediately check for the presence of a disk, in case one is already connected at the time of event registration. The event callback should be made for any connected disk devices (and not for unconnected disks).