_tc6807af.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:11k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.   **********************************************************************
  3.   *
  4.   *     Copyright 1999, 2000 Creative Labs, Inc.
  5.   *
  6.   **********************************************************************
  7.   *
  8.   *     Date                 Author               Summary of changes
  9.   *     ----                 ------               ------------------
  10.   *     October 20, 1999     Andrew de Quincey    Rewrote and extended
  11.   *                          Lucien Murray-Pitts  original incomplete 
  12.   *                                               driver.
  13.   *
  14.   *     April 18, 1999       Andrew Veliath       Original Driver
  15.   *                                               implementation
  16.   *
  17.   **********************************************************************
  18.   *
  19.   *     This program is free software; you can redistribute it and/or
  20.   *     modify it under the terms of the GNU General Public License as
  21.   *     published by the Free Software Foundation; either version 2 of
  22.   *     the License, or (at your option) any later version.
  23.   *
  24.   *     This program is distributed in the hope that it will be useful,
  25.   *     but WITHOUT ANY WARRANTY; without even the implied warranty of
  26.   *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  27.   *     GNU General Public License for more details.
  28.   *
  29.   *     You should have received a copy of the GNU General Public
  30.   *     License along with this program; if not, write to the Free
  31.   *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
  32.   *     USA.
  33.   *
  34.   **********************************************************************
  35.   */
  36. /**
  37.  *
  38.  * Overall driver for the Creative DXR2 card
  39.  * Low level tc6807af functions
  40.  *
  41.  */
  42. #include <linux/types.h>
  43. #include <dxr2.h>
  44. #include <tc6807af.h>
  45. #include <zivaDS.h>
  46. #include <asm/io.h>
  47. #include <asm/uaccess.h>
  48. static int dxr2_tc6807af_get_reg(tc6807af_t* instance, int reg);
  49. static int dxr2_tc6807af_set_reg(tc6807af_t* instance, int reg, int val);
  50. tc6807af_ops_t tc6807af_ops_table = {
  51.   
  52.   DXR2_LOGNAME,
  53.   dxr2_tc6807af_get_reg,
  54.   dxr2_tc6807af_set_reg
  55. };
  56. /**
  57.  *
  58.  * Get register from the tc6807af
  59.  *
  60.  * @param instance instance of the tc6807af to use
  61.  * @param reg register to get
  62.  *
  63.  * @return register value, or <0 on error
  64.  *
  65.  */
  66. static int dxr2_tc6807af_get_reg(tc6807af_t* instance, int reg)
  67. {
  68.   dxr2_t* dxr2Inst = (dxr2_t*) instance->data;
  69.   
  70.   // read & return it
  71.   return(readb((u32) dxr2Inst->tc6807afBase + (reg<<2)));
  72. }
  73. /**
  74.  *
  75.  * Set register on the tc6807af
  76.  *
  77.  * @param instance instance of the tc6807af to use
  78.  * @param reg register to set
  79.  * @param val Value to set
  80.  *
  81.  * @return 0 on success, or <0 on error
  82.  *
  83.  */
  84. static int dxr2_tc6807af_set_reg(tc6807af_t* instance, int reg, int val) 
  85. {
  86.   dxr2_t* dxr2Inst = (dxr2_t*) instance->data;
  87.   
  88.   // write it
  89.   writeb(val, (u32) dxr2Inst->tc6807afBase + (reg<<2));
  90.   // OK
  91.   return(0);
  92. }
  93. /**
  94.  *
  95.  * Get challenge key from tc6807af
  96.  *
  97.  * @param instance The instance of TC6807AF to use
  98.  * @param key 10 byte char array to recieve the key
  99.  *
  100.  * @return 0 on success, <0 on failure
  101.  *
  102.  */
  103. extern int dxr2_tc6807af_get_challenge_key(tc6807af_t* instance, char* key) 
  104. {
  105.   dxr2_t* dxr2Inst = (dxr2_t*) instance->data;
  106.   zivaDS_cssFlags_t oldFlags;
  107.   int status;
  108.   // read the old ziva flags
  109.   zivaDS_get_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  110.   // set Css mode
  111.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 1);
  112.   
  113.   // do the tc6807af function
  114.   status = tc6807af_get_challenge_key(instance, key);
  115.   // set non-Css mode 
  116.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 0);
  117.   // restore the old flags
  118.   zivaDS_restore_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  119.   // return status
  120.   return(status);
  121. }
  122. /**
  123.  *
  124.  * Send challenge key to TC6807AF
  125.  *
  126.  * @param instance The instance of TC6807AF to use
  127.  * @param key 10 byte char array containing the key
  128.  *
  129.  * @return 0 on success, <0 on failure
  130.  *
  131.  */
  132. extern int dxr2_tc6807af_send_challenge_key(tc6807af_t* instance, char* key) 
  133. {
  134.   dxr2_t* dxr2Inst = (dxr2_t*) instance->data;
  135.   zivaDS_cssFlags_t oldFlags;
  136.   int status;
  137.   // read the old ziva flags
  138.   zivaDS_get_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  139.   // set Css mode
  140.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 1);
  141.   
  142.   // do the tc6807af function
  143.   status = tc6807af_send_challenge_key(instance, key);
  144.   // set non-Css mode 
  145.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 0);
  146.   // restore the old flags
  147.   zivaDS_restore_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  148.   // return status
  149.   return(status);
  150. }
  151. /**
  152.  *
  153.  * Get the response key from the TC6807AF
  154.  *
  155.  * @param instance Instance of the TC6807AF to use
  156.  * @param key 5 byte char array to receive the key
  157.  *
  158.  * @return 0 on success, <0 on failure
  159.  *
  160.  */
  161. extern int dxr2_tc6807af_get_response_key(tc6807af_t* instance, char* key) 
  162. {
  163.   dxr2_t* dxr2Inst = (dxr2_t*) instance->data;
  164.   zivaDS_cssFlags_t oldFlags;
  165.   int status;
  166.   // read the old ziva flags
  167.   zivaDS_get_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  168.   // set Css mode
  169.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 1);
  170.   
  171.   // do the tc6807af function
  172.   status = tc6807af_get_response_key(instance, key);
  173.   // set non-Css mode 
  174.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 0);
  175.   // restore the old flags
  176.   zivaDS_restore_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  177.   // return status
  178.   return(status);
  179. }
  180. /**
  181.  *
  182.  * Send the response key to the TC6807AF
  183.  *
  184.  * @param instance Instance of the TC6807AF to use
  185.  * @param key 5 byte char array containing the key to send
  186.  *
  187.  * @return 0 on success, <0 on failure
  188.  *
  189.  */
  190. extern int dxr2_tc6807af_send_response_key(tc6807af_t* instance, char* key) 
  191. {
  192.   dxr2_t* dxr2Inst = (dxr2_t*) instance->data;
  193.   zivaDS_cssFlags_t oldFlags;
  194.   int status;
  195.   // read the old ziva flags
  196.   zivaDS_get_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  197.   // set Css mode
  198.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 1);
  199.   
  200.   // do the tc6807af function
  201.   status = tc6807af_send_response_key(instance, key);
  202.   // set non-Css mode 
  203.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 0);
  204.   // restore the old flags
  205.   zivaDS_restore_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  206.   // return status
  207.   return(status);
  208. }
  209. /**
  210.  *
  211.  * Send the disc title key
  212.  *
  213.  * @param instance Instance of the TC6807AF to use
  214.  * @param key 5 byte char array containing the key to send
  215.  *
  216.  * @return 0 on success, <0 on failure
  217.  *
  218.  */
  219. extern int dxr2_tc6807af_send_title_key(tc6807af_t* instance, char* key) 
  220. {
  221.   dxr2_t* dxr2Inst = (dxr2_t*) instance->data;
  222.   zivaDS_cssFlags_t oldFlags;
  223.   int status;
  224.   // read the old ziva flags
  225.   zivaDS_get_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  226.   // set Css mode
  227.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 1);
  228.   
  229.   // do the tc6807af function
  230.   status = tc6807af_send_title_key(instance, key);
  231.   // set non-Css mode 
  232.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 0);
  233.   // restore the old flags
  234.   zivaDS_restore_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  235.   // return status
  236.   return(status);
  237. }
  238. /**
  239.  *
  240.  * Set tc6807af decryption mode
  241.  *
  242.  * @param instance The instance of TC6807AF to use
  243.  * @param mode CSS mode (one of TC6807AF_CSSDECMODEX)
  244.  *
  245.  * @return 0 on success, <0 on failure
  246.  *
  247.  */
  248. extern int dxr2_tc6807af_set_decryption_mode(tc6807af_t* instance, int mode) 
  249. {
  250.   dxr2_t* dxr2Inst = (dxr2_t*) instance->data;
  251.   zivaDS_cssFlags_t oldFlags;
  252.   int status;
  253.   // read the old ziva flags
  254.   zivaDS_get_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  255.   // set Css mode
  256.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 1);
  257.   
  258.   // do the tc6807af function
  259.   status = tc6807af_set_decryption_mode(instance, mode);
  260.   // set non-Css mode 
  261.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 0);
  262.   // restore the old flags
  263.   zivaDS_restore_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  264.   // return status
  265.   return(status);
  266. }
  267. /**
  268.  *
  269.  * Send disc key to the TC6807AF
  270.  *
  271.  * @param instance The instance of TC6807AF to use
  272.  * @param key 0x800 byte array containing the disc key
  273.  *
  274.  * @return 0 on success, <0 on failure
  275.  *
  276.  */
  277. extern int dxr2_tc6807af_send_disc_key(tc6807af_t* instance, char* discKey)
  278. {
  279.   dxr2_t* dxr2Inst = (dxr2_t*) instance->data;
  280.   zivaDS_cssFlags_t oldFlags;
  281.   int status=0;
  282.   int endTime;
  283.   int loopFlag;
  284.   // disable IRQs
  285.   DXR2_ENTER_CRITICAL(dxr2Inst);
  286.   // check BM is not in use
  287.   if ((status = vxp524_bm_check_status(dxr2Inst->vxp524Instance)) < 0) {
  288.     
  289.     DXR2_EXIT_CRITICAL(dxr2Inst);
  290.     return(status);
  291.   }
  292.   // copy supplied buffer to DMA buffer
  293.   if (copy_from_user((void*) dxr2Inst->buffer[0], (void*) discKey, 0x800)) {
  294.     
  295.     DXR2_EXIT_CRITICAL(dxr2Inst);
  296.     return(-EFAULT);
  297.   }
  298.   // read the old ziva flags
  299.   zivaDS_get_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  300.   // do the command
  301.   zivaDS_command(dxr2Inst->zivaDSInstance, 
  302.  0x28,
  303.  0,0,0,0,0,0,
  304.  0,4);
  305.   // reset bus mastering
  306.   vxp524_bm_reset(dxr2Inst->vxp524Instance);
  307.   // do some ASIC twiddling
  308.   dxr2_asic_set_bits(dxr2Inst, 0x10, 0);
  309.   dxr2_asic_set_bits(dxr2Inst, 0x10, 0x10);
  310.   dxr2_asic_set_bits(dxr2Inst, 0x20, 0);
  311.   dxr2_asic_set_bits(dxr2Inst, 0x20, 0x20);
  312.   // tell the tc6807af to get ready
  313.   status = tc6807af_send_disc_key_part1(dxr2Inst->tc6807afInstance);
  314.   // send the data
  315.   // remembering to convert VIRTUAL address into BUS address...
  316.   vxp524_bm_send_data(dxr2Inst->vxp524Instance, virt_to_bus((void*) dxr2Inst->buffer[0]), 0x800, 0);
  317.   // set Css mode 
  318.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 1);
  319.   // wait for BM TX to finish
  320.   loopFlag=0;
  321.   endTime = jiffies + ((40*HZ)/100);
  322.   while(jiffies < endTime) {
  323.     
  324.     // let other things in
  325.     schedule();
  326.     // wait till DMA complete
  327.     if (vxp524_bm_completed(dxr2Inst->vxp524Instance, 0)) {
  328.       
  329.       loopFlag=1;
  330.       break;
  331.     }
  332.   }
  333.   
  334.   // clear bit4 of ASIC
  335.   dxr2_asic_set_bits(dxr2Inst, 0x10, 0);
  336.   
  337.   // disable PCI bus master
  338.   vxp524_set_bits(dxr2Inst->vxp524Instance, VXP524_INPUT_CFG, 0x10, 0);
  339.   // OK, bm no longer in use..
  340.   vxp524_bm_not_in_use(dxr2Inst->vxp524Instance);
  341.   // enable IRQs
  342.   DXR2_EXIT_CRITICAL(dxr2Inst);
  343.   // ok, tell the tc6807af to process it, if the timer didn't elapse
  344.   if (loopFlag) {
  345.     // OK, wait for tc6807af to process it
  346.     status = tc6807af_send_disc_key_part2(instance);
  347.   }
  348.   else {
  349.     
  350.     status = -ETIMEDOUT;
  351.   }
  352.   // set non-Css mode 
  353.   zivaDS_set_css_mode(dxr2Inst->zivaDSInstance, 0);
  354.   // restore the old flags
  355.   zivaDS_restore_css_flags(dxr2Inst->zivaDSInstance, &oldFlags);
  356.   // return status
  357.   return(status);
  358. }