This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

LPC2468 USB-MSD ChanFs FAT32

Dear All

i have a problem with modified version of USB hostlite with Mr Chans FS SFAT32.

DRESULT disk_ioctl(BYTE drv, /* Physical drive number (0..) */
BYTE ctrl, /* Control code */
void *buff /* Buffer to send/receive control data */
)
{
        DRESULT res;
        int result;

        (void) result;

                //The FatFs module uses only device independent commands described below. Any device dependent function is not used.
                //Command Description
                //CTRL_SYNC Make sure that the disk drive has finished pending write process. When the disk I/O module has a write back cache, flush the dirty sector immediately. This command is not required in read-only configuration.
                //GET_SECTOR_SIZE Returns sector size of the drive into the WORD variable pointed by Buffer. This command is not required in single sector size configuration, _MAX_SS is 512.
                //GET_SECTOR_COUNT Returns total sectors on the drive into the DWORD variable pointed by Buffer. This command is used by only f_mkfs function to determine the volume size to be created.
                //GET_BLOCK_SIZE Returns erase block size of the flash memory in unit of sector into the DWORD variable pointed by Buffer. This command is used by only f_mkfs function and it attempts to align data area to the erase block boundary. The allowable value is 1 to 32768 in power of 2. Return 1 if the erase block size is unknown or disk devices.
                if ( drv != 0)  return RES_PARERR;
                if (usb_status & STA_NOINIT) return RES_NOTRDY;
                res = RES_OK;
                switch(ctrl) {
                        case CTRL_SYNC:
                                // TODO
                                break;
                        case GET_SECTOR_SIZE:
                                *(WORD*)buff = blkSize;
                                break;
                        case GET_SECTOR_COUNT:
                                *(DWORD*)buff = numBlks;
                                break;
                        case GET_BLOCK_SIZE:
                                *(DWORD*)buff = 1;
                                break;
                        default:
                                res = RES_PARERR;
                                break;
                }
                return res;
}


This function CTRL_SYNC case is flushing the last f_write call, since it is empty.

Someboby could help me?

V.Nagarajan

Parents
  • Hi Tsuneo.

    I got it resolved by adding SCSI_SYNCHRONIZE_CACHE_10 command in CTRL_SYNC case of disk_ioctl().

    Could i please have your feedback on this.

    
    
    //----------------------------------------------------------------------------
    USB_INT32S  MS_SynchnoniseCache (void)
    {
        USB_INT32S  rc;
    
    
        Fill_MSCommand(0, 0, 0, MS_DATA_DIR_NONE, SCSI_SYNCHRONIZE_CACHE_10, 6);
        rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
        if (rc == OK) {
            rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
            if (rc == OK) {
                if (TDBuffer[12] != 0) {
                    rc = ERR_MS_CMD_FAILED;
                }
            }
        }
        return (rc);
    }
    
    
    DRESULT disk_ioctl(BYTE drv, /* Physical drive number (0..) */
    BYTE ctrl, /* Control code */
    void *buff /* Buffer to send/receive control data */
    )
    {
            DRESULT res;
            int result;
    
            (void) result;
    
    
                    if ( drv != 0)  return RES_PARERR;
                    if (usb_status & STA_NOINIT) return RES_NOTRDY;
                    res = RES_OK;
                    switch(ctrl) {
                            case CTRL_SYNC:
                                    // TODO
                                    MS_SynchnoniseCache();
                                    break;
                            case GET_SECTOR_SIZE:
                                    *(WORD*)buff = blkSize;
                                    break;
                            case GET_SECTOR_COUNT:
                                    *(DWORD*)buff = numBlks;
                                    break;
                            case GET_BLOCK_SIZE:
                                    *(DWORD*)buff = 1;
                                    break;
                            default:
                                    res = RES_PARERR;
                                    break;
                    }
                    return res;
    }
    
    void  Fill_MSCommand (USB_INT32U   block_number,
                          USB_INT32U   block_size,
                          USB_INT16U   num_blocks,
                          MS_DATA_DIR  direction,
                          USB_INT08U   scsi_cmd,
                          USB_INT08U   scsi_cmd_len)
    {
                USB_INT32U  data_len;
        static  USB_INT32U  tag_cnt = 0;
                USB_INT32U  cnt;
    
    
        for (cnt = 0; cnt < CBW_SIZE; cnt++) {
             TDBuffer[cnt] = 0;
        }
        switch(scsi_cmd) {
    
            case SCSI_CMD_TEST_UNIT_READY:
                 data_len = 0;
                 break;
            case SCSI_CMD_READ_CAPACITY:
                 data_len = 8;
                 break;
            case SCSI_CMD_REQUEST_SENSE:
                 data_len = 18;
                 break;
            case SCSI_CMD_INQUIRY:
                     data_len = 36;
                     break;
            default:
                 data_len = block_size * num_blocks;
                 break;
        }
        WriteLE32U(TDBuffer, CBW_SIGNATURE);
        WriteLE32U(&TDBuffer[4], tag_cnt);
        WriteLE32U(&TDBuffer[8], data_len);
        TDBuffer[12]     = (direction == MS_DATA_DIR_NONE) ? 0 : direction;
        TDBuffer[14]     = scsi_cmd_len;                                   /* Length of the CBW                 */
        TDBuffer[15]     = scsi_cmd;
            if(scsi_cmd == SCSI_SYNCHRONIZE_CACHE_10)
            {
                    return;
            }
            else if ((scsi_cmd == SCSI_CMD_REQUEST_SENSE)
         || (scsi_cmd == SCSI_CMD_INQUIRY)) {
            TDBuffer[19] = (USB_INT08U)data_len;
        } else {
            WriteBE32U(&TDBuffer[17], block_number);
        }
        WriteBE16U(&TDBuffer[22], num_blocks);
    }
    
    <\PRE>
    
    Once again thank you for pointing problem somewhere in earlier post.
    V.Nagarajan
    
    
    

