File-Copy-issue

Error Message:

Title: “Error Copying File or Folder”

“Cannot copy <filename>: The request could not be performed because of an I/O device error.”

When you try to copy files to SDHC card (which is exposed as mass storage through USB client), you may get this error in the middle of file copy. This is due to miscalculation of number of bytes available in the SDHC card by SDBUS driver.

Calculation of card capacity is done based on the C_SIZE value from the CSD (Card-Specific Data) register in the card.

For SDHC, capacity of the card is calculated using the below formula:

Capacity = (C_SIZE + 1) * 0x80000 and sector count is calculated as given below

Sector Count = Capacity / 0x200 (Here, 0x200 is the size of a sector in bytes)

(Where 4112 <= C_SIZE <= 65375 i.e., (approx. 2 GB) < capacity < 32 GB)

In WinCE SDBUS driver the capacity of card is calculated wrongly with the below formula

Capacity = (C_SIZE ) * 0x400 * 0x200

The addition 1 to C_SIZE is not used which makes the card size to be reduced by 0x80000 bytes.

PC recognizes the memory card with actual size and tries to copy the file to those sectors, which is restricted by the SDMemory driver. As the write sector fails when writing to those sectors, PC retries it up to 5 times and finally it pops up the error message as shown above.

 

For Example:

I have used a 8GB Transcend Pen Drive, the C_SIZE read from the CSD is 0x3C15 (15381 in decimal).

As per SDBUS driver formula the capacity of card is 8064073728 bytes and sector count is 15750144. So the SDMemory will restrict the memory access after 15750144th sector. Since PC side calculates the sector count separately based on the CSD data, it computes with actual formula and it will access sectors up to 15751168.

So when PC tries to write after 15750144th sector, SDMemory driver will return as invalid parameter which cause the file copy error as shown above.

 

Fix to be done:

SDBUS Driver needs to be modified which is available in WINCE600\PUBLIC\COMMON\OAK\DRIVERS\ SDCARD\SDBUS

Before making changes in SDBUS driver clone the driver to local platform folder using sysgen capture tool.

For information regarding sysgen capture tool check the following link:

https://msdn.microsoft.com/en-us/library/ee504692(v=winembedded.60).aspx

Code Change:

In InfoQueryCSD function of sddevinfo.cpp the capacity calculation is done. Change the DeviceSize calculation for SD v2.0 (SD_CSD_VERSION_CODE_2_0) as shown below.

Add + 1 to C_SIZE before multiplying with 0x200 and 0x400 for capacity calculation in SDBus driver.

Text in red color is the change to be done.

 
m_SDCardInfo.SDMMCInformation.ullDeviceSize
= ((ULONGLONG) GET_BIT_SLICE_FROM_CSD( pCSD,
  SD_CSD20_CSIZE_BIT_SLICE,
SD_CSD20_CSIZE_SLICE_SIZE ) + 1)
* 0x200 * 0x400;