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

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 C-Cube Ziva-DS MPEG decoder chip
  39.  * CSS functions.
  40.  *
  41.  */
  42. #include <linux/types.h>
  43. #ifdef __KERNEL_STRICT_NAME
  44. pooo
  45. #endif
  46. #include <linux/errno.h>
  47. #include <linux/sched.h>
  48. #include <zivaDS.h>
  49. static int zivaDS_css_delay(zivaDS_t* instance, int cssStart, int command, int timeout, 
  50.     int test);
  51. /**
  52.  *
  53.  * Sets the CSS decryption mode
  54.  *
  55.  * @param instance Ziva instance to use
  56.  * @param mode CSS mode one of ZIVADS_CSSDECRMODE_ON,ZIVADS_CSSDECRMODE_OFF
  57.  *
  58.  * @return 0 on success, <0 on failure
  59.  *
  60.  */
  61. extern int zivaDS_set_decryption_mode(zivaDS_t* instance, int mode)
  62. {
  63.   // get start of CSS data in ziva
  64.   int cssStart = zivaDS_get_mem(instance, ZIVADS_CSS_START);
  65.   int command;
  66.   int tmp;
  67.   int status;
  68.   // check CSS status
  69.   if (zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_STATUS) != 1) {
  70.     
  71.     return(-EBUSY);
  72.   }
  73.   // ziva command (for some reason...)
  74.   if ((status = zivaDS_command(instance, 0x137,1,0,0,0,0,0,0,3)) < 0) {
  75.     
  76.     return(status);
  77.   }
  78.   // set the mode
  79.   switch(mode) {
  80.   case ZIVADS_CSSDECRMODE_OFF:
  81.     
  82.     command = 8;
  83.     break;
  84.   case ZIVADS_CSSDECRMODE_ON:
  85.     command = 7;
  86.     break;
  87.   default:
  88.     return(-EINVAL);
  89.     break;
  90.   }
  91.   // wait until processing finished
  92.   if ((status = zivaDS_css_delay(instance, cssStart, command, 30, 1)) <0) {
  93.     
  94.     return(status);
  95.   }
  96.   // last bit
  97.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_COMMAND, 0);
  98.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_STATUS, 0);
  99.   tmp = zivaDS_get_mem(instance, ZIVADS_CSS_UNKNOWN0) & 0xfffffffb;
  100.   if (mode == ZIVADS_CSSDECRMODE_OFF) {
  101.     
  102.     tmp |= 0x4;
  103.   }
  104.   zivaDS_set_mem(instance, ZIVADS_CSS_UNKNOWN0, tmp);
  105.   // OK
  106.   return(0);
  107. }
  108. /**
  109.  *
  110.  * Send the challenge key to the Ziva
  111.  *
  112.  * @param instance Ziva instance to use
  113.  * @param key 10 byte char array containing the key
  114.  *
  115.  * @return 0 on success, <0 on failure
  116.  *
  117.  */
  118. extern int zivaDS_send_challenge_key(zivaDS_t* instance, char* key)
  119. {
  120.   // get start of CSS data in ziva
  121.   int cssStart = zivaDS_get_mem(instance, ZIVADS_CSS_START);
  122.   
  123.   // check CSS status
  124.   if (zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_STATUS) != 1) {
  125.     
  126.     return(-EBUSY);
  127.   }
  128.   // send it
  129.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDCHALLENGEKEY-(0*4), key[0]);
  130.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDCHALLENGEKEY-(1*4), key[1]);
  131.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDCHALLENGEKEY-(2*4), key[2]);
  132.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDCHALLENGEKEY-(3*4), key[3]);
  133.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDCHALLENGEKEY-(4*4), key[4]);
  134.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDCHALLENGEKEY-(5*4), key[5]);
  135.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDCHALLENGEKEY-(6*4), key[6]);
  136.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDCHALLENGEKEY-(7*4), key[7]);
  137.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDCHALLENGEKEY-(8*4), key[8]);
  138.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDCHALLENGEKEY-(9*4), key[9]);
  139.   
  140.   // wait until processing finished
  141.   return(zivaDS_css_delay(instance, cssStart, 3, 30, 1));
  142. }
  143. /**
  144.  *
  145.  * Get the challenge key from the Ziva
  146.  *
  147.  * @param instance Instance of the Ziva to use
  148.  * @param key 10 byte char array to put the key in
  149.  *
  150.  * @return 0 on success, <0 on failure
  151.  *
  152.  */
  153. extern int zivaDS_get_challenge_key(zivaDS_t* instance, char* key)
  154. {
  155.   int status;
  156.   // get start of CSS data in ziva
  157.   int cssStart = zivaDS_get_mem(instance, ZIVADS_CSS_START);
  158.   // check CSS status
  159.   if (zivaDS_get_mem(instance, cssStart + ZIVADS_CSSOFFSET_STATUS) != 1) {
  160.     
  161.     return(-EBUSY);
  162.   }
  163.   // do it
  164.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_COMMAND, 1);
  165.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_STATUS, 0);
  166.   if ((status = zivaDS_command(instance, 0x137,1,0,0,0,0,0,0,3)) < 0) {
  167.     
  168.     return(status);
  169.   }
  170.   // delay
  171.   if ((status = zivaDS_css_delay(instance, cssStart, -1, 30, 1)) < 0) {
  172.     
  173.     return(status);
  174.   }
  175.   // get it
  176.   key[0] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETCHALLENGEKEY);
  177.   key[1] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETCHALLENGEKEY-(1*4));
  178.   key[2] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETCHALLENGEKEY-(2*4));
  179.   key[3] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETCHALLENGEKEY-(3*4));
  180.   key[4] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETCHALLENGEKEY-(4*4));
  181.   key[5] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETCHALLENGEKEY-(5*4));
  182.   key[6] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETCHALLENGEKEY-(6*4));
  183.   key[7] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETCHALLENGEKEY-(7*4));
  184.   key[8] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETCHALLENGEKEY-(8*4));
  185.   key[9] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETCHALLENGEKEY-(9*4));
  186.   // ok
  187.   return(0);
  188. }
  189. /**
  190.  *
  191.  * Send the response key to the Ziva
  192.  *
  193.  * @param instance Instance of the Ziva to use
  194.  * @param key 5 byte char array containing the key
  195.  *
  196.  * @return 0 on success, <0 on failure
  197.  *
  198.  */
  199. extern int zivaDS_send_response_key(zivaDS_t* instance, char* key)
  200. {
  201.   // get start of CSS data in ziva
  202.   int cssStart = zivaDS_get_mem(instance, ZIVADS_CSS_START);
  203.   // check CSS status
  204.   if (zivaDS_get_mem(instance, cssStart + ZIVADS_CSSOFFSET_STATUS) != 1) {
  205.     
  206.     return(-EBUSY);
  207.   }
  208.   
  209.   // send it
  210.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDRESPONSEKEY, key[0]);
  211.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDRESPONSEKEY-(1*4), key[1]);
  212.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDRESPONSEKEY-(2*4), key[2]);
  213.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDRESPONSEKEY-(3*4), key[3]);
  214.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDRESPONSEKEY-(4*4), key[4]);
  215.   // wait until processing finished
  216.   return(zivaDS_css_delay(instance, cssStart, 2, 30, 1));
  217. }
  218. /**
  219.  *
  220.  * Get the response key from the Ziva
  221.  *
  222.  * @param instance Instance of the Ziva to use
  223.  * @param key 5 byte char array to put the key in
  224.  *
  225.  * @return 0 on success, <0 on failure
  226.  *
  227.  */
  228. extern int zivaDS_get_response_key(zivaDS_t* instance, char* key)
  229. {
  230.   int status;
  231.   // get start of CSS data in ziva
  232.   int cssStart = zivaDS_get_mem(instance, ZIVADS_CSS_START);
  233.   // check CSS status
  234.   if (zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_STATUS) != 1) {
  235.     
  236.     return(-EBUSY);
  237.   }
  238.   // wait for processing
  239.   if ((status = zivaDS_css_delay(instance, cssStart, 4, 30, 1)) <0) {
  240.     
  241.     return(status);
  242.   }
  243.   
  244.   // get it
  245.   key[0] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETRESPONSEKEY);
  246.   key[1] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETRESPONSEKEY-(1*4));
  247.   key[2] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETRESPONSEKEY-(2*4));
  248.   key[3] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETRESPONSEKEY-(3*4));
  249.   key[4] = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_GETRESPONSEKEY-(4*4));
  250.   // done
  251.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_COMMAND, 0);
  252.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_STATUS, 0);
  253.   // OK
  254.   return(0);
  255. }
  256. /**
  257.  *
  258.  * Part 1 of send disc key (setup)
  259.  *
  260.  * @param instance Instance of the Ziva to use
  261.  *
  262.  * @return 0 on success, or <0 on failure
  263.  *
  264.  */
  265. extern int zivaDS_send_disc_key_part1(zivaDS_t* instance)
  266. {
  267.   int status;
  268.   // get start of CSS data in ziva
  269.   int cssStart = zivaDS_get_mem(instance, ZIVADS_CSS_START);
  270.   // check CSS status
  271.   if (zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_STATUS) != 1) {
  272.     
  273.     return(-EBUSY);
  274.   }
  275.   // do command
  276.   if ((status = zivaDS_command(instance, 0x137,1,0,0,0,0,0,0,3)) < 0) {
  277.     
  278.     return(status);
  279.   }
  280.   // wait for processing       
  281.   return(zivaDS_css_delay(instance, cssStart, 5, 30, 3));
  282. }
  283. /**
  284.  *
  285.  * Part 2 of send disc key (finalise)
  286.  *
  287.  * @param instance Instance of the Ziva to use
  288.  *
  289.  * @return 0 on success, or <0 on failure
  290.  *
  291.  */
  292. extern int zivaDS_send_disc_key_part2(zivaDS_t* instance)
  293. {
  294.   // get start of CSS data in ziva
  295.   int cssStart = zivaDS_get_mem(instance, ZIVADS_CSS_START);
  296.   // end
  297.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_COMMAND, 0);
  298.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_STATUS, 0);
  299.   
  300.   // OK
  301.   return(0);
  302. }
  303. /**
  304.  *
  305.  * Send the disc title key
  306.  *
  307.  * @param instance Instance of the Ziva to use
  308.  * @param key 5 byte char array containing the key to send
  309.  *
  310.  * @return 0 on success, <0 on failure
  311.  *
  312.  */
  313. extern int zivaDS_send_title_key(zivaDS_t* instance, char* key)
  314. {
  315.   int status;
  316.   // get start of CSS data in ziva
  317.   int cssStart = zivaDS_get_mem(instance, ZIVADS_CSS_START);
  318.   // check CSS status
  319.   if (zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_STATUS) != 1) {
  320.     
  321.     return(-EBUSY);
  322.   }
  323.   // command
  324.   if ((status = zivaDS_command(instance, 0x137,1,0,0,0,0,0,0,3)) < 0) {
  325.     
  326.     return(status);
  327.   }
  328.   // send it
  329.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDTITLEKEY-(0*4), key[0]);
  330.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDTITLEKEY-(1*4), key[1]);
  331.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDTITLEKEY-(2*4), key[2]);
  332.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDTITLEKEY-(3*4), key[3]);
  333.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_SENDTITLEKEY-(4*4), key[4]);
  334.   // wait for processing
  335.   if ((status = zivaDS_css_delay(instance, cssStart, 6, 30, 1)) < 0) {
  336.     
  337.     return(status);
  338.   }
  339.   
  340.   // end
  341.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_COMMAND, 0);
  342.   zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_STATUS, 0);
  343.   // OK
  344.   return(0);
  345. }
  346. /**
  347.  *
  348.  * Sets write command to the ziva, and waits (max timeout usecs)
  349.  * until ziva status becomes 1 (or timeout)
  350.  * This is used by the various CSS key functions to wait until processing
  351.  * has been completed (or has failed.. whichever happens first)
  352.  *
  353.  * @param instance zivaDS instance to use
  354.  * @param cssStart Offset into the Ziva memory of the CSS data
  355.  * @param command Command to write
  356.  * @param timeout Timeout for operation in centiseconds (e.g. 3 = 0.03secs)
  357.  * @param test Value to test status against
  358.  *
  359.  * @returns 0 on success, -ETIMEDOUT on timeout
  360.  *
  361.  */
  362. static int zivaDS_css_delay(zivaDS_t* instance, int cssStart, int command, int timeout, 
  363.     int test) 
  364. {
  365.   int endTime;
  366.   int tmp;
  367.   // write command
  368.   if (command != -1) {
  369.     zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_COMMAND, command);
  370.     zivaDS_set_mem(instance, cssStart+ZIVADS_CSSOFFSET_STATUS, 0);
  371.   }
  372.   // loop for timeout centisecs (ish), or until condition met
  373.   endTime = jiffies + ((timeout*HZ)/100);
  374.   while(jiffies < endTime) {
  375.     
  376.     // let other things in
  377.     schedule();
  378.     // get value
  379.     tmp = zivaDS_get_mem(instance, cssStart+ZIVADS_CSSOFFSET_STATUS);
  380.     // if test met, exit
  381.     if (tmp == test) {
  382.       
  383.       return(0);
  384.     }
  385.   }
  386.   
  387.   // loop must have timed out
  388.   return(-ETIMEDOUT);
  389. }
  390.