lun.c
上传用户:sourcesun
上传日期:2013-09-23
资源大小:362k
文件大小:9k
源码类别:

DNA

开发平台:

Asm

  1. /*************************************************************************
  2.  *
  3.  *    Used with ICCARM and AARM.
  4.  *
  5.  *    (c) Copyright IAR Systems 2005
  6.  *
  7.  *    File name   : lun0.c
  8.  *    Description : USB Mass storage device LUNs
  9.  *
  10.  *    History :
  11.  *    1. Data        : November 15, 2005
  12.  *       Author      : Stanimir Bonev
  13.  *       Description : Create
  14.  *
  15.  *    $Revision: 1.2.2.1 $
  16. **************************************************************************/
  17. #define LUN_GOBALS
  18. #include "lun.h"
  19. #define LCD_BACKLIGHT_ON()    (IO0SET_bit.P0_21 = 1)
  20. #define LCD_BACKLIGHT_OFF()   (IO0CLR_bit.P0_21 = 1)
  21. LunFpnt_t LunFun [SCSI_LUN_NUMB] =
  22. {
  23.   // Lun0
  24.   {
  25.     // Init
  26.     NULL,
  27.     // Info
  28.     NULL,
  29.     // Status
  30.     NULL,
  31.     // Io
  32.     NULL,
  33.   },
  34.   // Lun1
  35.   {
  36.     // Init
  37.     NULL,
  38.     // Info
  39.     NULL,
  40.     // Status
  41.     NULL,
  42.     // Io
  43.     NULL,
  44.   },
  45. };
  46. #pragma location="DMA_RAM"
  47. #pragma data_alignment=4
  48. __no_init Int8U Lun0Buffer[2048];
  49. /*************************************************************************
  50.  * Function Name: LunInit
  51.  * Parameters: Int32U LunInd,
  52.  *             DiskInitFpnt_t DiskInitFpnt, DiskInfoFpnt_t DiskInfoFpnt,
  53.  *             DiskStatusFpnt_t DiskStatusFpnt, DiskIoFpnt_t, DiskIoFpnt
  54.  *
  55.  * Return: none
  56.  *
  57.  * Description: LUN Init
  58.  *
  59.  *************************************************************************/
  60. void LunInit (Int32U LunInd,
  61.               DiskInitFpnt_t DiskInitFpnt, DiskInfoFpnt_t DiskInfoFpnt,
  62.               DiskStatusFpnt_t DiskStatusFpnt, DiskIoFpnt_t DiskIoFpnt)
  63. {
  64.   LunFun[LunInd].DiskInitFpnt   = DiskInitFpnt;
  65.   LunFun[LunInd].DiskInfoFpnt   = DiskInfoFpnt;
  66.   LunFun[LunInd].DiskStatusFpnt = DiskStatusFpnt;
  67.   LunFun[LunInd].DiskIoFpnt     = DiskIoFpnt;
  68. }
  69. /*************************************************************************
  70.  * Function Name: LunImp
  71.  * Parameters:  none
  72.  *
  73.  * Return: none
  74.  *
  75.  * Description: LUN commands implementation
  76.  *
  77.  *************************************************************************/
  78. void LunImp (Int32U LunInd)
  79. {
  80. static LunState_t LunState;
  81. static Int32U BlockStart, BlockNum;
  82. pLunFpnt_t Lun = &LunFun[LunInd];
  83. pDiskStatus_t pDiskStatus;
  84.   if(pScsiMessage[LunInd] == NULL)
  85.   {
  86.     return;
  87.   }
  88.   // Get a message
  89.   Int32U Message   = *pScsiMessage[LunInd];
  90.   pInt32U pMessage = pScsiMessage[LunInd]+1;
  91.   // Clear the message pointer
  92.   pScsiMessage[LunInd] = NULL;
  93.   if (Message == LunInitMsg)
  94.   {
  95.     Lun->DiskInitFpnt();
  96.     LunState = LunCommandDecode;
  97.     return;
  98.   }
  99.   if (Message == LunResetReqMsg)
  100.   {
  101.     LunState = LunCommandDecode;
  102.     return;
  103.   }
  104.   switch (LunState)
  105.   {
  106.   case LunCommandDecode:
  107.     switch (Message)
  108.     {
  109.     case LunInquiryReqMsg:
  110.       ScsiInquiryData(Lun0Buffer,Lun->DiskInfoFpnt(Lun0Buffer,DiskInquiry));
  111.       break;
  112.     case LunTestUntilReadyReqMsg:
  113.       pDiskStatus = Lun->DiskStatusFpnt();
  114.       switch (pDiskStatus->DiskStatus)
  115.       {
  116.       case DiskCommandPass:
  117.         if (pDiskStatus->MediaChanged)
  118.         {
  119.           ScsiTestUntilReadyData(ScsiMediaChanged);
  120.           pDiskStatus->MediaChanged = FALSE;
  121.         }
  122.         else
  123.         {
  124.           ScsiTestUntilReadyData(ScsiCommandNoKey);
  125.         }
  126.         break;
  127.       case DiskNotReady:
  128.         ScsiTestUntilReadyData(ScsiMediamNotReady);
  129.         break;
  130.       case DiskNotPresent:
  131.         ScsiTestUntilReadyData(ScsiMediaNotPresent);
  132.         break;
  133.       case DiskChanged:
  134.         ScsiTestUntilReadyData(ScsiMediaChanged);
  135.         break;
  136.       default:
  137.         ScsiTestUntilReadyData(ScsiFatalError);
  138.         break;
  139.       }
  140.       break;
  141.     case LunModeSense6ReqMsg:
  142.       ScsiModeSenseData(Lun->DiskStatusFpnt()->WriteProtect);
  143.       break;
  144.     case LunReadFormatCapacityReqMsg:
  145.       ScsiReadFormatCapcityData(Lun0Buffer,Lun->DiskInfoFpnt(Lun0Buffer,DiskFormatCapacity));
  146.       break;
  147.     case LunReadCapacity10ReqMsg:
  148.       ScsiReadCapacityData(Lun->DiskStatusFpnt()->BlockNumb-1,
  149.                            Lun->DiskStatusFpnt()->BlockSize);
  150.       break;
  151.     case LunRead10ReqMsg:
  152.       BlockStart = *pMessage;
  153.       BlockNum = *++pMessage;
  154.       if ((BlockStart + BlockNum) > Lun->DiskStatusFpnt()->BlockNumb)
  155.       {
  156.         ScsiCmdError(ScsiInvalidCbd,ScsiStallIn);
  157.         break;
  158.       }
  159.       switch(Lun->DiskIoFpnt(Lun0Buffer,BlockStart++,1,DiskRead))
  160.       {
  161.       case DiskCommandPass:
  162.         ScsiReadData(Lun0Buffer,
  163.                      Lun->DiskStatusFpnt()->BlockSize,
  164.                      (--BlockNum == 0));
  165.         if(BlockNum)
  166.         {
  167.           LunState = LunRead;
  168.         }
  169.         break;
  170.       case DiskNotReady:
  171.         // the Media not ready
  172.         ScsiCmdError(ScsiMediamNotReady,ScsiStallIn);
  173.         break;
  174.       case DiskNotPresent:
  175.         // the Media not present
  176.         ScsiCmdError(ScsiMediaNotPresent,ScsiStallIn);
  177.         break;
  178.       default:
  179.         ScsiCmdError(ScsiFatalError,ScsiStallIn);
  180.         break;
  181.       }
  182.       break;
  183.     case LunWrite10ReqMsg:
  184.       BlockStart = *pMessage;
  185.       BlockNum = *++pMessage;
  186.       if ((BlockStart + BlockNum) > Lun->DiskStatusFpnt()->BlockNumb)
  187.       {
  188.         ScsiCmdError(ScsiInvalidCbd,ScsiStallOut);
  189.         break;
  190.       }
  191.       ScsiWriteData(Lun0Buffer,
  192.                     Lun->DiskStatusFpnt()->BlockSize,
  193.                     FALSE);
  194.       LunState = LunWrite;
  195.       break;
  196.     case LunVerify10BytChkReqMsg:
  197.       BlockStart = *pMessage;
  198.       BlockNum = *++pMessage;
  199.       if ((BlockStart + BlockNum) > Lun->DiskStatusFpnt()->BlockNumb)
  200.       {
  201.         ScsiCmdError(ScsiInvalidCbd,ScsiStallOut);
  202.         break;
  203.       }
  204.       ScsiWriteData(Lun0Buffer,
  205.                     Lun->DiskStatusFpnt()->BlockSize,
  206.                     FALSE);
  207.       LunState = LunVerify;
  208.       break;
  209.     case LunVerify10ReqMsg:
  210.       BlockStart = *pMessage;
  211.       BlockNum = *++pMessage;
  212.       if ((BlockStart + BlockNum) > Lun->DiskStatusFpnt()->BlockNumb)
  213.       {
  214.         ScsiCmdError(ScsiInvalidCbd,ScsiStallOut);
  215.         break;
  216.       }
  217.       // Always pass
  218.       ScsiWriteData(NULL,0,TRUE);
  219.       break;
  220.     default:
  221.       // Unknow command
  222.       ScsiCmdError(ScsiUnknowCommand,ScsiStallBoth);
  223.       break;
  224.     }
  225.     break;
  226.   case LunRead:
  227.     switch(Lun->DiskIoFpnt(Lun0Buffer,BlockStart++,1,DiskRead))
  228.     {
  229.     case DiskCommandPass:
  230.       ScsiReadData(Lun0Buffer,
  231.                    Lun->DiskStatusFpnt()->BlockSize,
  232.                    (--BlockNum == 0));
  233.       if(BlockNum == 0)
  234.       {
  235.         LunState = LunCommandDecode;
  236.       }
  237.       break;
  238.     case DiskNotReady:
  239.       // the Media not ready
  240.       ScsiCmdError(ScsiMediamNotReady,ScsiStallIn);
  241.       LunState = LunCommandDecode;
  242.       break;
  243.     case DiskNotPresent:
  244.       // the Media not present
  245.       ScsiCmdError(ScsiMediaNotPresent,ScsiStallIn);
  246.       LunState = LunCommandDecode;
  247.       break;
  248.     default:
  249.       ScsiCmdError(ScsiFatalError,ScsiStallIn);
  250.       LunState = LunCommandDecode;
  251.       break;
  252.     }
  253.     break;
  254.   case LunWrite:
  255.     if(Message == LunDataReadyMsg)
  256.     {
  257.       switch(Lun->DiskIoFpnt(Lun0Buffer,BlockStart++,1,DiskWrite))
  258.       {
  259.       case DiskCommandPass:
  260.         if(--BlockNum == 0)
  261.         {
  262.           ScsiWriteData(NULL,0,TRUE);
  263.           LunState = LunCommandDecode;
  264.         }
  265.         else
  266.         {
  267.         ScsiWriteData(Lun0Buffer,
  268.                       Lun->DiskStatusFpnt()->BlockSize,
  269.                       FALSE);
  270.         }
  271.         break;
  272.       case DiskNotReady:
  273.         // the Media not ready
  274.         ScsiCmdError(ScsiMediamNotReady,ScsiStallOut);
  275.         LunState = LunCommandDecode;
  276.         break;
  277.       case DiskNotPresent:
  278.         // the Media not present
  279.         ScsiCmdError(ScsiMediaNotPresent,ScsiStallOut);
  280.         LunState = LunCommandDecode;
  281.         break;
  282.       default:
  283.         ScsiCmdError(ScsiFatalError,ScsiStallOut);
  284.         LunState = LunCommandDecode;
  285.         break;
  286.       }
  287.     }
  288.     else
  289.     {
  290.       LunState = LunCommandDecode;
  291.     }
  292.     break;
  293.   case LunVerify:
  294.     if(Message == LunDataReadyMsg)
  295.     {
  296.       switch(Lun->DiskIoFpnt(Lun0Buffer,BlockStart++,1,DiskVerify))
  297.       {
  298.       case DiskCommandPass:
  299.         if(--BlockNum == 0)
  300.         {
  301.           ScsiWriteData(NULL,0,TRUE);
  302.           LunState = LunCommandDecode;
  303.         }
  304.         else
  305.         {
  306.         ScsiWriteData(Lun0Buffer,
  307.                       Lun->DiskStatusFpnt()->BlockSize,
  308.                       FALSE);
  309.         }
  310.         break;
  311.       case DiskMiscompareError:
  312.         ScsiCmdError(ScsiMediaNotPresent,ScsiStallOut);
  313.         LunState = LunCommandDecode;
  314.         break;
  315.       case DiskNotReady:
  316.         // the Media not ready
  317.         ScsiCmdError(ScsiMediamNotReady,ScsiStallOut);
  318.         LunState = LunCommandDecode;
  319.         break;
  320.       case DiskNotPresent:
  321.         // the Media not present
  322.         ScsiCmdError(ScsiMediaNotPresent,ScsiStallOut);
  323.         LunState = LunCommandDecode;
  324.         break;
  325.       default:
  326.         ScsiCmdError(ScsiFatalError,ScsiStallOut);
  327.         LunState = LunCommandDecode;
  328.         break;
  329.       }
  330.     }
  331.     else
  332.     {
  333.       LunState = LunCommandDecode;
  334.     }
  335.     break;
  336.   default:
  337.     // something is wrong
  338.     ScsiCmdError(ScsiFatalError,ScsiStallBoth);
  339.     LunState = LunCommandDecode;
  340.     break;
  341.   }
  342.   if(LunState != LunCommandDecode)
  343.   {
  344.     LCD_BACKLIGHT_ON();
  345.   }
  346.   else
  347.   {
  348.     LCD_BACKLIGHT_OFF();
  349.   }
  350. }