SDIO: Is cmd53 tested with sdbus driver in XP, SP2 for block mode ?

  • Thread starter Thread starter esha
  • Start date Start date
E

esha

I'm doing sdio driver on XP SP2. This SDIO driver is compiled using 2003
SP1 ddk. SDIO card is coming up properly and i could do several
operations using CMD52 (read/write etc). I have not enabled the
interrupts yet. Now, i'm trying the CMD53. CMD53 works fine in byte
mode. That is BlockMode in SD_RW_EXTENDED_ARGUMENT is set to 0 and the
parameters in SDCMD_DESCRIPTOR set to SDTT_SINGLE_BLOCK and SDRT_5.

But when i try the SDTT_MULTI_BLOCK mode, the command sent on the bus
is not proper. I captured the CMD53 on the bus using LA, and this is
what i found.

My block size set was 4 bytes. I was trying to read/write 8 bytes so
that two blocks of transaction should happen. But all the time, the
CMD53 on the bus had 8 as Block Count. After i did some different
exercise, i found that the Parameters.DeviceCommand.Length is sent as
block count for CMD53 instead of .u.bits.Count in
SD_RW_EXTENDED_ARGUMENT. (I made sure that the Block Mode in
SD_RW_EXTENDED_ARGUMENT is set to 1 so that even on the bus i see the
same for cmd53. I do not see any response from the SDIO card for this
and also, the bus driver is returning back, 0xC0000185 or
0x80000011..
My sdio card supports block mode (the card capability reg- 0x08 of cccr
reads 0x1F .....)

Is the bus driver in XP SP2 tested with CMD53 block mode (or
SDTT_MULTI_BLOCK) ?
I have attached the CMD53 function i've written, along with this
mail... Please let me know if there is any problem.

Please help !

Rgds
Esha
------------------------------------
NTSTATUS
SdioReadWriteBuffer(PDEVICE_OBJECT fdo,IN ULONG Function,IN PUCHAR
PBuffer,IN ULONG Address,
IN UCHAR BlockMode,IN ULONG Length,IN BOOLEAN WriteToDevice,OUT PULONG
BytesRead)
{
PFDO_DATA fdoData;
PSDBUS_REQUEST_PACKET sdrp;
SD_RW_EXTENDED_ARGUMENT extendedArgument;
NTSTATUS status = STATUS_SUCCESS;
PMDL Mdl=NULL;
UCHAR i;
PUCHAR pBuf=NULL;
ULONG BlockSize=0;
ULONG len = Length;
ULONG Data=0;
SDCMD_DESCRIPTOR ReadIoExtendedDesc =
{SDCMD_IO_RW_EXTENDED, SDCC_STANDARD,SDTD_READ,
SDTT_MULTI_BLOCK , SDRT_5};
//{SDCMD_IO_RW_EXTENDED, SDCC_STANDARD,SDTD_READ,
SDTT_MULTI_BLOCK , SDRT_1};

SDCMD_DESCRIPTOR WriteIoExtendedDesc =
{SDCMD_IO_RW_EXTENDED, SDCC_STANDARD,SDTD_WRITE,
SDTT_MULTI_BLOCK , SDRT_5};

fdoData = (PFDO_DATA)fdo->DeviceExtension;

SdioDbgPrint(TRACE,"cmd53: fn %d len %d,add 0x%X blkmode %d WrRd
%d\n",Function,
Length,Address,BlockMode,WriteToDevice);
if(BlockMode == BYTE_MODE)
{
ReadIoExtendedDesc.TransferType = SDTT_SINGLE_BLOCK;
WriteIoExtendedDesc.TransferType = SDTT_SINGLE_BLOCK;
//len = BlockSize;
len = Length;
}
else
{
//(Function == FN0) ? (BlockSize = fdoData->BlockSizeFN0) :
(BlockSize = fdoData->BlockSizeFNx);
//status = SdioReadWriteByte(fdo,
FN0,(PUCHAR)&BlockSize,FN0_BLOCK_SIZE_REG,FALSE);

//just for testing, make sure that the same is written in
FN0_BLOCK_SIZE_REG before running this
BlockSize = 0x04;
SdioDbgPrint(TRACE,"\nBlksize 0x%X\n",BlockSize);

//Round of the length to the block size
if(Length % BlockSize)
len = (((Length / BlockSize) * BlockSize) + BlockSize);
else
len = ((Length / BlockSize) * BlockSize);
}

SdioDbgPrint(TRACE,"Calc len 0x%X\n",len);
pBuf = ExAllocatePool(NonPagedPool,len);
if (!pBuf) {
return STATUS_INSUFFICIENT_RESOURCES;
}

