亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? cdu31a.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
?? 第 1 頁 / 共 4 頁
字號:
/*
 * Sony CDU-31A CDROM interface device driver.
 *
 * Corey Minyard (minyard@wf-rch.cirr.com)
 *
 * Colossians 3:17
 *
 * The Sony interface device driver handles Sony interface CDROM
 * drives and provides a complete block-level interface as well as an
 * ioctl() interface compatible with the Sun (as specified in
 * include/linux/cdrom.h).  With this interface, CDROMs can be
 * accessed and standard audio CDs can be played back normally.
 *
 * This interface is (unfortunatly) a polled interface.  This is
 * because most Sony interfaces are set up with DMA and interrupts
 * disables.  Some (like mine) do not even have the capability to
 * handle interrupts or DMA.  For this reason you will see a lot of
 * the following:
 *
 *   retry_count = jiffies+ SONY_JIFFIES_TIMEOUT;
 *   while ((retry_count > jiffies) && (! <some condition to wait for))
 *   {
 *      while (handle_sony_cd_attention())
 *         ;
 *
 *      sony_sleep();
 *   }
 *   if (the condition not met)
 *   {
 *      return an error;
 *   }
 *
 * This ugly hack waits for something to happen, sleeping a little
 * between every try.  it also handles attentions, which are
 * asyncronous events from the drive informing the driver that a disk
 * has been inserted, removed, etc.
 *
 * One thing about these drives: They talk in MSF (Minute Second Frame) format.
 * There are 75 frames a second, 60 seconds a minute, and up to 75 minutes on a
 * disk.  The funny thing is that these are sent to the drive in BCD, but the
 * interface wants to see them in decimal.  A lot of conversion goes on.
 *
 *  Copyright (C) 1993  Corey Minyard
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */



#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/fs.h>
#include <linux/kernel.h>
#include <linux/hdreg.h>
#include <linux/genhd.h>
#include <linux/ioport.h>

#include <asm/system.h>
#include <asm/io.h>
#include <asm/segment.h>

#include <linux/cdrom.h>
#include <linux/cdu31a.h>

#define MAJOR_NR CDU31A_CDROM_MAJOR
#include "blk.h"

#define CDU31A_MAX_CONSECUTIVE_ATTENTIONS 10

static unsigned short cdu31a_addresses[] =
{
   0x340,	/* Standard configuration Sony Interface */
   0x1f88,	/* Fusion CD-16 */
   0x230,	/* SoundBlaster 16 card */
   0x360,	/* Secondary standard Sony Interface */
   0x320,	/* Secondary standard Sony Interface */
   0x330,	/* Secondary standard Sony Interface */
   0
};


static int handle_sony_cd_attention(void);
static int read_subcode(void);
static void sony_get_toc(void);
static int scd_open(struct inode *inode, struct file *filp);
static void do_sony_cd_cmd(unsigned char cmd,
                           unsigned char *params,
                           unsigned int num_params,
                           unsigned char *result_buffer,
                           unsigned int *result_size);
static void size_to_buf(unsigned int size,
                        unsigned char *buf);


/* The base I/O address of the Sony Interface.  This is a variable (not a
   #define) so it can be easily changed via some future ioctl() */
static unsigned short sony_cd_base_io = 0;

/*
 * The following are I/O addresses of the various registers for the drive.  The
 * comment for the base address also applies here.
 */
static volatile unsigned short sony_cd_cmd_reg;
static volatile unsigned short sony_cd_param_reg;
static volatile unsigned short sony_cd_write_reg;
static volatile unsigned short sony_cd_control_reg;
static volatile unsigned short sony_cd_status_reg;
static volatile unsigned short sony_cd_result_reg;
static volatile unsigned short sony_cd_read_reg;
static volatile unsigned short sony_cd_fifost_reg;


static int sony_disc_changed = 1;          /* Has the disk been changed
                                              since the last check? */
static int sony_toc_read = 0;              /* Has the table of contents been
                                              read? */
static int sony_spun_up = 0;               /* Has the drive been spun up? */
static unsigned int sony_buffer_size;      /* Size in bytes of the read-ahead
                                              buffer. */
static unsigned int sony_buffer_sectors;   /* Size (in 2048 byte records) of
                                              the read-ahead buffer. */
static unsigned int sony_usage = 0;        /* How many processes have the
                                              drive open. */

static volatile int sony_first_block = -1; /* First OS block (512 byte) in
                                              the read-ahead buffer */
static volatile int sony_last_block = -1;  /* Last OS block (512 byte) in
                                              the read-ahead buffer */

static struct s_sony_toc *sony_toc;              /* Points to the table of
                                                    contents. */
static struct s_sony_subcode * volatile last_sony_subcode; /* Points to the last
                                                    subcode address read */
static unsigned char * volatile sony_buffer;     /* Points to the read-ahead
                                                    buffer */

