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

DVD

开发平台:

C/C++

  1. /*=================================================================
  2. atapi_if.c: ATAPI INTERFACE
  3. 2000-01-01         Created  by 
  4. 2002-06-12 08:42AM Modified by cyue
  5. 2004-04-16         Modified by Terry
  6. Copyright(c)2000-2002 by Sunplus Technology (HsingChu) Co., Ltd.
  7.                    ALL RIGHTS RESERVED
  8.                    
  9. =================================================================*/
  10. //#define NPRINTF
  11. //#define NEPRINTF
  12. #include "config.h"
  13. #include "misc.h"
  14. #include "global.h"
  15. #include "ata.h"
  16. #include "fs.h"
  17. #include "cderr.h"
  18. #include "drv.h"
  19. #include "sinf.h"
  20. #include "atapi_if.h"
  21. #include "pu8560.h"
  22. #include "emuio.h"
  23. #include "lbaif.h"
  24. #if 0//def SUPPORT_SPI_QSI
  25. #include "iop.h"
  26. #endif
  27. #ifdef SUPPORT_CD_TEXT
  28.     #include "CDTextUtil.h"
  29.     #include "memmap0.h"
  30. #endif
  31. #ifndef DVDRELEASE
  32. //#define DBG_ATAPI
  33. #endif
  34. #ifndef DBG_ATAPI
  35. #undef printf
  36. #undef print_block
  37. #define printf(f, a...) do {} while (0)
  38. #define print_block(x,y) do {} while (0)
  39. #endif
  40. extern UINT8  cIDEStatus;
  41. extern UINT8  *pServoMemXferPtr;
  42. extern UINT16 wServoMemXferLen;
  43. extern UINT8 cHostDVDDSPMode;
  44. extern UINT8 cCmdBlock[12];
  45. extern void ServoDecMainLoop(void);
  46. extern void save_cmp_disc_info(UINT32 info1);//wanghaoying 20030812
  47. extern UINT32 search_file(BYTE*);
  48. void IDECommandProc(void);
  49. void ServoDecInit(void);
  50. void ResetInterfaceProc(void);
  51. //==================================================================
  52. //UINT8 pc[12];  //reduce global var.
  53. //UINT8 pc_rdata[32];
  54. UINT16 request_sense_flag;
  55. // 0: DISC_VCD, 1: DISC_DVD
  56. UINT8 DiscType = CDDVD;
  57. //UINT8 CSSEnable = 0;
  58. UINT32 udf_find_anchor(void);
  59. //==================================================================
  60. #define DVDDSP_CONFIG_DEF ATA_INTR_MODE //ATAPI_INTR_MODE
  61. #define WaitIRQ()   while ((regs0->dvddsp_function & DEVICE_INT) == 0) ;//for test DRQ mode
  62. #define SHORT_TIME_OUT 400//4 sec
  63. #define NORMAL_TIME_OUT 700//7 sec 
  64. #define LONG_TIME_OUT 800//8 sec
  65. #define MAX_TIME_OUT       1000//10 sec
  66. //==================================================================
  67. //extern function and varible
  68. void disp_fan_in(void);
  69. void flush_atapi(void);;
  70. void cppm_init( UINT32 );
  71. void polling();
  72. extern UINT8   bReadSubChannel; //Jeff 20020927
  73. extern UINT16  iBlockLen;
  74. //terry,2004/2/6 05:43PM
  75. #ifdef DVD_SERVO
  76. //
  77. // FUNCTION
  78. // atapi_dvddsp_busy_waiting()
  79. //
  80. // DESCRIPTION
  81. // compatible atapi 
  82. //
  83. void atapi_dvddsp_busy_waiting(int seek)
  84. {
  85.    set_host_request();
  86.    ServoDecMainLoop();   // DVD_SERVO
  87. }
  88. #endif
  89. //==================================================================
  90. // ATAPI Procedure
  91. // return 1: ERR, 0: OK
  92. //inline UINT8 
  93. UINT16
  94. atapi_reg_read(UINT8 addr)
  95. {
  96. addr = IDE_STATUS;
  97. return (UINT16)cIDEStatus;
  98. }
  99.  
  100. UINT8 atapi_is_error(void)
  101. {
  102. return (atapi_reg_read(IDE_STATUS) & STATUS_ERR);
  103. }
  104. int atapi_read_error(void)
  105. {
  106. UINT16 id;
  107.     UINT8 ubuf[20];
  108.     
  109.     id=atapi_reg_read(IDE_STATUS) & STATUS_ERR;
  110. if (id != 0) 
  111. printf("atapi_read_error:error %dn",id);
  112. atapi_p_request_sense(ubuf);
  113. cderr_update_show_time();
  114. return -1;
  115. }
  116. return 0;
  117. }
  118. UINT8 atapi_rst(UINT8 mode)
  119. {
  120.     printf("atapi_rst: reset mode:%xnn",mode);
  121. if (mode & DSP_HOST_RESET) 
  122. {
  123. //necessary reset Loader HW
  124.         ServoDecInit();
  125.         ResetInterfaceProc();
  126.         
  127.         #ifdef SERVO_RANDOM_SEEK
  128.         while(1)
  129.         {
  130.          polling(); // for random seek
  131.          ServoDecMainLoop(); // barry add for polling servo status
  132.         }
  133.         #endif 
  134.         
  135. }
  136.     if(mode&ATA_SW_RESET)
  137.     { 
  138.      //necessary IDE_COMMAND=0x08 Driver reset        
  139. }
  140. if(mode&ATA_WAIT_RDY)
  141. {
  142.     //terry,2002/5/31 09:56PM, FUSS request: open must be avaible
  143.     
  144.     do
  145.     {
  146.        ServoDecMainLoop();
  147.     } while ( (cIDEStatus&0x80) == 0x80 );  // BSY bit
  148. io_write("Servo Start-up finishn");
  149. //wait 10sec for atapi_p_test_unit_ready() 
  150. //else return ATAPI_ERROR;
  151. }
  152.     return 0;//success
  153. }
  154. UINT8
  155. atapi_receive_data(UINT8 *p, int n)
  156. {
  157.    #define TIMEOUT 100 //1s
  158.    #define GET_RTC_15_0() (regs0->rtc_15_0)
  159.    UINT32 old,now,cnt;
  160.    
  161.    memset(p, 0, n);//clear buffer
  162.    //wait servo  ,run polling
  163.    //receive data to pointer p,size n
  164.    pServoMemXferPtr = p;
  165.    wServoMemXferLen = n;
  166.    cHostDVDDSPMode = 0;
  167.    old = GET_RTC_15_0(); 
  168.    
  169.    //for read disc, open tray delay bug.
  170.    if(system_state==SYSTEM_READ_TITLE)  cnt=TIMEOUT;//terry,2003/11/21 04:03PM
  171.    else cnt=0;
  172.    
  173.    do
  174.    {  
  175.       now = GET_RTC_15_0();   
  176.       if(old!=now)
  177.       {
  178.         cnt++;
  179.         old=now;
  180.       }
  181.       
  182.       if(cnt>TIMEOUT)
  183.       {
  184.           polling();          
  185.          // printf(".");
  186.       }
  187.       //ycwen 2005/1/21: To prevent audio buffer from underflow when ran_read() taking too much time (e.x. long seek)
  188.       #ifdef MP3_JPEG_COWORK 
  189.       polling_read_data();
  190.       #endif
  191.       
  192.       disp_fan_in();//terry 20030902       
  193.       ServoDecMainLoop();
  194.    } while ( (cIDEStatus&0x80) == 0x80 );  // BSY bit
  195.    //printf("IDE Status1 : %x n",cIDEStatus);
  196.    return atapi_is_error();
  197. }
  198. UINT8
  199. atapi_do_packet(UINT8 *pck)
  200. {
  201. #if 0
  202.     UINT8 i;
  203.     for (i=0 ; i<12 ; i++) { cCmdBlock[i] = *(pck+i); }
  204. #endif
  205.     
  206.     memcpyS(cCmdBlock,pck,12);    
  207.     print_block(cCmdBlock,6);
  208.     
  209.     IDECommandProc();
  210.     if (cIDEStatus & 0x01)
  211.         return ATAPI_ERROR;
  212.     else
  213.         return ATAPI_OK;
  214. }
  215. //return 
  216. //  1: error
  217. //  0: ok     
  218. /*UINT8 atapi_do_set_features(void)
  219. {
  220.   return 0;
  221. }*/
  222. // Packet command
  223. // read 18 bytes
  224. UINT8 
  225. atapi_p_request_sense(UINT8 *block_info)
  226. {
  227. int sense_key;
  228. UINT8 pc[12];
  229.     request_sense_flag=0;
  230. memset(pc, 0, 12);
  231. pc[0] = 0x03;
  232. pc[4] = 0x12;
  233. atapi_do_packet(pc);
  234. if (atapi_receive_data(block_info, 18) == 1) {
  235. printf("p_request_sense receive data errorn");
  236. return 1;
  237. }
  238.     sense_key=block_info[2]&0xf;
  239. if (block_info[2] == 00) {
  240. printf("no sensen");
  241. } else {
  242. //printf("Sense key: 0x%02xn",sense_key);
  243. //printf("ASC: 0x%02xn", block_info[12]);
  244. //printf("ASCQ:0x%02xn", block_info[13]);
  245. if(sense_key==2)
  246. {
  247. if(block_info[12]==0x04)
  248.            request_sense_flag|=ATAPI_NOT_READY;
  249.         else if((block_info[12]==0x3A)&&(block_info[13]==0x00))
  250.        request_sense_flag|=ATAPI_NO_MEDIA;
  251.     else if((block_info[12]==0x06)&&(block_info[13]==0x00))
  252.        request_sense_flag|=ATAPI_MEDIA_UPSIDE_DOWN;
  253. }else if(sense_key==5)
  254. {
  255. if(block_info[12]==0x30)
  256.        request_sense_flag|=ATAPI_UNKNOWN_MEDIA;
  257.     else if(block_info[12]==0x64)
  258.        request_sense_flag|=ATAPI_ILLEGAL_MODE;
  259. }
  260.         else if(sense_key==4) //servo can't focus for a long time, Jeff 20031203
  261. {
  262. request_sense_flag|=ATAPI_UNKNOWN_MEDIA;
  263. }
  264. }
  265. return 0;
  266. }
  267. UINT8
  268. atapi_p_test_unit_ready(void)
  269. {
  270. int ret;
  271. UINT8 pc[12];
  272.     UINT8 pc_rdata[32];
  273. memset(pc, 0, 12);
  274. //printf("!");
  275. ret=atapi_do_packet(pc);//ret==0, unit is ready
  276. //if(ret==1)
  277. if (cIDEStatus & 0x01)  // CHECK bit assert
  278. {
  279.  atapi_p_request_sense(pc_rdata);//kenny
  280.  
  281.  if(request_sense_flag&ATAPI_NO_MEDIA)
  282.  ret=ATAPI_NO_MEDIA;
  283. else if(request_sense_flag&ATAPI_NOT_READY)
  284.   ret=ATAPI_NOT_READY;
  285. else if(request_sense_flag&ATAPI_MEDIA_UPSIDE_DOWN)
  286.   ret=ATAPI_MEDIA_UPSIDE_DOWN; 
  287. else if(request_sense_flag&ATAPI_UNKNOWN_MEDIA)
  288.   ret=ATAPI_UNKNOWN_MEDIA; 
  289. else
  290.   ret=0xff; 
  291.  
  292. }
  293. return ret;
  294. }
  295. UINT8 
  296. atapi_p_start_stop_unit(UINT8 start)
  297. {
  298. UINT8 pc[12];
  299.     UINT8 pc_rdata[32];
  300.     
  301. flush_atapi();
  302. atapi_read_error();
  303. memset(pc, 0, 12);
  304. pc[0] = 0x1B;
  305. pc[1] = 0x01;
  306. pc[4] = start;
  307. if (atapi_do_packet(pc) == 1) {
  308. printf("p_start_stop_unit errorn");
  309.  atapi_p_request_sense(pc_rdata);//kenny
  310. return 1;
  311. }
  312. return 0;
  313. }
  314. UINT8 
  315. atapi_p_mechanism_status(void)
  316. {
  317. UINT8 pc[12];
  318.     UINT8 pc_rdata[32];
  319. flush_atapi();//alan 2002/5/30 06:29PM added to solve standby wake up fail when power on/off
  320. memset(pc, 0, 12);
  321. pc[0] = 0xBD;
  322. pc[9] = 0x08;
  323. if (atapi_do_packet(pc) == ATAPI_ERROR) {
  324. printf("p_mechanism_status do_packet errorn");
  325.  atapi_p_request_sense(pc_rdata);//kenny
  326. return ATAPI_ERROR;
  327. }
  328. memset(pc_rdata, 0, 8);
  329. if (atapi_receive_data(pc_rdata, 8) == ATAPI_ERROR) {
  330. printf("p_mechanism_status receive data errorn");
  331. #ifdef SHOW_SPECIAL_DISC_TYPE
  332.         read_disc_state = 0xf0; 
  333.         #endif
  334.         
  335. return ATAPI_ERROR;
  336. }
  337. //    printf("%dn", pc_rdata[1] >> 5);
  338.    
  339.     if(pc_rdata[1] & 0x01) 
  340. {
  341. //   printf("===============>>>>>door close errorn");
  342.   
  343.       return ATAPI_DOOR_CLOSE_ERR;
  344. }else if (((pc_rdata[1] >> 4) & 1) == 0) 
  345. {
  346. //   printf("door closen");
  347.       return ATAPI_DOOR_CLOSE;
  348. }
  349. //   printf("door openn");
  350. return ATAPI_DOOR_OPEN;
  351. }
  352. UINT8 
  353. atapi_p_read_12(UINT32 lba, UINT32 len)
  354. {
  355. BYTE ret;
  356. UINT8 pc[12];
  357.     UINT8 pc_rdata[32];
  358. memset(pc, 0, 12);
  359. pc[0] = 0xA8;
  360. pc[2] = (lba >> 24) & 0x000000ff; /* LBA (MSB) */
  361. pc[3] = (lba >> 16) & 0x000000ff;
  362. pc[4] = (lba >> 8) & 0x000000ff;
  363. pc[5] =  lba & 0x000000ff; /* LBA (LSB) */
  364. pc[6] = (len >> 24) & 0x000000ff;   // transfer length(MSB)
  365. pc[7] = (len >> 16) & 0x000000ff;        
  366. pc[8] = (len >> 8) & 0x000000ff;          
  367. pc[9] =  len & 0x000000ff;  
  368.     
  369.     ret=atapi_do_packet(pc);
  370. if(dev_status_flag&READ_PRESENT_DATA)
  371.          dev_status_flag&=~READ_PRESENT_DATA;
  372. if (ret == 1) {
  373. printf("!!!!!!!!p_read_12 errorn");
  374.         atapi_p_request_sense(pc_rdata);
  375.         printf("!!!!!!!!Request outn");
  376.       
  377.       if(request_sense_flag&ATAPI_NOT_READY)
  378.       {
  379.        printf("!!!!!!!!p_read_12 error, unit not readyn");
  380.     
  381.              cderr_handler(CDERR_ATA_NOT_READY);
  382.           
  383.            if(atapi_do_packet(pc) == 1) 
  384.        {
  385.        printf("p_read_12 again errorn");
  386.         atapi_p_request_sense(pc_rdata);//kenny
  387.       
  388.        }
  389.       
  390.              
  391.       
  392.       }//not ready
  393.       else if(request_sense_flag&ATAPI_ILLEGAL_MODE)
  394.       {
  395.       
  396.        return ATAPI_ILLEGAL;
  397.       
  398.   
  399.       } 
  400.           
  401. return 1;
  402. }
  403. return 0;
  404. }
  405. // generic packet command
  406. void 
  407. init_cdrom_command(struct cdrom_generic_command *cgc, void *buffer, int len)
  408. {
  409. memset(cgc, 0, sizeof(*cgc));
  410. memset(buffer, 0, len);
  411. cgc->buffer = (char *) buffer;
  412. cgc->buflen = len;
  413. }
  414. // only support 3 commands now
  415. // return 0: ok, -1: error
  416. int 
  417. generic_packet(struct cdrom_generic_command *cgc)
  418. {
  419.     UINT8 pc_rdata[32];
  420. if ((cgc->cmd[0]==GPCMD_READ_DVD_STRUCTURE)||(cgc->cmd[0]==GPCMD_REPORT_KEY))
  421. {
  422. if (atapi_do_packet(cgc->cmd)!=0)
  423. {
  424. printf("generic_packet:packet errorn");
  425. atapi_p_request_sense(pc_rdata);
  426. memset(cgc->buffer,0,cgc->buflen);
  427. return -1;
  428. }
  429. atapi_receive_data(cgc->buffer, cgc->buflen);
  430. }
  431. else if(cgc->cmd[0]==GPCMD_SEND_KEY)
  432. {
  433. if (atapi_do_packet(cgc->cmd)!=0)
  434. {
  435. printf("generic_packet:packet errorn");
  436. atapi_p_request_sense(pc_rdata);
  437. return -1;
  438. }
  439. //atapi_send_data(cgc->buffer, cgc->buflen);
  440. }
  441.     return atapi_read_error();
  442. }
  443. UINT8 
  444. atapi_get_cprm_config(void)
  445. {
  446. BYTE ret=0;
  447. UINT8 pc[12];
  448.     UINT8 pc_rdata[32];
  449. memset(pc, 0, 12);
  450. pc[0] = 0x46;   
  451. pc[1] = 0x02; //feature descriptor be returned
  452. pc[2] = 0x01; //cprm 
  453. pc[3] = 0x0B;
  454. // transfer length
  455. pc[8] = 0x08;   
  456.     if( atapi_do_packet(pc)==0 )
  457.     {
  458. if(atapi_receive_data(pc_rdata, 8) ) 
  459. {
  460. printf("atapi_get_cprm_config  receive errorn");
  461. //memset(pc_rdata, 0, 2048*len);    
  462. ret = ATAPI_ERROR;    
  463. }else
  464. {
  465. print_block(pc_rdata,8);//01:0x010B
  466. if(pc_rdata[2]&0x01)
  467. {
  468. printf("DVD-R,DVD-RW or DVD-RAMn");
  469. }
  470. }else
  471. {
  472. printf("get cprm config failn");
  473.         atapi_p_request_sense(pc_rdata);
  474.         ret = ATAPI_ERROR;    
  475. }
  476. return ret;
  477. }
  478. /*
  479. *   lba: read start location
  480. *   len: read start length
  481. */
  482. UINT8 
  483. atapi_block_read(UINT32 lba, UINT32 len)
  484. {
  485.     UINT8 pc_rdata[32];
  486. #ifdef USE_HDD
  487.     extern UINT8 hdd_block_read(UINT32 lba, UINT32 len);
  488.       //Verdure add, cyue:2002-06-12 04:45PM modified
  489.       if  (hd_play)
  490.       {
  491.           hdd_block_read(lba, len);
  492.           return 0;
  493.       }
  494. #endif
  495.     if (atapi_is_error() == ATAPI_ERROR) 
  496.     {
  497. printf("enter block_read errorn");
  498. atapi_p_request_sense(pc_rdata);
  499. cderr_handler(CDERR_DAT_DISCONTINUE);
  500. return ATAPI_ERROR;
  501. }
  502. if (is_user_opened())
  503. {
  504. printf("USER OPEN!!!n");
  505. return ATAPI_ERROR;
  506. }
  507. dev_status_flag|=READ_PRESENT_DATA;//kenny
  508.    
  509. cHostDVDDSPMode = 1;
  510. if (DiscType != CDDVD)
  511. {
  512. //printf("readcdn");
  513. if (atapi_read_cd(lba, len) == ATAPI_ERROR) 
  514.     return ATAPI_ERROR;
  515. }
  516. else
  517. { // DVD
  518. //printf("read12n");
  519.     if (atapi_p_read_12(lba, len) == ATAPI_ERROR) return ATAPI_ERROR;      
  520. }
  521.    
  522.   
  523.     if (atapi_reg_read(IDE_STATUS) == 0x50) 
  524.     {   //DRQ=0,BSY=0,DRDY=1,DSC=1
  525.        printf("skip directly!n");
  526.        return ATAPI_ERROR;
  527.     }   
  528.   
  529.     return ATAPI_OK;
  530. }
  531. void 
  532. atapi_init(void)
  533. {
  534.     //io_write("Servo atapi_init Start!n");
  535.     //ServoDecInit();
  536.     //ResetInterfaceProc();
  537.     hostx_servo_buf_init();
  538.     atapi_rst(DSP_HOST_RESET|ATA_HW_RESET);
  539.     //delay(1);
  540.     atapi_p_test_unit_ready();//start up loader
  541.     //io_write("Servo atapi_init End!n");
  542. }
  543. #include "dvdioctl.h"
  544. void disc_init(void)
  545. {
  546. //    #define DISC_IS_DVD() (gbSrvDiscStatus&0x40)//terry,2003/12/26 03:01PM
  547. //    extern BYTE gbSrvDiscStatus;
  548.     int     iRetry, nTryNum;
  549.     UINT32  iAnchor=0;
  550.    //UINT32 dVTS_LSN_VOB,dVTS_LSN_IFO;//terry,mark it,2003/8/7 02:19AM
  551.    
  552.    DiscType = CDUNKNOWN;
  553.    printf("disc_init n");
  554.    //add re-try anchor when read DVD disc, Jeff 20031017
  555.    if ( DISC_IS_DVD() )
  556.        nTryNum = 2;
  557.    else
  558.        nTryNum = 1;
  559.     for (iRetry=0; iRetry<nTryNum; iRetry++) {
  560.         iAnchor = udf_find_anchor();
  561.         if (iAnchor !=0) break;
  562.         
  563.         // 2004/07/16 yltseng
  564.         wb_tag_init();
  565.     }
  566.    //if (udf_find_anchor() == 0) 
  567.    //{
  568.    //     printf("no anchor foundn");
  569.    //}
  570.     if ( (iAnchor == 0) && (iRetry>=nTryNum) ) {
  571.         printf("no anchor foundn");
  572.     }
  573.    else
  574.    {        
  575.         printf("initialize filesystemn");
  576.         if ( fs_init() < 0) return;
  577.         if(dVMG_LSN)
  578.         {
  579.        DiscType = CDDVD;
  580.        cd_type_loaded=DiscType;
  581. #if defined (SAME_DISC_RESUME) || defined (RECORD_KEY) || defined(POWER_RESUME) //terry,2003/8/7 02:20AM
  582. #ifdef DVD_AUDIO//nono 2004-2-25 0:40
  583.           if((cd_type_loaded==CDDVD) && (dAMG_LSN==0)) 
  584. #endif //DVD_AUDIO
  585.   {
  586. same_disc_vob11_pos = search_file("VTS_01_1.VOB");
  587. save_cmp_disc_info(same_disc_vob11_pos);
  588.   }
  589. #endif //Maoyong 2004.02.25 end #if defined (SAME_DISC_RESUME) || defined (RECORD_KEY) || defined(POWER_RESUME) //terry,2003/8/7 02:20AM
  590. #define ALWAYS_ENABLE_CSS
  591. #ifdef  ALWAYS_ENABLE_CSS
  592. //            CSSEnable=1;
  593. #else            
  594. {
  595.         dvd_struct s;
  596.         
  597.             s.type = DVD_STRUCT_COPYRIGHT;
  598.     s.copyright.layer_num = 0;
  599.     dvd_read_struct(&s);
  600.             CSSEnable=s.copyright.cpst;
  601. }
  602. #endif            
  603.         }
  604. #ifdef DVD_AUDIO
  605.         cppm_init( dAMG_LSN );
  606. #endif
  607.    }
  608. }
  609. BYTE user_only=0;
  610. //user_only : 
  611. // 1:user data only
  612. // 0:ATAPI_READCD_9_SYNC|ATAPI_READCD_9_HEADER_ALL|ATAPI_READCD_9_USERDATA
  613. // | ATAPI_READCD_9_ECC;
  614. //if ( (cd_type_loaded==CDDA) && (cd_subtype!=CD_DTS) )
  615. //      pc[10]=bReadSubChannel; //Jeff 20020927
  616. UINT8 
  617. atapi_read_cd(UINT32 lba, UINT32 len)
  618. {
  619. BYTE ret;
  620. UINT8 pc[12];
  621.     UINT8 pc_rdata[32];
  622. memset(pc, 0, 12);
  623. pc[0] = 0xBE;
  624.     // LBA
  625. pc[2] = (lba >> 24) & 0x00ff; 
  626.    pc[3] = (lba >> 16) & 0x00ff;
  627.    pc[4] = (lba >> 8) & 0x00ff;
  628.    pc[5] =  lba & 0x00ff;  
  629.    // transfer length
  630.    pc[6] = (len >> 16) & 0x00ff;
  631.    pc[7] = (len >> 8) & 0x00ff;          
  632.    pc[8] =  len & 0x00ff;  
  633.   
  634.    // ....
  635. #define ATAPI_READCD_9_SYNC (1<<7)
  636. #define ATAPI_READCD_9_HEADER_NONE (0<<5)
  637. #define ATAPI_READCD_9_HEADER_HEADER (1<<5)
  638. #define ATAPI_READCD_9_HEADER_SUBHEADER (2<<5)
  639. #define ATAPI_READCD_9_HEADER_ALL (3<<5)
  640. #define ATAPI_READCD_9_USERDATA (1<<4)
  641. #define ATAPI_READCD_9_ECC (1<<3)
  642.    if(user_only==1)
  643.    {
  644.       pc[9] =0x10;
  645.    }
  646.    else
  647.    {
  648.       pc[9] = ATAPI_READCD_9_SYNC
  649.       | ATAPI_READCD_9_HEADER_ALL
  650.          | ATAPI_READCD_9_USERDATA
  651.      | ATAPI_READCD_9_ECC;
  652. }
  653.     if ( (cd_type_loaded==CDDA) && (cd_subtype!=CD_DTS) )
  654.         pc[10]=bReadSubChannel; //Jeff 20020927
  655.      ret=atapi_do_packet(pc);
  656.  if((dev_status_flag&READ_PRESENT_DATA))         
  657.  {
  658.          dev_status_flag&=~READ_PRESENT_DATA;
  659.      }  
  660. if (ret == 1) 
  661. {
  662. printf("p_read_cd errorn");
  663.         atapi_p_request_sense(pc_rdata);
  664. return 1;
  665. }
  666. return 0;
  667. }
  668. int 
  669. cdrom_read_tocentry(int trackno, BYTE format, int buflen)
  670. {
  671. UINT8 pc[12];
  672.     UINT8 pc_rdata[32];
  673. memset(&pc, 0, sizeof(pc));
  674. pc[0] = 0x43;
  675. pc[2] = format;//2001/9/26
  676. pc[6] = trackno;
  677. pc[7] = (buflen >> 8);
  678. pc[8] = (buflen & 0xff);
  679. pc[1] = 2;//msf_flag
  680. if (atapi_do_packet(pc) == 1) {
  681. printf("cdrom_read_tocentry errorn");
  682.         atapi_p_request_sense(pc_rdata);
  683. if(request_sense_flag&ATAPI_NOT_READY)//kenny
  684.       {
  685.       
  686.        printf("!!!!!cdrom_read_tocentry , Unit not ready");
  687.     
  688.     
  689.     
  690.      cderr_handler(CDERR_ATA_NOT_READY);
  691.     
  692.      if (atapi_do_packet(pc) == 1) {
  693. printf("cdrom_read_tocentry error againn");
  694.  atapi_p_request_sense(pc_rdata);
  695.     
  696.            
  697.       
  698.       } //if(not_ready==1)
  699.        
  700. return 1;
  701. }
  702. //memset(pc_rdata, 0, sizeof(pc_rdata));
  703. //if (atapi_receive_data(pc_rdata, buflen) == 1) {
  704. //memset(pwb, 0, sizeof(pwb));
  705. if (atapi_receive_data(pwb, buflen) == 1) {
  706. printf("cdrom_read_tocentry receive data errorn");
  707. return 1;
  708. }
  709. return 0;
  710. }
  711. /************************************************/
  712. // atapi_p_mode_sense:
  713. //  This function is only used before excute disc_init().
  714. //  Because before reading TOC( disc type is unknown), I don't know read command should be command 0xA8 or 0xBE.
  715. //  I found that if disc is CDDA and send 0xA8 or 0x28 to loader, then loader will response illegle mode error.
  716. //  So we must make sure disc is CDDA or not. 
  717. //  If DISC is CDDA then DiscType is setting CDDA, for other disc  DiscType is CDDVD. 
  718. //  And we can use disc_init() to identify disc is real DVD disc or not. 
  719. //  If it is not DVD disc then read toc to classify CDDA,VCD, MP3.
  720. //  
  721. /***********************************************/
  722. BYTE atapi_p_get_disc_info(void)
  723. {
  724.     BYTE buflen;  
  725.     UINT8 pc[12];
  726. pc[0] = 0x5A;
  727. pc[2] = 0x41;
  728. pc[7] = 0;
  729. pc[8] = buflen = 0x0A;
  730. atapi_do_packet(pc);
  731. // wait_servo();
  732.   
  733. if (atapi_receive_data(pwb, buflen) == 1) 
  734. {
  735. printf("atapi_mode_sense receive data errorn");
  736. return 1;
  737. }
  738.    
  739.     if(pwb[2]==0x02||pwb[2]==0x06||pwb[2]==0x12||pwb[2]==0x16||pwb[2]==0x22||pwb[2]==0x26)      
  740.          DiscType=CDDA;
  741.     else if(pwb[2]==0x41)
  742.          DiscType=CDDVD;          
  743.     else
  744.     {
  745.      printf("atapi_p_get_disc_infon");
  746.          DiscType=CDUNKNOWN; 
  747.     }
  748. return 0;
  749. }
  750. int
  751. atapi_open_tray(void)
  752. {
  753. #if 0//def SUPPORT_SPI_QSI
  754. BYTE run_in_value;
  755. ReadFromI2c(I2C_ID_MEMORY,PRODUCTION_TESTING,(BYTE *)&run_in_value,sizeof(run_in_value));
  756. if(run_in_value==0)//production reset
  757. return;
  758. #endif
  759. printf("openn");
  760. return atapi_p_start_stop_unit(START_STOP_DO_EJECT);                      
  761. }
  762. int
  763. atapi_close_tray(UINT8 nStatus)
  764. {
  765. #if 0//def SUPPORT_SPI_QSI
  766. BYTE run_in_value;
  767. ReadFromI2c(I2C_ID_MEMORY,PRODUCTION_TESTING,(BYTE *)&run_in_value,sizeof(run_in_value));
  768. if(run_in_value==0)//production reset
  769. return;
  770. #endif
  771. printf("closen");
  772. if (!nStatus) // Robert 2003/12/16
  773. return atapi_p_start_stop_unit(START_STOP_DO_LOAD);
  774. else
  775. return atapi_p_start_stop_unit(START_STOP_DO_LOAD_POWER_OFF);
  776. }
  777. int
  778. atapi_abort_play(void)
  779. {
  780. printf("stopn");
  781. if(!is_user_opened())
  782. {
  783.     return atapi_p_start_stop_unit(START_STOP_DO_STOP);
  784. }else
  785.     return 0;
  786. }
  787. //terry,2003/8/23 08:03PM
  788. int
  789. atapi_standby_mode(void)
  790. {
  791. #if defined(TOP_DOOR_LOADER)||defined(TCL_STANDBY)||defined(CHECK_PORTABLE_OPCLSW) //Jack added 04/11/25 //2004-4-19 18:59 lijd
  792.         extern  UINT8   srv_on;
  793.         printf("stopn");
  794. atapi_p_start_stop_unit(START_STOP_DO_STOP);
  795. #ifndef TOP_DOOR_FOR_NGAILIK     //hq add for ngailik, in order to wake up the system after power off-on quickly switch. 2004-3-3 17:38
  796.    if(srv_on!=0)                 //wthsin,2004/8/9 09:33pm to fast the standby time in Top Loader 
  797.     delay_srv_10ms(300);    
  798. #endif//TOP_DOOR_FOR_NGAILIK
  799. #endif
  800. printf("standbyn");
  801. return atapi_p_start_stop_unit(START_STOP_DO_STANDBY);
  802. }
  803. #ifdef SUPPORT_CD_TEXT
  804. int atapi_read_cd_text( void )
  805. {      
  806.     int iCDTextRetry = 0;
  807.     for( ; iCDTextRetry < READTOC_RETRY; iCDTextRetry++ )
  808.     {        
  809.         if(is_user_opened())
  810.             return -1;
  811.      
  812.         flush_atapi();      
  813.         int iRet = cdrom_read_tocentry( 1, 5, 4 );     
  814.      
  815.         if( iRet == 0 )
  816.             break;
  817.         else if( iRet < 0 )
  818.             return -2;
  819.         else
  820.             printf( "READ CD TEXT retry:%xn", iCDTextRetry );
  821.     }
  822.     
  823.     if( iCDTextRetry >= READTOC_RETRY )
  824.     {
  825.         ClearCDTextData();//lizhx 2004/08/23
  826.         printf( "READ CD TEXT FAIL,exitn" );    
  827.         return -2;
  828.     }
  829.      
  830.     int iLen = (pwb[0]<<8) + pwb[1];  
  831.     if( ( iLen <= 0 ) || ( iLen > 2048 ) )
  832.     {
  833.         printf( "Read CD TEXT length errorn" );
  834.         return -2;
  835.     }
  836.     printf( "CD TEXT length:%dn", iLen - 2 );
  837.     if( is_user_opened() )
  838.         return -1;
  839.   
  840.     cdrom_read_tocentry( 1, 5, ( iLen / 2 * 2 ) + 4 );
  841.     PreParseCDTextData( pwb, iLen, cd_trk_hi - cd_trk_lo, (BYTE*) ( SDRAM_BASE + ( ( CD_TEXT_YA )<< 10 ) ), CD_TEXT_SIZE );
  842. }
  843. #endif
  844. /*
  845. ** FUNCTION
  846. ** atapi_read_toc
  847. **
  848. ** History : 2003/12/08(Jeff) when (is_svo_dvd()), change to fmt=0
  849. */
  850. int atapi_read_toc(void)
  851. {
  852.     BYTE    cd_trk_cna;
  853.     int     toc_retry;
  854.     int     i;
  855.     int     ret;
  856.     BYTE    fmt;
  857.     int     iSize;
  858.     if ( is_svo_dvd() ) {
  859.         fmt     = 0;
  860.         iSize   = 4;
  861.     } else {
  862.         fmt     = 2;
  863.         iSize   = 6;
  864.     }
  865.   
  866. #ifdef NINTAUS_DVD
  867. fmt     = 2;
  868. iSize   = 6;
  869. #endif
  870.   
  871.     //
  872.     // init toc table
  873.     //
  874.     for (i=0; i<=0x66; i++)
  875.         settrkmsf(i, READTOC_INIT);
  876.     for(toc_retry=0;toc_retry<READTOC_RETRY;toc_retry++)
  877.     {
  878.         if(is_user_opened())
  879.             return -1;
  880.      
  881.         flush_atapi();      
  882.         ret = cdrom_read_tocentry(1, fmt, 4);     
  883.      
  884.         if(ret==0)
  885.             break;
  886.         else if(ret<0)
  887.             return -2;
  888.         else
  889.         {
  890.             printf("READ TOC retry:%xn",toc_retry);        
  891.         }
  892.     }
  893.   
  894.     if(toc_retry>=READTOC_RETRY)
  895.     {
  896.         printf("READ LONG TOC FAIL,exitn");    
  897.         return -2;
  898.     }
  899.   
  900.     {
  901.         UINT8 *p;
  902.         int len,trk;
  903.     
  904.         len=(pwb[0]<<8) + pwb[1] - 2;  
  905.         if( (len<=0)||(len>2048) )
  906.         {
  907.             printf("Read toc length errorn");
  908.             return -2;
  909.         }
  910.   
  911.         printf("toc table length:%dn",len);
  912.   
  913.         if(is_user_opened())
  914.             return -1;
  915.      
  916.         cdrom_read_tocentry(1, fmt, (len/2*2)+4);
  917.   
  918. #if 0
  919.     {
  920.         int j;
  921.         int iSize;
  922.         //iSize = 6;
  923.         iSize = 4;
  924.         printf("=========================n");
  925.         printf("%02x%02x%02x%02x, len=%dn", pwb[0], pwb[1], pwb[2], pwb[3], len);
  926.         for(j=4;j<len;j+=iSize)
  927.         {
  928.             for(i=0;i<iSize;i++)
  929.                 printf("%02x ",pwb[j+i]);
  930.             printf("n");
  931.         }
  932.         printf("=========================n");
  933.     }  
  934. #endif
  935.     // fmt = 2
  936.     // =======================================
  937.     // BYTE    0        1    2    3    4    5
  938.     // servo   Session  ADR  Pnt  Min  Sec  Frm
  939.     // atapi   0        1    3    8    9    10
  940.     // =======================================
  941.     // fmt = 0(for DVD only)
  942.     // =======================================
  943.     // BYTE    0        1    2    3
  944.     // servo   Session  Min  Sec  Frm
  945.     // atapi   2        4    5    6
  946.     //
  947.     SessionNs=0;       
  948.     //print_block(pwb,1024);
  949.     for (i=4; i<len; i+=iSize)
  950.     {
  951.         p=&pwb[i];
  952.         if (fmt==2) {
  953.             cd_trk_cna=(p[1]&0x0f)<<4;
  954.             cd_trk_cna|=(p[1]&0xf0)>>4;
  955.        
  956.             if(p[2]<=0xa2) {
  957.                 if(p[2]==0xa0) {
  958.                     trk=0x64;
  959.                     if(p[0]==1) {
  960.                         cd_trk_lo_now=cd_trk_lo=p[3];       
  961.                     }else if(p[0]>1) {
  962.                         SessionNs=p[3];
  963.                         printf("lo:%xn",p[3]);
  964.                     }
  965.                 } else if(p[2]==0xa1) {
  966.             cd_trk_hi=p[3];
  967.             trk=0x65;
  968.                 } else if(p[2]==0xa2) {
  969.             trk=0x66;
  970.                 } else {
  971.                     trk=p[2];       
  972.                     if(trk>100) {
  973.                         printf("~~read toc trk no.(%x) error~~n",trk);
  974.                         return -2;
  975.                     }
  976.                 }
  977.        
  978.                 {
  979.                     UINT32  iMSF;
  980.             
  981.                     //check msf validation, Jeff update, 20030819
  982.                     //pFsJpeg->cdrom.track_info[trk]=((UINT32)(cd_trk_cna)<<24) | ((UINT32)p[3] <<16)| ((UINT32)p[4]<<8) | ((BYTE)(p[5]));
  983.                     iMSF = ((UINT32)p[3] << 16)| ((UINT32)p[4] << 8) | ((BYTE)(p[5]));
  984.                     if (iMSF<0x200) iMSF = 0x200;
  985.                     pFsJpeg->cdrom.track_info[trk]=((UINT32)(cd_trk_cna)<<24) | iMSF;
  986.                 printf("trk:%d msf:%08xn",trk,pFsJpeg->cdrom.track_info[trk]);
  987.                 }
  988.             } //if(p[2]<=0xa2) {
  989.         } else { //fmt=0(for DVD only)
  990.             trk = p[0];
  991.             pFsJpeg->cdrom.track_info[trk] = ((UINT32)( (0x41000000) | (p[1]<<16) | (p[2]<<8) | p[3]) );
  992.             cd_trk_hi = trk;
  993.             SessionNs = trk;
  994.         }
  995. #ifdef MODIFY_MULTI_SESSION_CD_DISC//NONO for tonic GERMANY CD(totle trk 13->12).20040208
  996. if( ((gettrkcna(1) & 0x0040/*CNA_MASK_TYPE*/) != 0x40/*CNA_DATA*/)/*&&(cd_trk_hi<= p[3])*/&&(p[0]>1) )
  997. break;
  998. #endif//MODIFY_MULTI_SESSION_CD_DISC
  999.     } //for (i=4; i<len; i+=6)
  1000.     pFsJpeg->cdrom.track_info[0]=pFsJpeg->cdrom.track_info[1];
  1001.      
  1002.     {
  1003.         UINT32 max,min;
  1004.        
  1005.         for(trk=cd_trk_lo_now;trk<cd_trk_hi;trk++)
  1006.         {
  1007.             max=pFsJpeg->cdrom.track_info[trk+1]&0xffffff;
  1008.             min=pFsJpeg->cdrom.track_info[trk]&0xffffff;
  1009.             if( (min>max)||(min==0xffffff) )
  1010.             {
  1011.                 cd_trk_hi=trk-1;
  1012.                 printf("Read toc length error,max:%x min:%xn",max,min);
  1013.                 break;
  1014.             }
  1015.         }
  1016.      
  1017.         if(cd_trk_hi<cd_trk_lo_now)
  1018.         {
  1019.             printf("Read toc length error,hi:%x low:%xn",cd_trk_hi,cd_trk_lo_now);
  1020.             return -2;
  1021.         }
  1022.     }
  1023.     printf("read finishn" );
  1024.     return 0;
  1025.     }
  1026. }
  1027. //=============ycwen 2004/08/10================
  1028. #if defined(DVD_SERVO_REAL_TURN_OFF)//nono rename 4-12-30 11:19//def NO_DVD_SERVO
  1029. void servo_turn_off(void)
  1030. {
  1031.     //Decoder gated clock
  1032.     WriteServoReg(0x4333,0x07);
  1033.     WriteServoReg(0x4334,0xff);
  1034.     WriteServoReg(0x4335,0xff);
  1035.     WriteServoReg(0x4336,0xff);
  1036.     WriteServoReg(0x4337,0xff);
  1037.     //Servo AFE power down
  1038.     WriteServoReg(0x4403,0x04);
  1039.     WriteServoReg(0x440e,0x02);
  1040.     WriteServoReg(0x4435,0x00);
  1041.     WriteServoReg(0x453c,0x20);
  1042.     //servo DSP gated clock
  1043.     WriteServoReg(0x4410,0x03);
  1044.     WriteServoReg(0x4416,0x01);
  1045. }
  1046. #endif //DVD_SERVO_REAL_TURN_OFF
  1047. #ifdef MP4_SPEED_UP_SRV
  1048. /************************************************/
  1049. /* Change CD speed for some MP4 files that      */
  1050. /* need high transfer bit-rate.                 */
  1051. /* axel 20041018                                */
  1052. /************************************************/
  1053. void atapi_p_change_speed(UINT8 speed)
  1054. {
  1055.     UINT8 pc[12];
  1056. pc[0] = 0xf0;
  1057. pc[1] = 0xbb;
  1058. pc[2] = speed;
  1059. atapi_do_packet(pc);
  1060.     
  1061. }
  1062. #endif //MP4_SPEED_UP_SRV