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_ACTION
Either MTD_REQ_ERASE
, MTD_REQ_READ
, MTD_REQ_WRITE
, or
MTD_REQ_COPY
.
MTD_REQ_NOERASE
For a write command that is sized and aligned on erase block boundaries, this specifies that no erase should be performed.
MTD_REQ_VERIFY
Specifies that writes should be verified.
MTD_REQ_READY
Indicates that this request is a retry of a previously request that
was delayed until the card asserted READY
.
MTD_REQ_TIMEOUT
Indicates that this request is a retry of a previously request that was delayed by a timeout.
MTD_REQ_FIRST
Indicates that this request is the first in a series of requests.
MTD_REQ_LAST
Indicates that this request is the last of a series of requests.
MTD_REQ_KERNEL
Indicates 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_WAITREQ
Specifies that the request should be retried after another MTD request currently in progress completes.
MTD_WAITTIMER
Specifies that the request should be continued after the time
specified in the timeout
field.
MTD_WAITRDY
Specifies that the request should be continued when the card signals
READY
, or when the time specified in Timeout
elapses,
whichever happens first.
MTD_WAITPOWER
Specifies 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_TYPE
Either WIN_MEMORY_TYPE_CM
for common memory, or
WIN_MEMORY_TYPE_AM
for attribute memory.
WIN_USE_WAIT
Specifies 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_HANDLE
The 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_HANDLE
The client handle is invalid.
CS_BAD_VPP
The 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_HANDLE
The client handle is invalid.