Next Previous Contents

6. Memory Technology Drivers

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.

6.1 MTD request handling

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:




For a write command that is sized and aligned on erase block boundaries, this specifies that no erase should be performed.


Specifies that writes should be verified.


Indicates that this request is a retry of a previously request that was delayed until the card asserted READY.


Indicates that this request is a retry of a previously request that was delayed by a timeout.


Indicates that this request is the first in a series of requests.


Indicates that this request is the last of a series of requests.


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:


Specifies that the request should be retried after another MTD request currently in progress completes.


Specifies that the request should be continued after the time specified in the timeout field.


Specifies that the request should be continued when the card signals READY, or when the time specified in Timeout elapses, whichever happens first.


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.

6.2 MTD helper functions

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);

MTDRequestWindow, MTDReleaseWindow

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:


Either WIN_MEMORY_TYPE_CM for common memory, or WIN_MEMORY_TYPE_AM for attribute memory.


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:


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:


The client handle is invalid.


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:


The client handle is invalid.

Next Previous Contents