static volatile int sony_inuse = 0;  /* Is the drive in use?  Only one operation at a time
                                        allowed */

static struct wait_queue * sony_wait = NULL;

static struct task_struct *has_cd_task = NULL;  /* The task that is currently using the
                                                   CDROM drive, or NULL if none. */

/*
 * The audio status uses the values from read subchannel data as specified
 * in include/linux/cdrom.h.
 */
static volatile int sony_audio_status = CDROM_AUDIO_NO_STATUS;

/*
 * The following are a hack for pausing and resuming audio play.  The drive
 * does not work as I would expect it, if you stop it then start it again,
 * the drive seeks back to the beginning and starts over.  This holds the
 * position during a pause so a resume can restart it.  It uses the
 * audio status variable above to tell if it is paused.
 */
unsigned volatile char cur_pos_msf[3] = { 0, 0, 0 };
unsigned volatile char final_pos_msf[3] = { 0, 0, 0 };

/*
 * This routine returns 1 if the disk has been changed since the last
 * check or 0 if it hasn't.  Setting flag to 0 resets the changed flag.
 */
int
check_cdu31a_media_change(int full_dev, int flag)
{
   int retval, target;


   target = MINOR(full_dev);

   if (target > 0) {
      printk("Sony CD-ROM request error: invalid device.\n");
      return 0;
   }

   retval = sony_disc_changed;
   if (!flag)
   {
      sony_disc_changed = 0;
   }

   return retval;
}


/*
 * Wait a little while (used for polling the drive).  If in initialization,
 * setting a timeout doesn't work, so just loop for a while.
 */
static inline void
sony_sleep(void)
{
   current->state = TASK_INTERRUPTIBLE;
   current->timeout = jiffies;
   schedule();
}


/*
 * The following are convenience routine to read various status and set
 * various conditions in the drive.
 */
static inline int
is_attention(void)
{
   return((inb(sony_cd_status_reg) & SONY_ATTN_BIT) != 0);
}

static inline int
is_busy(void)
{
   return((inb(sony_cd_status_reg) & SONY_BUSY_BIT) != 0);
}

static inline int
is_data_ready(void)
{
   return((inb(sony_cd_status_reg) & SONY_DATA_RDY_BIT) != 0);
}

static inline int
is_data_requested(void)
{
   return((inb(sony_cd_status_reg) & SONY_DATA_REQUEST_BIT) != 0);
}

static inline int
is_result_ready(void)
{
   return((inb(sony_cd_status_reg) & SONY_RES_RDY_BIT) != 0);
}

static inline int
is_param_write_rdy(void)
{
   return((inb(sony_cd_fifost_reg) & SONY_PARAM_WRITE_RDY_BIT) != 0);
}

static inline void
reset_drive(void)
{
   outb(SONY_DRIVE_RESET_BIT, sony_cd_control_reg);
}

static inline void
clear_attention(void)
{
   outb(SONY_ATTN_CLR_BIT, sony_cd_control_reg);
}

static inline void
clear_result_ready(void)
{
   outb(SONY_RES_RDY_CLR_BIT, sony_cd_control_reg);
}

static inline void
clear_data_ready(void)
{
   outb(SONY_DATA_RDY_CLR_BIT, sony_cd_control_reg);
}

static inline void
clear_param_reg(void)
{
   outb(SONY_PARAM_CLR_BIT, sony_cd_control_reg);
}

static inline unsigned char
read_status_register(void)
{
   return(inb(sony_cd_status_reg));
}

static inline unsigned char
read_result_register(void)
{
   return(inb(sony_cd_result_reg));
}

static inline unsigned char
read_data_register(void)
{
   return(inb(sony_cd_read_reg));
}

static inline void
write_param(unsigned char param)
{
   outb(param, sony_cd_param_reg);
}

static inline void
write_cmd(unsigned char cmd)
{
   outb(cmd, sony_cd_cmd_reg);
   outb(SONY_RES_RDY_INT_EN_BIT, sony_cd_control_reg);
}

/*
 * Set the drive parameters so the drive will auto-spin-up when a
 * disk is inserted.
 */
static void
set_drive_params(void)
{
   unsigned char res_reg[2];
   unsigned int res_size;
   unsigned char params[3];


   params[0] = SONY_SD_MECH_CONTROL;
   params[1] = 0x03;
   do_sony_cd_cmd(SONY_SET_DRIVE_PARAM_CMD,
                  params,
                  2,
                  res_reg,
                  &res_size);
   if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
   {
      printk("  Unable to set mechanical parameters: 0x%2.2x\n", res_reg[1]);
   }
}

/*
 * This code will reset the drive and attempt to restore sane parameters.
 */
