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

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.  * Driver for the Toshiba TC6807AF CSS decode chip
  39.  * CSS functions
  40.  *
  41.  */
  42. #include <linux/types.h>
  43. #include <linux/errno.h>
  44. #include <linux/sched.h>
  45. #include <tc6807af.h>
  46. static int tc6807af_css_delay(tc6807af_t* instance, int value, int timeout);
  47. /**
  48.  *
  49.  * Set tc6807af decryption mode
  50.  *
  51.  * @param instance The instance of TC6807AF to use
  52.  * @param mode CSS mode one of TC6807AF_CSSDECRMODE_ON,TC6807AF_CSSDECRMODE_OFF
  53.  *
  54.  * @return 0 on success, <0 on failure
  55.  *
  56.  */
  57. extern int tc6807af_set_decryption_mode(tc6807af_t* instance, int mode)
  58. {
  59.   // different things depending on mode
  60.   switch(mode) {
  61.   case TC6807AF_CSSDECRMODE_OFF:
  62.     
  63.     tc6807af_set_loc(instance, TC6807AF_LOC2, 0xE7);
  64.     break;
  65.   case TC6807AF_CSSDECRMODE_ON:
  66.     
  67.     tc6807af_set_loc(instance, TC6807AF_LOC1, 3);
  68.     tc6807af_set_loc(instance, TC6807AF_LOC2, 0xE6);
  69.     tc6807af_set_loc(instance, TC6807AF_LOC0, 0);
  70.     tc6807af_set_loc(instance, TC6807AF_LOC0, 0x23);
  71.     break;
  72.   default:
  73.     return(-EINVAL);
  74.   }
  75.   
  76.   // OK
  77.   return(0);
  78. }
  79. /**
  80.  *
  81.  * Send challenge key to TC6807AF
  82.  *
  83.  * @param instance The instance of TC6807AF to use
  84.  * @param key 10 byte char array containing the key
  85.  *
  86.  * @return 0 on success, <0 on failure
  87.  *
  88.  */
  89. extern int tc6807af_send_challenge_key(tc6807af_t* instance, char* key)
  90. {
  91.   // send it
  92.   tc6807af_set_loc(instance, TC6807AF_LOCCHALLENGEKEY, key[0]);
  93.   tc6807af_set_loc(instance, TC6807AF_LOCCHALLENGEKEY+1, key[1]);
  94.   tc6807af_set_loc(instance, TC6807AF_LOCCHALLENGEKEY+2, key[2]);
  95.   tc6807af_set_loc(instance, TC6807AF_LOCCHALLENGEKEY+3, key[3]);
  96.   tc6807af_set_loc(instance, TC6807AF_LOCCHALLENGEKEY+4, key[4]);
  97.   tc6807af_set_loc(instance, TC6807AF_LOCCHALLENGEKEY+5, key[5]);
  98.   tc6807af_set_loc(instance, TC6807AF_LOCCHALLENGEKEY+6, key[6]);
  99.   tc6807af_set_loc(instance, TC6807AF_LOCCHALLENGEKEY+7, key[7]);
  100.   tc6807af_set_loc(instance, TC6807AF_LOCCHALLENGEKEY+8, key[8]);
  101.   tc6807af_set_loc(instance, TC6807AF_LOCCHALLENGEKEY+9, key[9]);
  102.   // delay
  103.   return(tc6807af_css_delay(instance, 0x18, 30));
  104. }
  105. /**
  106.  *
  107.  * Get challenge key from tc6807af
  108.  *
  109.  * @param instance The instance of TC6807AF to use
  110.  * @param key 10 byte char array to recieve the key
  111.  *
  112.  * @return 0 on success, <0 on failure
  113.  *
  114.  */
  115. extern int tc6807af_get_challenge_key(tc6807af_t* instance, char* key)
  116. {
  117.   int status;
  118.   
  119.   // delay
  120.   if ((status = tc6807af_css_delay(instance, 0x12, 30)) < 0) {
  121.     
  122.     return(status);
  123.   }
  124.   // send it
  125.   key[0] = tc6807af_get_loc(instance, TC6807AF_LOCCHALLENGEKEY);
  126.   key[1] = tc6807af_get_loc(instance, TC6807AF_LOCCHALLENGEKEY+1);
  127.   key[2] = tc6807af_get_loc(instance, TC6807AF_LOCCHALLENGEKEY+2);
  128.   key[3] = tc6807af_get_loc(instance, TC6807AF_LOCCHALLENGEKEY+3);
  129.   key[4] = tc6807af_get_loc(instance, TC6807AF_LOCCHALLENGEKEY+4);
  130.   key[5] = tc6807af_get_loc(instance, TC6807AF_LOCCHALLENGEKEY+5);
  131.   key[6] = tc6807af_get_loc(instance, TC6807AF_LOCCHALLENGEKEY+6);
  132.   key[7] = tc6807af_get_loc(instance, TC6807AF_LOCCHALLENGEKEY+7);
  133.   key[8] = tc6807af_get_loc(instance, TC6807AF_LOCCHALLENGEKEY+8);
  134.   key[9] = tc6807af_get_loc(instance, TC6807AF_LOCCHALLENGEKEY+9);
  135.   // ok
  136.   return(0);
  137. }
  138. /**
  139.  *
  140.  * Send the response key to the TC6807AF
  141.  *
  142.  * @param instance Instance of the TC6807AF to use
  143.  * @param key 5 byte char array containing the key to send
  144.  *
  145.  * @return 0 on success, <0 on failure
  146.  *
  147.  */
  148. extern int tc6807af_send_response_key(tc6807af_t* instance, char* key)
  149. {
  150.   // send it
  151.   tc6807af_set_loc(instance, TC6807AF_LOCRESPONSEKEY, key[0]);
  152.   tc6807af_set_loc(instance, TC6807AF_LOCRESPONSEKEY+1, key[1]);
  153.   tc6807af_set_loc(instance, TC6807AF_LOCRESPONSEKEY+2, key[2]);
  154.   tc6807af_set_loc(instance, TC6807AF_LOCRESPONSEKEY+3, key[3]);
  155.   tc6807af_set_loc(instance, TC6807AF_LOCRESPONSEKEY+4, key[4]);
  156.   // delay
  157.   return(tc6807af_css_delay(instance, 0x17, 30));
  158. }
  159. /**
  160.  *
  161.  * Get the response key from the TC6807AF
  162.  *
  163.  * @param instance Instance of the TC6807AF to use
  164.  * @param key 5 byte char array to receive the key
  165.  *
  166.  * @return 0 on success, <0 on failure
  167.  *
  168.  */
  169. extern int tc6807af_get_response_key(tc6807af_t* instance, char* key)
  170. {
  171.   // get it
  172.   key[0] = tc6807af_get_loc(instance, TC6807AF_LOCRESPONSEKEY);
  173.   key[1] = tc6807af_get_loc(instance, TC6807AF_LOCRESPONSEKEY+1);
  174.   key[2] = tc6807af_get_loc(instance, TC6807AF_LOCRESPONSEKEY+2);
  175.   key[3] = tc6807af_get_loc(instance, TC6807AF_LOCRESPONSEKEY+3);
  176.   key[4] = tc6807af_get_loc(instance, TC6807AF_LOCRESPONSEKEY+4);
  177.   return(0);
  178. }
  179. /**
  180.  *
  181.  * Part1 of The TC6807AF specific part of the send disc key protocol. 
  182.  * Since the disc key os 0x800 bytes, you usually DMA it to the chip somehow...
  183.  *
  184.  * @param instance Instance of the TC6807AF to use
  185.  *
  186.  * @return 0 on success, <0 on failure
  187.  *
  188.  */
  189. extern int tc6807af_send_disc_key_part1(tc6807af_t* instance)
  190. {
  191.   // send it
  192.   tc6807af_set_loc(instance, TC6807AF_LOC1, 1);
  193.   tc6807af_set_loc(instance, TC6807AF_LOC2, 0x24);
  194.   tc6807af_set_loc(instance, TC6807AF_LOC0, 0x15);
  195.   tc6807af_set_loc(instance, TC6807AF_LOC1, 3);
  196.   tc6807af_set_loc(instance, TC6807AF_LOC2, 0x26);
  197. }
  198. /**
  199.  *
  200.  * Part2 of The TC6807AF specific part of the send disc key protocol. 
  201.  * This bit waits until (I assume) the TC6807AF has finished processing the key
  202.  *
  203.  * @param instance Instance of the TC6807AF to use
  204.  *
  205.  * @return 0 on success, <0 on failure
  206.  *
  207.  */
  208. extern int tc6807af_send_disc_key_part2(tc6807af_t* instance)
  209. {
  210.   // wait for processing
  211.   return(tc6807af_css_delay(instance, -1, 100));
  212. }
  213. /**
  214.  *
  215.  * Send the disc title key
  216.  *
  217.  * @param instance Instance of the TC6807AF to use
  218.  * @param key 6 byte char array containing the key to send
  219.  *
  220.  * @return 0 on success, <0 on failure
  221.  *
  222.  */
  223. extern int tc6807af_send_title_key(tc6807af_t* instance, char* key)
  224. {
  225.   // send it
  226.   tc6807af_set_loc(instance, TC6807AF_LOCTITLEKEY, key[0]);
  227.   tc6807af_set_loc(instance, TC6807AF_LOCTITLEKEY+1, key[1]);
  228.   tc6807af_set_loc(instance, TC6807AF_LOCTITLEKEY+2, key[2]);
  229.   tc6807af_set_loc(instance, TC6807AF_LOCTITLEKEY+3, key[3]);
  230.   tc6807af_set_loc(instance, TC6807AF_LOCTITLEKEY+4, key[4]);
  231.   tc6807af_set_loc(instance, TC6807AF_LOCTITLEKEY+5, key[5]);
  232.   tc6807af_set_loc(instance, TC6807AF_LOC0, 0);
  233.   // wait for processing
  234.   return(tc6807af_css_delay(instance, 0x25, 20));
  235. }
  236. /**
  237.  *
  238.  * Sets register 0 to supplied value, and waits (max 30,000 usecs)
  239.  * until bit 7 and bit 6 of register 0 become unset. 
  240.  * This is used by the various CSS key functions to wait until processing
  241.  * has been completed (or has failed.. whichever happens first)
  242.  *
  243.  * @param instance tc6807af instance to use
  244.  * @param value Value to write to register 0 (-1 => don't write anything)
  245.  * @param timeout Timeout for operation in centiseconds (e.g. 3 = 0.03secs)
  246.  *
  247.  * @returns 0 on success, -ETIMEDOUT on timeout, or error
  248.  *
  249.  */
  250. static int tc6807af_css_delay(tc6807af_t* instance, int value, int timeout) 
  251. {
  252.   int endTime;
  253.   int tmp;
  254.   // write value
  255.   if (value != -1) {
  256.     
  257.     tc6807af_set_loc(instance, 0, value);
  258.   }
  259.   // extra tests
  260.   if ((value == 0) || (value == 0x12)) {
  261.     
  262.     return(0);
  263.   }
  264.   // loop for timeout centisecs (ish), or until condition met
  265.   endTime = jiffies + ((timeout*HZ)/100);
  266.   while(jiffies < endTime) {
  267.     
  268.     // let other things in
  269.     schedule();
  270.     // get register 0
  271.     tmp =  tc6807af_get_loc(instance, 0);
  272.     // if bit 7 is set
  273.     if (tmp & 0x80) {
  274.       
  275.       // if bit 6 is not set => OK!
  276.       if (!(tmp & 0x40)) {
  277. return(0);
  278.       }
  279.       
  280.       // Erk! bit6 wasn't set! => error
  281.       return(-ETIMEDOUT);
  282.     }
  283.   }
  284.   
  285.   // loop must have timed out
  286.   return(-ETIMEDOUT);
  287. }