RtlZeroMemory(pBuf, len);
if (WriteToDevice)
RtlCopyMemory(pBuf,PBuffer, Length);
// first, get an MDL to map the data. Call IoAllocateMdl to
// allocate an MDL and pass in a pointer to a buffer //
allocated from the non-paged pool.
Mdl = IoAllocateMdl(pBuf, len, FALSE, FALSE, NULL);
if (Mdl == NULL) {
ExFreePool(pBuf);
return STATUS_INSUFFICIENT_RESOURCES;
}

MmBuildMdlForNonPagedPool (Mdl);
// next, allocate a request packet for the arguments of the command
sdrp = ExAllocatePool(NonPagedPool, sizeof(SDBUS_REQUEST_PACKET));
if (!sdrp) {
IoFreeMdl(Mdl);
return STATUS_INSUFFICIENT_RESOURCES;
}
RtlZeroMemory(sdrp, sizeof(SDBUS_REQUEST_PACKET));
sdrp->RequestFunction = SDRF_DEVICE_COMMAND;
extendedArgument.u.AsULONG = 0;
if(BlockMode == BYTE_MODE)
{
extendedArgument.u.bits.BlockMode = 0;
extendedArgument.u.bits.Count = len;
}
else
{
extendedArgument.u.bits.BlockMode = 1;
extendedArgument.u.bits.Count = len / BlockSize;
}
SdioDbgPrint(TRACE,"cmd53:set Count %d, blkmode
%d\n",extendedArgument.u.bits.Count,
extendedArgument.u.bits.BlockMode);
extendedArgument.u.bits.Function = Function;
extendedArgument.u.bits.OpCode = 1; // increment
address
extendedArgument.u.bits.Address = Address;

if (WriteToDevice) {
extendedArgument.u.bits.WriteToDevice = 1;
sdrp->Parameters.DeviceCommand.CmdDesc = WriteIoExtendedDesc;

} else {
extendedArgument.u.bits.WriteToDevice = 0;
sdrp->Parameters.DeviceCommand.CmdDesc = ReadIoExtendedDesc;
}
sdrp->Parameters.DeviceCommand.Argument =
extendedArgument.u.AsULONG;
sdrp->Parameters.DeviceCommand.Mdl = Mdl;

//This send the Block Count in CMD3 as the blocksize * num of block
and
//makes the system crash - BSOD
//sdrp->Parameters.DeviceCommand.Length = len;

//With this the SdBusSubmitRequest returns 0xc0000185 status and
//the Block count in CMD53 gets the actual byte read/write length
//sdrp->Parameters.DeviceCommand.Length = Length;

//This send the Block Count in CMD3 as proper block count, but still
the
//bus drivers gives status as 0xc0000185 or 0x80000011
sdrp->Parameters.DeviceCommand.Length =
extendedArgument.u.bits.Count; //len;


// finally, submit the request
status = SdBusSubmitRequest(fdoData->SDBusInterface.Context,sdrp);

SdioDbgPrint(TRACE,"cmd53: resplen: %d\n",sdrp->ResponseLength);
SdioDbgPrint(TRACE,"cmd53: sts: %X \n",status);
SdioDbgPrint(TRACE,"cmd53: info: %X\n",sdrp->Information);

if (NT_SUCCESS(status) && !WriteToDevice) {
*BytesRead = Length;
RtlCopyMemory(PBuffer, pBuf, Length);
}
IoFreeMdl(Mdl);
ExFreePool(pBuf);
ExFreePool(sdrp);
return status;
}
 
A couple of months ago, I was developing an SDIO driver for XP SP2 and I
believe we had CMD53 block mode working. I think your problem is setting
SD_RW_EXTENDED_ARGUMENT to 0. I seem to remember there are parameters that
are needed. If you look at the source in the example from MS:

excerpt from
http://msdn.microsoft.com/library/e..._97e9062d-965e-46bd-a399-7cd60bf932fa.xml.asp

// then, set up the argument and command descriptor
sdIoArgument.u.AsULONG = 0; // <---- INITIALIZATION ONLY
sdIoArgument.u.bits.Address = Offset;

// retrieve function number, the driver previously initialized
// this value with the SdBus GetProperty call
sdIoArgument.u.bits.Function = pDevExt->FunctionNumber;
sdIoArgument.u.bits.WriteToDevice = 1;

sdrp->Parameters.DeviceCommand.Argument =
sdIoArgument.u.AsULONG;

Setting the ext args to 0 is only initializing the variable. Notice that
for simplicity, the ext args is really a separate local variable, which is
setup and then transferred into the sdrp structure. Within the ext args,
you should set the Function, Address, WriteToDevice and other fields. Then
the separate ext arg variable is then transferred into
sdrp->Parameters.DeviceCommand.Argument member.

I hope this helps

((&->
 
Back
Top