Reply
  • Hi Tsuneo.

    I got it resolved by adding SCSI_SYNCHRONIZE_CACHE_10 command in CTRL_SYNC case of disk_ioctl().

    Could i please have your feedback on this.

    
    
    //----------------------------------------------------------------------------
    USB_INT32S  MS_SynchnoniseCache (void)
    {
        USB_INT32S  rc;
    
    
        Fill_MSCommand(0, 0, 0, MS_DATA_DIR_NONE, SCSI_SYNCHRONIZE_CACHE_10, 6);
        rc = Host_ProcessTD(EDBulkOut, TD_OUT, TDBuffer, CBW_SIZE);
        if (rc == OK) {
            rc = Host_ProcessTD(EDBulkIn, TD_IN, TDBuffer, CSW_SIZE);
            if (rc == OK) {
                if (TDBuffer[12] != 0) {
                    rc = ERR_MS_CMD_FAILED;
                }
            }
        }
        return (rc);
    }
    
    
    DRESULT disk_ioctl(BYTE drv, /* Physical drive number (0..) */
    BYTE ctrl, /* Control code */
    void *buff /* Buffer to send/receive control data */
    )
    {
            DRESULT res;
            int result;
    
            (void) result;
    
    
                    if ( drv != 0)  return RES_PARERR;
                    if (usb_status & STA_NOINIT) return RES_NOTRDY;
                    res = RES_OK;
                    switch(ctrl) {
                            case CTRL_SYNC:
                                    // TODO
                                    MS_SynchnoniseCache();
                                    break;
                            case GET_SECTOR_SIZE:
                                    *(WORD*)buff = blkSize;
                                    break;
                            case GET_SECTOR_COUNT:
                                    *(DWORD*)buff = numBlks;
                                    break;
                            case GET_BLOCK_SIZE:
                                    *(DWORD*)buff = 1;
                                    break;
                            default:
                                    res = RES_PARERR;
                                    break;
                    }
                    return res;
    }
    
    void  Fill_MSCommand (USB_INT32U   block_number,
                          USB_INT32U   block_size,
                          USB_INT16U   num_blocks,
                          MS_DATA_DIR  direction,
                          USB_INT08U   scsi_cmd,
                          USB_INT08U   scsi_cmd_len)
    {
                USB_INT32U  data_len;
        static  USB_INT32U  tag_cnt = 0;
                USB_INT32U  cnt;
    
    
        for (cnt = 0; cnt < CBW_SIZE; cnt++) {
             TDBuffer[cnt] = 0;
        }
        switch(scsi_cmd) {
    
            case SCSI_CMD_TEST_UNIT_READY:
                 data_len = 0;
                 break;
            case SCSI_CMD_READ_CAPACITY:
                 data_len = 8;
                 break;
            case SCSI_CMD_REQUEST_SENSE:
                 data_len = 18;
                 break;
            case SCSI_CMD_INQUIRY:
                     data_len = 36;
                     break;
            default:
                 data_len = block_size * num_blocks;
                 break;
        }
        WriteLE32U(TDBuffer, CBW_SIGNATURE);
        WriteLE32U(&TDBuffer[4], tag_cnt);
        WriteLE32U(&TDBuffer[8], data_len);
        TDBuffer[12]     = (direction == MS_DATA_DIR_NONE) ? 0 : direction;
        TDBuffer[14]     = scsi_cmd_len;                                   /* Length of the CBW                 */
        TDBuffer[15]     = scsi_cmd;
            if(scsi_cmd == SCSI_SYNCHRONIZE_CACHE_10)
            {
                    return;
            }
            else if ((scsi_cmd == SCSI_CMD_REQUEST_SENSE)
         || (scsi_cmd == SCSI_CMD_INQUIRY)) {
            TDBuffer[19] = (USB_INT08U)data_len;
        } else {
            WriteBE32U(&TDBuffer[17], block_number);
        }
        WriteBE16U(&TDBuffer[22], num_blocks);
    }
    
    <\PRE>
    
    Once again thank you for pointing problem somewhere in earlier post.
    V.Nagarajan
    
    
    

Children
No data