hdd_if.c
上传用户:poi891205
上传日期:2013-07-15
资源大小:9745k
文件大小:11k
源码类别:

DVD

开发平台:

C/C++

  1. /*=================================================================
  2.   hdd_if.c: Some ATA Control for HDD
  3.   
  4.   2002-04-04 10:00AM Created  by cyue
  5.   2002-04-28 10:00AM modified by Verdure
  6.   2002-06-12 08:42AM Modified by cyue
  7.   
  8. Copyright(c)2000-2002 by Worldplus Technology (ShenZhen) Co., Ltd.
  9. ALL RIGHTS RESERVED
  10. =================================================================*/
  11. #include "misc.h"
  12. #include "set.h"
  13. #include "global.h"
  14. #include "ata.h"
  15. #include "atapi_if.h"
  16. #include "image.h"
  17. #include "fs.h"
  18. #include "func.h"
  19. #include "cderr.h"
  20. #include "avd.h"
  21. #include "hdd_if.h"
  22. #include "hdd_if.h"
  23. #ifdef USE_HDD // cyue: Skip code if not use hdd!!
  24. #define DBG_HDD
  25. #ifndef DBG_HDD
  26. #undef printf
  27. #undef print_block
  28. #define printf(f, a...) {}
  29. #define print_block(x,y) {}
  30. #endif
  31. //extern UINT8 CSSEnable;
  32. #define   POLLING_MODE
  33. #ifdef  POLLING_MODE //for new D version chip
  34. #define DVDDSP_CONFIG_DEF ATAPI_ADV_POLLING
  35. #else
  36. #define DVDDSP_CONFIG_DEF ATAPI_INTR_MODE
  37. #endif
  38. #define SHORT_TIME_OUT (1*90)//1 sec //4 sec
  39. #define NORMAL_TIME_OUT (7*90)//7 sec 
  40. #define LONG_TIME_OUT (8*90)//8 sec
  41. #define MAX_TIME_OUT (10*90)//10 sec
  42. /* Check whether HD present */
  43. UINT8 HDD_DEV_Existence(void)
  44. {
  45. /* read Status register until BSY=0 & DRQ=0 */
  46. if(atapi_chk_time_out(WAIT_DRQ_BSY_ZERO,NORMAL_TIME_OUT))  //wait 8sec
  47. {          
  48. printf("ATA BUS NOT READY!n");
  49. return ATAPI_ERROR;
  50. }
  51. atapi_reg_write(IDE_DEVICE_HEAD, HDD_DEV);
  52. /* read Status register until BSY=0 & DRQ=0 */
  53. if(atapi_chk_time_out(WAIT_DRQ_BSY_ZERO,NORMAL_TIME_OUT))
  54. {                   
  55. printf("HD NOT READY!!n");
  56. return ATAPI_ERROR;
  57. }  
  58. return 0;
  59. }
  60. /* Identify the device before issuing the command to a device */
  61. void HDD_DEV_Identify(void)
  62. {  
  63. while(atapi_reg_read(IDE_STATUS) & (STATUS_BSY | STATUS_DRQ)) ;
  64. atapi_reg_write(IDE_DEVICE_HEAD,HDD_DEV);
  65. atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns
  66. while(atapi_reg_read(IDE_STATUS) & (STATUS_BSY | STATUS_DRQ)) ;
  67. return;
  68. }
  69. //int ATA_Read(UINT32 lba,UINT32 seccnt)
  70. //UINT8 atapi_do_packet(UINT8 *pck)
  71. UINT8 hdd_do_packet( UINT32 wait_time, UINT8 *pck)
  72. {
  73.     //UINT32 wait_time=0;
  74. //printf(__FUNCTION__":");
  75.     //printf("--sec=%d,lba=%lxnn",*(pck+9),
  76.     //    (*(pck+2)<<24) | (*(pck+3)<<16) | (*(pck+4)<<8) | *(pck+5) );
  77.     if (dev_status_flag&READ_PRESENT_DATA)
  78. wait_time=SHORT_TIME_OUT;
  79.     else
  80. wait_time=NORMAL_TIME_OUT;
  81.     //HDD_DEV_Identify();
  82.     if (atapi_chk_time_out(WAIT_ALT_NO_BUSY,wait_time))
  83.     {                   
  84. //printf(__FUNCTION__" ==> Timout 1n");
  85. cderr_handler(CDERR_ATA_BUSY);
  86. return ATAPI_ERROR;
  87.     }
  88.     atapi_reg_write(IDE_DEVICE_HEAD,HDD_DEV|(*(pck+2)&0x0f));
  89.     atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns
  90.     atapi_reg_write(IDE_SECTOR_CNT,*(pck+9));
  91.     atapi_reg_write(IDE_SECTOR_NUM,*(pck+5));
  92.     atapi_reg_write(IDE_CYLINDER_LO,*(pck+4));
  93.     atapi_reg_write(IDE_CYLINDER_HI,*(pck+3));
  94.     atapi_reg_write(IDE_COMMAND,0x20);
  95.     atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns
  96. if (atapi_chk_time_out(WAIT_IRQ,MAX_TIME_OUT))
  97. {                   
  98. //printf(__FUNCTION__" ==>< IRQ Timout >n");
  99. cderr_handler(CDERR_ATA_BUSY);
  100. return ATAPI_ERROR;
  101. }
  102. if (atapi_chk_time_out(WAIT_STATUS_NO_BSY,wait_time))
  103. {                   
  104. //printf(__FUNCTION__" ==> Timout 4n");
  105. cderr_handler(CDERR_ATA_BUSY);
  106. return ATAPI_ERROR;
  107. }
  108.     atapi_reg_read(IDE_ALT_STATUS);
  109.     if (atapi_is_error() != 0) 
  110.     {
  111.         //printf("send_data in do_packet errorn");
  112.         return ATAPI_ERROR;
  113.     }
  114.     return ATAPI_OK;
  115. int HDD_PIO_ReadData(UINT8 *buff)
  116. {
  117.     int i;
  118.     while(1)
  119.     {
  120. atapi_reg_read(IDE_ALT_STATUS);
  121.         switch(atapi_reg_read(IDE_STATUS)&(STATUS_BSY|STATUS_DRQ))
  122. {
  123. case STATUS_DRQ: //Need Data Transfer
  124. for(i=0;i<256;i++) // Sector Block Transfer
  125. {
  126. register UINT16 data=atapi_reg_read(IDE_DATA);
  127. *buff++=data&0xFF;
  128. *buff++=data>>8;
  129. }
  130. break;
  131. case 0: // Done
  132. atapi_reg_read(IDE_ALT_STATUS);
  133. atapi_reg_read(IDE_STATUS);
  134. return 0;
  135. case STATUS_BSY: // ATA Device Busy
  136. break;
  137. default:
  138.     break;
  139. }
  140.     }
  141.     return 0;
  142. }
  143. int HDD_PIO_WriteData(UINT8 *buff)
  144. {
  145.     int i;
  146.     while(1)
  147.     {
  148. switch(atapi_reg_read(IDE_STATUS)&(STATUS_BSY|STATUS_DRQ))
  149. {
  150. case STATUS_DRQ: //Need Data Transfer
  151. for(i=0;i<256;i++) // Sector Block Transfer
  152. {
  153. register UINT16 data= *buff+(*(buff+1))*256;
  154. atapi_reg_write(IDE_DATA,data);
  155. buff+=2;
  156. }
  157. break;
  158. case 0: // Done
  159. atapi_reg_read(IDE_ALT_STATUS);
  160. atapi_reg_read(IDE_STATUS);
  161. return 0;
  162. case STATUS_BSY: // ATA Device Busy
  163. break;
  164. default:
  165.     break;
  166. }
  167.     }
  168.     return 0;
  169. }
  170. int HDD_ReadSec(UINT8 *buff,UINT32 lba,int seccnt)
  171. {
  172. //printf(__FUNCTION__":nn");
  173. HDD_DEV_Identify();
  174. atapi_reg_write(IDE_DEVICE_HEAD,HDD_DEV|(lba>>24));
  175. atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns
  176. atapi_reg_write(IDE_SECTOR_CNT,seccnt);
  177. atapi_reg_write(IDE_SECTOR_NUM,lba&0xFF);
  178. atapi_reg_write(IDE_CYLINDER_LO,(lba>>8)&0xFF);
  179. atapi_reg_write(IDE_CYLINDER_HI,(lba>>16)&0xFF);
  180. atapi_reg_write(IDE_COMMAND,0x20);
  181. atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns
  182. return HDD_PIO_ReadData(buff);
  183. int HDD_WriteSec(UINT8 *buff,UINT32 lba,int seccnt)
  184. {
  185. //printf(__FUNCTION__":nn");
  186. HDD_DEV_Identify();
  187. atapi_reg_write(IDE_DEVICE_HEAD,HDD_DEV|(lba>>24));
  188. atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns
  189. atapi_reg_write(IDE_SECTOR_CNT,seccnt);
  190. atapi_reg_write(IDE_SECTOR_NUM,lba&0xFF);
  191. atapi_reg_write(IDE_CYLINDER_LO,(lba>>8)&0xFF);
  192. atapi_reg_write(IDE_CYLINDER_HI,(lba>>16)&0xFF);
  193. atapi_reg_write(IDE_COMMAND,0x30);
  194. atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns
  195. return HDD_PIO_WriteData(buff);
  196. /* HD go to Sleep,and must wake it up by HD Reset */
  197. void HDD_Sleep(void)
  198. {
  199. //printf(__FUNCTION__":nn");
  200. HDD_DEV_Identify();
  201. atapi_reg_write(IDE_DEVICE_HEAD,HDD_DEV);
  202. atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns
  203. atapi_reg_write(IDE_COMMAND,0x99);
  204. atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns    
  205. while(atapi_reg_read(IDE_STATUS)&STATUS_BSY) ;
  206. printf("NOW HD SLEEP!!!");
  207. }
  208. UINT32 HDD_GetMaxLBA()
  209. {
  210. //printf(__FUNCTION__":nn");
  211. HDD_DEV_Identify();
  212. atapi_reg_write(IDE_DEVICE_HEAD,HDD_DEV);
  213. atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns
  214. atapi_reg_write(IDE_COMMAND,0xF8);
  215. atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns   
  216. while(atapi_reg_read(IDE_STATUS)&STATUS_BSY);
  217. printf("n--GetLBA: %x--n", atapi_reg_read(IDE_STATUS)); 
  218. return  ( (UINT32)atapi_reg_read(IDE_SECTOR_NUM)
  219. +((UINT32)atapi_reg_read(IDE_CYLINDER_LO)<<8)
  220. +((UINT32)atapi_reg_read(IDE_CYLINDER_HI)<<16)
  221. +(((UINT32)atapi_reg_read(IDE_DEVICE_HEAD)&0x0F)<<24) );
  222. }
  223. int HDD_GetCHS(UINT8* buff)
  224. {
  225. //printf(__FUNCTION__":nn");
  226. HDD_DEV_Identify();
  227. atapi_reg_write(IDE_DEVICE_HEAD,HDD_DEV);
  228. atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns
  229. atapi_reg_write(IDE_COMMAND,0xEC);
  230. atapi_reg_read(IDE_ALT_STATUS);  //delay 400ns
  231.     
  232. return HDD_PIO_ReadData(buff);
  233. }
  234. void  HDD_Reset(void)
  235. {
  236. //printf(__FUNCTION__":nn");
  237. #ifdef DVD728
  238.     regs0->dvddsp_public = PIO_MODE4|ATAPI_ADV_POLLING;
  239. #else
  240. regs0->dvddsp_config = PIO_MODE4|ATAPI_ADV_POLLING;
  241. #endif
  242. atapi_rst(DSP_HOST_RESET|ATA_HW_RESET);
  243. #ifdef DVD728
  244. regs0->dvddsp_public = PIO_MODE4|ATAPI_ADV_POLLING;
  245. #else
  246. regs0->dvddsp_config = PIO_MODE4|ATAPI_ADV_POLLING;
  247. #endif
  248. while(atapi_reg_read(IDE_ALT_STATUS) & (STATUS_BSY|STATUS_ERR)) ;
  249. printf("n--Reset: %x--n", atapi_reg_read(IDE_STATUS));
  250. delay(6000);
  251. }
  252. void print_sector(UINT8 *buff)
  253. {
  254. int i,j;
  255. for(i=0;i<0x20;i++)
  256. {
  257. printf("n  %02x0: ",i);
  258. for(j=0;j<0x10;j++)
  259. {
  260. printf(" %02x",*buff++);
  261. }
  262. }
  263. }
  264. void ata_init(void)
  265. {
  266. #ifdef DVD728
  267. regs0->dvddsp_public = PIO_MODE4|DVDDSP_CONFIG_DEF;//DVDDSP_CONFIG_DEF;
  268. #else
  269. regs0->dvddsp_config = PIO_MODE4|DVDDSP_CONFIG_DEF;//DVDDSP_CONFIG_DEF;
  270. #endif
  271.     atapi_rst(DSP_HOST_RESET|ATA_HW_RESET);
  272. #ifdef DVD728
  273.     regs0->dvddsp_public = PIO_MODE4|DVDDSP_CONFIG_DEF;//DVDDSP_CONFIG_DEF;
  274. #else
  275. regs0->dvddsp_config = PIO_MODE4|DVDDSP_CONFIG_DEF;//DVDDSP_CONFIG_DEF;
  276. #endif
  277. delay(1);
  278. printf("ATA Test Rdyn");
  279. }
  280. //UINT8 atapi_block_read(UINT32 lba, UINT32 len)
  281. UINT8 hdd_block_read(UINT32 lba, UINT32 len)
  282. {
  283. #if 0 
  284.     if (atapi_is_error() == ATAPI_ERROR)
  285.     {   
  286.         printf("enter ata_block_read errorn");
  287.         cderr_handler(CDERR_DAT_DISCONTINUE);
  288.         return ATAPI_ERROR;
  289.     }
  290.     
  291.     if (is_user_opened())
  292.     {
  293.         printf("USER OPEN!!!n");
  294.         return ATAPI_ERROR;
  295.     }
  296. #endif
  297.     //printf("HDD_block_read:%lx---%lxn",lba,len);
  298.     //regs0->dvddsp_config = ATAPI_DEVICE ;// | ATAPI_FIFO_FLUSH | ATAPI_CSS_ENABLE;
  299.     dev_status_flag|=READ_PRESENT_DATA;
  300.     //ATA_Read(lba, len*4);
  301.     atapi_p_read_12(lba, len);
  302. #ifdef DVD728
  303.     regs0->dvddsp_public = PIO_MODE4|DVDDSP_CONFIG_DEF;
  304. #else
  305.     regs0->dvddsp_config = PIO_MODE4|DVDDSP_CONFIG_DEF;
  306. #endif
  307.     regs0->dvddsp_blocksize = 256;
  308.     regs0->dvddsp_blocklength = len;//*8;
  309.     //regs0->dvddsp_function = (IDE_DATA<<8) | ATAPI_READ | DATA_MODE | HOST_START ;
  310.     if (atapi_reg_read(IDE_STATUS) == 0x50) 
  311.     { //DRQ=0,BSY=0,DRDY=1,DSC=1
  312. printf("skip directly!n");
  313. return ATAPI_ERROR;
  314.     } 
  315.     else 
  316.     {    
  317.         regs0->dvddsp_function = (IDE_DATA<<8) | ATAPI_READ | DATA_MODE | HOST_START ;
  318.     }
  319.     
  320.     while ((regs0->dvddsp_function&HOST_BUSY) != 0)  ; 
  321.     return ATAPI_OK;
  322. }
  323. #if 0
  324. UINT8 atapi_receive_data(UINT8 *p, int n)
  325. {
  326.     UINT16 USER_DATA;
  327.     int i,j;
  328.     /*****
  329.     * Host: read Alternate status register and ignore results. This
  330.     * prevent polling host from reading status before it is valid
  331.     ******/
  332.     atapi_reg_read(IDE_ALT_STATUS);
  333.     j = 0;
  334.     do
  335.     {
  336. /*****
  337. * Host: read Status register until BSY=0 & DRQ=1. Status register
  338. * is read to clear pending interrput
  339. *****/
  340. #ifdef POLLING_MODE
  341. if (atapi_chk_time_out(WAIT_DRQ_OK,LONG_TIME_OUT))
  342. {          
  343. //printf(__FUNCTION__" ==> Timout 1n");
  344. cderr_handler(CDERR_ATA_BUSY);
  345. return ATAPI_ERROR;
  346. }
  347. #else
  348. while ( (atapi_reg_read(IDE_STATUS) & STATUS_BSY) ||!(atapi_reg_read(IDE_STATUS) & STATUS_DRQ) ) 
  349. {
  350. WaitIRQ();
  351. }
  352. #endif
  353. printf("data length:n=%dn",n);
  354. i = 512;
  355. if (i > n)
  356. i = n;
  357. /*****
  358. * DRQ block transfer
  359. *****/
  360. for (; i > 0; i-=2)
  361. {
  362. USER_DATA = atapi_reg_read(IDE_DATA);
  363. *(p+j+1)  = USER_DATA >> 8;
  364. *(p+j)    = USER_DATA & 0xff;
  365. j += 2;
  366. n -= 2;
  367. }
  368.     } while (n != 0);
  369.     /*****
  370.     * Host: wait device to clear BSY=0, it indicates command is complete.
  371.     *****/
  372.     if (atapi_chk_time_out(WAIT_STATUS_NO_BSY,LONG_TIME_OUT))
  373.     {          
  374. //printf(__FUNCTION__" ==> Timout 2n");
  375. //cderr_handler(CDERR_ATA_BUSY);
  376. if (atapi_is_error()==0)
  377. {//printf(__FUNCTION__" ==> !!!!ATAPI ERROR n");}
  378. return ATAPI_ERROR;
  379.     }
  380.     /*****
  381.     * Host: read Alternate status register and ignore results. This 
  382.     * polling host from reading status before it is valid.
  383.     * Note - Device is command complete, it should perform its error routine if
  384.     * an error is reported
  385.     *****/
  386.     atapi_reg_read(IDE_ALT_STATUS);
  387.     return atapi_is_error();
  388. }
  389. #endif
  390. #endif //USE_HDD