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:

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.

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.

MTDModifyWindow

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.

MTDSetVpp

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.

MTDRDYMask

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.


Next Previous Contents