A Memory Technology Driver (``MTD'') is used by Card Services to
implement bulk memory services for a particular type of memory device.
An MTD should register as a normal Card Services client with a call to
RegisterClient. When it receives a card insertion event, it
should use GetFirstRegion and GetNextRegion to identify
memory regions that it will administer. Then, it should use
RegisterMTD to take control of these regions. MTD read, write,
copy, and erase requests are packaged into CS_EVENT_MTD_REQUEST
events by Card Services, and passed to the MTD's event handler for
processing.
An MTD receives requests from Card Services in the form of
CS_EVENT_MTD_REQUEST events. Card Services passes a description
of the request in the mtdrequest field of the event callback
arguments. For requests that transfer data to or from the host, the
host buffer address is passed in the buffer field.
The mtd_request_t structure is given by:
typedef struct mtd_request_t {
u_int SrcCardOffset;
u_int DestCardOffset;
u_int TransferLength;
u_int Function;
u_long MediaID;
u_int Status;
u_int Timeout;
} mtd_request_t;
The Function field is bit mapped and describes the action to be
performed by this request:
MTD_REQ_ACTIONEither MTD_REQ_ERASE, MTD_REQ_READ, MTD_REQ_WRITE, or
MTD_REQ_COPY.
MTD_REQ_NOERASEFor a write command that is sized and aligned on erase block boundaries, this specifies that no erase should be performed.
MTD_REQ_VERIFYSpecifies that writes should be verified.
MTD_REQ_READYIndicates that this request is a retry of a previously request that
was delayed until the card asserted READY.
MTD_REQ_TIMEOUTIndicates that this request is a retry of a previously request that was delayed by a timeout.
MTD_REQ_FIRSTIndicates that this request is the first in a series of requests.
MTD_REQ_LASTIndicates that this request is the last of a series of requests.
MTD_REQ_KERNELIndicates that the host buffer for a read or write command is located in kernel memory, as opposed to user memory.
The MediaID field is the value specified in the RegisterMTD
request for this region. The Status field is used by the MTD
when it is unable to satisfy a request because a device is busy. MTD
requests normally run without blocking. If an MTD request would
block, it should return an error code of CS_BUSY, and set
Status to one of the have the following values:
MTD_WAITREQSpecifies that the request should be retried after another MTD request currently in progress completes.
MTD_WAITTIMERSpecifies that the request should be continued after the time
specified in the timeout field.
MTD_WAITRDYSpecifies that the request should be continued when the card signals
READY, or when the time specified in Timeout elapses,
whichever happens first.
MTD_WAITPOWERSpecifies that the request should be retried after something happens that affects power availability to the socket.
For MTD_WAITTIMER and MTD_WAITRDY, the Timeout field
will specify the timeout interval in milliseconds.
Since an MTD processes requests generated by Card Services, there may be some restrictions on the sorts of Card Services calls that can be safely made from the MTD event handler. The MTD helper functions provide a limited set of special services that may be needed by an MTD but would be tricky to implement using the normal Card Services calls. In the Linux implementation, most CS calls can be safely made from an MTD event handler, but the MTD helper interface is included for compatibility.
#include "cs_types.h"
#include "cs.h"
#include "bulkmem.h"
int MTDHelperEntry(int subfunc, void *arg1, void *arg2);
int MTDHelperEntry(MTDRequestWindow, client_handle_t *handle, win_req_t *mod);
int MTDHelperEntry(MTDReleaseWindow, window_handle_t handle);
These services are identical to the standard Card Services
RequestWindow and ReleaseWindow calls.
int MTDHelperEntry(MTDModifyWindow, memory_handle_t handle, mtd_mod_req_t *mod);
The mtd_mod_req_t structure is give by:
typedef struct mtd_mod_req_t {
u_int Attributes;
u_int AccessSpeed;
u_int CardOffset;
} mtd_mod_req_t;
MTDModifyWindow is essentially equivalent to using the normal
ModifyWindow and MapMemPage calls.
The following flags can be specified in Attributes:
WIN_MEMORY_TYPEEither WIN_MEMORY_TYPE_CM for common memory, or
WIN_MEMORY_TYPE_AM for attribute memory.
WIN_USE_WAITSpecifies that the controller should observe the card's MWAIT signal.
A window configured with MTDModifyWindow will always be enabled,
and have a 16 bit data width.
Return codes:
CS_BAD_HANDLEThe memory handle is invalid.
int MTDHelperEntry(MTDSetVpp, client_handle_t client, mtd_vpp_req_t *req);
typedef struct mtd_vpp_req_t {
u_char Vpp1, Vpp2;
} mtd_vpp_req_t;
MTDSetVpp changes the programming voltage for a socket.
Vpp1 and Vpp2 should be given in units of 1/10 volt.
Currently, Vpp1 should always equal Vpp2.
Return codes:
CS_BAD_HANDLEThe client handle is invalid.
CS_BAD_VPPThe specified Vpp is not available, or Vpp1 does not equal Vpp2.
int MTDHelperEntry(MTDRDYMask, client_handle_t client, mtd_rdy_req_t *req);
typedef struct mtd_rdy_req_t {
u_int Mask;
} mtd_rdy_req_t;
MTDRDYMask selects whether or not CS_EVENT_READY_CHANGE
events will be enabled. The client should already have indicated to
Card Services that it should receive ready change events, via a call
to either RegisterClient or SetEventMask. Ready change
events will be enabled if the CS_EVENT_READY_CHANGE bit is set in
the Mask argument.
Return codes:
CS_BAD_HANDLEThe client handle is invalid.