static void
restart_on_error(void)
{
   unsigned char res_reg[2];
   unsigned int res_size;
   unsigned int retry_count;


   printk("cdu31a: Resetting drive on error\n");
   reset_drive();
   retry_count = jiffies + SONY_RESET_TIMEOUT;
   while ((retry_count > jiffies) && (!is_attention()))
   {
      sony_sleep();
   }
   set_drive_params();
   do_sony_cd_cmd(SONY_SPIN_UP_CMD, NULL, 0, res_reg, &res_size);
   if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
   {
      printk("cdu31a: Unable to spin up drive: 0x%2.2x\n", res_reg[1]);
   }

   current->state = TASK_INTERRUPTIBLE;
   current->timeout = jiffies + 200;
   schedule();

   do_sony_cd_cmd(SONY_READ_TOC_CMD, NULL, 0, res_reg, &res_size);
   if ((res_size < 2) || ((res_reg[0] & 0x20) == 0x20))
   {
      printk("cdu31a: Unable to read TOC: 0x%2.2x\n", res_reg[1]);
   }
   sony_get_toc();
   if (!sony_toc_read)
   {
      printk("cdu31a: Unable to get TOC data\n");
   }
}

/*
 * This routine writes data to the parameter register.  Since this should
 * happen fairly fast, it is polled with no OS waits between.
 */
static int
write_params(unsigned char *params,
             int num_params)
{
   unsigned int retry_count;


   retry_count = SONY_READY_RETRIES;
   while ((retry_count > 0) && (!is_param_write_rdy()))
   {
      retry_count--;
   }
   if (!is_param_write_rdy())
   {
      return -EIO;
   }

   while (num_params > 0)
   {
      write_param(*params);
      params++;
      num_params--;
   }

   return 0;
}


/*
 * The following reads data from the command result register.  It is a
 * fairly complex routine, all status info flows back through this
 * interface.  The algorithm is stolen directly from the flowcharts in
 * the drive manual.
 */
