Hi,
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) {