我们现在使用的是sirfA4芯片做的产品,使用它的USB口用于U盘读播MP3和视频文件,之前发现USB口出现这样问题:有个次品U盘(标称容量16G,实际容量只有4G),在电脑上都能正常读写数据,没有什么问题,但是拿到我们机器上就出现插入U盘可以识别,但是会经常性的出现读数据失败,USB识别到断开的情况。
追踪程序发现读取Csw 长度为0,此时会重新初始化,造成USB disk重新枚举,但是怎么也不能再读到U盘的数据,只有重新拔插才能正常工作。偶然机会发现,在读U盘数据时如果没有运行其他程序,出错的几率会小很多,于是判断是对USB的响应中出现了中断去做其他事情造成不能及时相应,兼容性不好的U盘就会死机,所以出现问题,只要及时响应USB操作,应该能解决此问题。 最后在 disK.C中增加以下代码解决此问题:
case DISK_IOCTL_WRITE:
{
DEBUGMSG(ZONE_DSK_IOCTL, (TEXT("USBDISK6>DSK_IOControl>%s\r\n"),
(bRead ? TEXT("IOCTL_DISK_READ"):TEXT("IOCTL_DISK_WRITE"))));
// Sterilize the caller's SG_REQ.
if (!SterilizeIoRequest(
pDevice->pSterileIoRequest,
(PSG_REQ)pInBuf,
InBufLen)
) {
dwErr = ERROR_INVALID_PARAMETER;
break;
}
// If write, ensure that the device is not write-protected.
if (!bRead && pDevice->Flags.WriteProtect) {
dwErr = ERROR_WRITE_PROTECT;
break;
}
pDevice->Flags.MediumChanged = FALSE;
// Initiate I/O. Note that, to determine if ScsiRWSG succeeded,
// we are required to inspect the sr_status. It's safe to do so,
// because pSterileIoRequest is our safe copy of the caller's
// SG_REQ.
#if MXcompatible
dwThreadID = GetCurrentThread();
dwThreadPri = CeGetThreadPriority(dwThreadID);
dwThreadQuantum = CeGetThreadQuantum(dwThreadID);
CeSetThreadPriority(dwThreadID, 0);
CeSetThreadQuantum(dwThreadID, 0);
try
{
#endif
SafeBytesReturned = ScsiRWSG(
pDevice,
pDevice->pSterileIoRequest,
pDevice->Lun,
bRead
);
#if MXcompatible
}
except(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ?
EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
{
dwErr = pDevice->pSterileIoRequest->sr_status;
CeSetThreadQuantum(dwThreadID, dwThreadQuantum);
CeSetThreadPriority(dwThreadID, dwThreadPri);
break;
}
CeSetThreadQuantum(dwThreadID, dwThreadQuantum);
CeSetThreadPriority(dwThreadID, dwThreadPri);
#endif