static void
get_result(unsigned char *result_buffer,
           unsigned int *result_size)
{
   unsigned char a, b;
   int i;
   unsigned int retry_count;


   while (handle_sony_cd_attention())
      ;
   /* Wait for the result data to be ready */
   retry_count = jiffies + SONY_JIFFIES_TIMEOUT;
   while ((retry_count > jiffies) && (is_busy() || (!(is_result_ready()))))
   {
      sony_sleep();

      while (handle_sony_cd_attention())
         ;
   }
   if (is_busy() || (!(is_result_ready())))
   {
      result_buffer[0] = 0x20;
      result_buffer[1] = SONY_TIMEOUT_OP_ERR;
      *result_size = 2;
      return;
   }

   /*
    * Get the first two bytes.  This determines what else needs
    * to be done.
    */
   clear_result_ready();
   a = read_result_register();
   *result_buffer = a;
   result_buffer++;
   b = read_result_register();
   *result_buffer = b;
   result_buffer++;
   *result_size = 2;

   /*
    * 0x20 means an error occured.  Byte 2 will have the error code.
    * Otherwise, the command succeded, byte 2 will have the count of

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美一区二区黄| 一区二区三区日韩欧美精品| 国产精品久久久久aaaa樱花 | 欧美亚洲国产一区二区三区va| 制服丝袜日韩国产| 中文字幕亚洲一区二区av在线| 婷婷开心激情综合| 91免费版在线| 国产亚洲综合色| 日本欧美加勒比视频| 9色porny自拍视频一区二区| 欧美tickle裸体挠脚心vk| 一区二区三区在线视频观看58 | 麻豆国产精品777777在线| 日本精品一区二区三区高清 | 欧美剧在线免费观看网站| 亚洲精品一区在线观看| 午夜伊人狠狠久久| 一本一道综合狠狠老| 国产精品美女久久福利网站| 激情成人午夜视频| 日韩一级二级三级| 日韩av一区二| 欧美二区乱c少妇| 亚洲bdsm女犯bdsm网站| 欧美影视一区在线| 亚洲午夜日本在线观看| 在线视频综合导航| 一区二区三区四区在线| 色av一区二区| 亚洲小少妇裸体bbw| 欧美日韩在线播放三区四区| 亚洲精品欧美综合四区| 91视频一区二区三区| 亚洲日穴在线视频| 欧美亚洲免费在线一区| 午夜精品福利视频网站| 正在播放亚洲一区| 美女视频一区二区三区| 精品国产精品网麻豆系列| 精品无码三级在线观看视频| wwwwww.欧美系列| 成人一区二区三区视频| 亚洲同性gay激情无套| 91免费在线看| 五月激情六月综合| 99久久国产综合精品女不卡| 一区二区三区四区不卡在线| 欧美一区二区在线免费观看| 亚洲妇女屁股眼交7| 精品视频1区2区| 日韩二区三区在线观看| 精品sm捆绑视频| 国产制服丝袜一区| 国产精品国产三级国产aⅴ入口| av电影在线观看不卡| 亚洲线精品一区二区三区八戒| 欧美一区二区三级| 懂色av一区二区夜夜嗨| 亚洲一区二区三区自拍| 欧美成人免费网站| 91视频91自| 人人狠狠综合久久亚洲| 日本一区二区三区视频视频| 色哟哟欧美精品| 麻豆成人av在线| 一区在线中文字幕| 欧美一级日韩一级| 成人高清免费观看| 日韩高清在线一区| 国产精品美日韩| 在线播放91灌醉迷j高跟美女| 国产最新精品精品你懂的| 一区二区免费视频| 久久久久久久久久久久久女国产乱| www.av亚洲| 另类小说色综合网站| 国产精品久久综合| 日韩欧美国产成人一区二区| 91在线一区二区三区| 精品一区二区三区在线视频| 亚洲精品乱码久久久久久黑人| 精品久久人人做人人爽| 欧美午夜不卡视频| 成人精品免费视频| 蜜臀国产一区二区三区在线播放| 中文字幕av一区二区三区免费看| 91精品国产综合久久婷婷香蕉| 成人动漫一区二区在线| 国产综合久久久久影院| 午夜视频一区在线观看| 一区二区三区免费在线观看| 欧美韩日一区二区三区四区| 亚洲精品一线二线三线无人区| 欧美精品一级二级三级| 色狠狠av一区二区三区| 99视频精品全部免费在线| 国产麻豆成人精品| 精品综合久久久久久8888| 天天综合日日夜夜精品| 亚洲午夜激情av| 亚洲狼人国产精品| 自拍视频在线观看一区二区| 中文字幕av在线一区二区三区| 精品99一区二区| 久久先锋影音av鲁色资源| 欧美大片在线观看一区二区| 欧美日韩成人综合| 欧美性一区二区| 欧美日韩一区高清| 欧美日韩不卡一区二区| 欧美体内she精视频| 欧美综合视频在线观看| 在线视频观看一区| 在线精品视频小说1| 欧美日韩国产电影| 91精品国产福利在线观看| 欧美精品一二三| 日韩精品一区二区三区视频 | 亚洲高清中文字幕| 亚洲狠狠爱一区二区三区| 亚洲一区二区中文在线| 午夜视频一区二区| 亚洲成人精品影院| 人禽交欧美网站| 国产一区二区三区久久久| 国产精品99久久久久久久vr| 丁香六月综合激情| 一本到三区不卡视频| 欧美日韩第一区日日骚| 7777精品伊人久久久大香线蕉 | 欧美肥妇bbw| 欧美sm美女调教| 国产午夜精品一区二区三区嫩草| 欧美经典一区二区| 亚洲欧洲国产日韩| 亚洲成精国产精品女| 久久超碰97中文字幕| 成人午夜免费视频| 色菇凉天天综合网| 欧美va亚洲va香蕉在线| 久久久久久久电影| 亚洲黄色片在线观看| 日本美女视频一区二区| 国产高清在线精品| 色网站国产精品| 欧美一区二区三区四区五区| 久久久精品免费观看| 亚洲激情一二三区| 麻豆精品一区二区av白丝在线| 国产麻豆精品一区二区| 欧美色爱综合网| 精品91自产拍在线观看一区| 亚洲男人的天堂在线aⅴ视频| 日韩制服丝袜av| www.亚洲色图| 日韩午夜小视频| ...中文天堂在线一区| 日韩福利电影在线观看| 99热精品国产| 久久综合九色综合97婷婷女人 | 国产精品一区二区果冻传媒| 欧美综合视频在线观看| 国产偷国产偷精品高清尤物| 一区二区三区在线视频观看58| 国产一区二区伦理| 精品视频色一区| 亚洲人成精品久久久久久| 精品一二三四在线| 欧美人牲a欧美精品| 自拍偷拍欧美激情| 国产成人无遮挡在线视频| 91精品在线观看入口| 伊人夜夜躁av伊人久久| 国产高清久久久| 日韩一区二区视频在线观看| 亚洲一区视频在线| av中文字幕一区| 国产日韩欧美一区二区三区综合| 三级一区在线视频先锋| 色狠狠av一区二区三区| 中文字幕精品—区二区四季| 国产资源在线一区| 精品久久久久久综合日本欧美| 亚洲6080在线| 欧美做爰猛烈大尺度电影无法无天| 欧美高清一级片在线观看| 狠狠色狠狠色综合| 日韩午夜精品电影| 日本系列欧美系列| 欧美美女直播网站| 亚洲一区视频在线观看视频| 91精品91久久久中77777| 亚洲视频一区二区在线| 99久久精品一区| 成人免费在线视频| 91色乱码一区二区三区| 亚洲黄网站在线观看| 色婷婷久久久久swag精品| 伊人色综合久久天天人手人婷|