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

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

?? scsi.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
?? 第 1 頁 / 共 4 頁
字號:
/*
 *	scsi.c Copyright (C) 1992 Drew Eckhardt 
 *	generic mid-level SCSI driver by
 *		Drew Eckhardt 
 *
 *	<drew@colorado.edu>
 *
 *	Bug correction thanks go to : 
 *		Rik Faith <faith@cs.unc.edu>
 *		Tommy Thorn <tthorn>
 *		Thomas Wuensche <tw@fgb1.fgb.mw.tu-muenchen.de>
 * 
 *       Modified by Eric Youngdale eric@tantalus.nrl.navy.mil to
 *       add scatter-gather, multiple outstanding request, and other
 *       enhancements.
 */

#include <asm/system.h>
#include <linux/sched.h>
#include <linux/timer.h>
#include <linux/string.h>

#include "../block/blk.h"
#include "scsi.h"
#include "hosts.h"
#include "constants.h"

/*
static const char RCSid[] = "$Header: /usr/src/linux/kernel/blk_drv/scsi/RCS/scsi.c,v 1.5 1993/09/24 12:45:18 drew Exp drew $";
*/

/* Command groups 3 and 4 are reserved and should never be used.  */
const unsigned char scsi_command_size[8] = { 6, 10, 10, 12, 12, 12, 10, 10 };

#define INTERNAL_ERROR (panic ("Internal error in file %s, line %d.\n", __FILE__, __LINE__))

static void scsi_done (Scsi_Cmnd *SCpnt);
static int update_timeout (Scsi_Cmnd *, int);
static void print_inquiry(unsigned char *data);
static void scsi_times_out (Scsi_Cmnd * SCpnt);

static int time_start;
static int time_elapsed;

#define MAX_SCSI_DEVICE_CODE 10
const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE] =
{
 "Direct-Access    ",
 "Sequential-Access",
 "Printer          ",
 "Processor        ",
 "WORM             ",
 "CD-ROM           ",
 "Scanner          ",
 "Optical Device   ",
 "Medium Changer   ",
 "Communications   "
};


/*
	global variables : 
	NR_SCSI_DEVICES is the number of SCSI devices we have detected, 
	scsi_devices an array of these specifing the address for each 
	(host, id, LUN)
*/
	
int NR_SCSI_DEVICES=0;

Scsi_Device * scsi_devices = NULL;

static unsigned char generic_sense[6] = {REQUEST_SENSE, 0,0,0, 255, 0};

/* We make this not static so that we can read the array with gdb. */
/* static */ Scsi_Cmnd * last_cmnd = NULL;

/*
 *	As the scsi do command functions are inteligent, and may need to 
 *	redo a command, we need to keep track of the last command 
 *	executed on each one.
 */

#define WAS_RESET 	0x01
#define WAS_TIMEDOUT 	0x02
#define WAS_SENSE	0x04
#define IS_RESETTING	0x08
#define ASKED_FOR_SENSE 0x10
/* #define NEEDS_JUMPSTART 0x20  defined in hosts.h */

/*
 *	This is the number  of clock ticks we should wait before we time out 
 *	and abort the command.  This is for  where the scsi.c module generates 
 *	the command, not where it originates from a higher level, in which
 *	case the timeout is specified there.
 *
 *	ABORT_TIMEOUT and RESET_TIMEOUT are the timeouts for RESET and ABORT
 *	respectively.
 */

#ifdef DEBUG
	#define SCSI_TIMEOUT 500
#else
	#define SCSI_TIMEOUT 100
#endif

#ifdef DEBUG
	#define SENSE_TIMEOUT SCSI_TIMEOUT
	#define ABORT_TIMEOUT SCSI_TIMEOUT
	#define RESET_TIMEOUT SCSI_TIMEOUT
#else
	#define SENSE_TIMEOUT 50
	#define RESET_TIMEOUT 50
	#define ABORT_TIMEOUT 50
	#define MIN_RESET_DELAY 100
#endif

/* The following devices are known not to tolerate a lun != 0 scan for
   one reason or another.  Some will respond to all luns, others will
   lock up. */

     struct blist{
       char * vendor;
       char * model;
       char * revision; /* Latest revision known to be bad.  Not used yet */
     };

static struct blist blacklist[] = 
{
   {"DENON","DRD-25X","V"},   /* A cdrom that locks up when probed at lun != 0 */
   {"IMS", "CDD521/10","2.06"},   /* Locks-up when LUN>0 polled. */
   {"MAXTOR","XT-3280","PR02"},   /* Locks-up when LUN>0 polled. */
   {"MAXTOR","XT-4380S","B3C"},   /* Locks-up when LUN>0 polled. */
   {"MAXTOR","MXT-1240S","I1.2"}, /* Locks up when LUN > 0 polled */
   {"MAXTOR","XT-4170S","B5A"},   /* Locks-up sometimes when LUN>0 polled. */
   {"MAXTOR","XT-8760S","B7B"},   /* guess what? */
   {"NEC","CD-ROM DRIVE:841","1.0"},  /* Locks-up when LUN>0 polled. */
   {"RODIME","RO3000S","2.33"},  /* Locks up if polled for lun != 0 */
   {"SEAGATE", "ST157N", "\004|j"}, /* causes failed REQUEST SENSE on lun 1 for aha152x
				     * controller, which causes SCSI code to reset bus.*/
   {"SEAGATE", "ST296","921"},   /* Responds to all lun */
   {"SONY","CD-ROM CDU-541","4.3d"},
   {"TANDBERG","TDC 3600","U07"},  /* Locks up if polled for lun != 0 */
   {"TEAC","CD-ROM","1.06"},	/* causes failed REQUEST SENSE on lun 1 for seagate
				 * controller, which causes SCSI code to reset bus.*/
   {"TEXEL","CD-ROM","1.06"},   /* causes failed REQUEST SENSE on lun 1 for seagate
				 * controller, which causes SCSI code to reset bus.*/
   {NULL, NULL, NULL}};	

static int blacklisted(unsigned char * response_data){
  int i = 0;
  unsigned char * pnt;
  for(i=0; 1; i++){
    if(blacklist[i].vendor == NULL) return 0;
    pnt = &response_data[8];
    while(*pnt && *pnt == ' ') pnt++;
    if(memcmp(blacklist[i].vendor, pnt,
	       strlen(blacklist[i].vendor))) continue;
    pnt = &response_data[16];
    while(*pnt && *pnt == ' ') pnt++;
    if(memcmp(blacklist[i].model, pnt,
	       strlen(blacklist[i].model))) continue;
    return 1;
  };	
};

/*
 *	As the actual SCSI command runs in the background, we must set up a 
 *	flag that tells scan_scsis() when the result it has is valid.  
 *	scan_scsis can set the_result to -1, and watch for it to become the 
 *	actual return code for that call.  the scan_scsis_done function() is 
 *	our user specified completion function that is passed on to the  
 *	scsi_do_cmd() function.
 */

static volatile int in_scan = 0;
static int the_result;
static void scan_scsis_done (Scsi_Cmnd * SCpnt)
	{
	
#ifdef DEBUG
	printk ("scan_scsis_done(%d, %06x)\n", SCpnt->host, SCpnt->result);
#endif	
	SCpnt->request.dev = 0xfffe;
	}
/*
 *	Detecting SCSI devices :	
 *	We scan all present host adapter's busses,  from ID 0 to ID 6.  
 *	We use the INQUIRY command, determine device type, and pass the ID / 
 *	lun address of all sequential devices to the tape driver, all random 
 *	devices to the disk driver.
 */

static void scan_scsis (void)
{
  int dev, lun, type;
  unsigned char scsi_cmd [12];
  unsigned char scsi_result [256];
  struct Scsi_Host * shpnt;
  Scsi_Cmnd  SCmd;
  
  ++in_scan;
  lun = 0;
  
  SCmd.next = NULL;
  SCmd.prev = NULL;
  for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next)
      {
	shpnt->host_queue = &SCmd;  /* We need this so that
					 commands can time out */
	for (dev = 0; dev < 8; ++dev)
	  if (shpnt->this_id != dev)
/*
 * We need the for so our continue, etc. work fine.
 */

#ifdef NO_MULTI_LUN
	    for (lun = 0; lun < 1; ++lun)
#else
	    for (lun = 0; lun < 8; ++lun)
#endif
	      {
		scsi_devices[NR_SCSI_DEVICES].host = shpnt;
		scsi_devices[NR_SCSI_DEVICES].id = dev;
		scsi_devices[NR_SCSI_DEVICES].lun = lun;
		scsi_devices[NR_SCSI_DEVICES].index = NR_SCSI_DEVICES;
		scsi_devices[NR_SCSI_DEVICES].device_wait = NULL;
/*
 * Assume that the device will have handshaking problems, and then 
 * fix this field later if it turns out it doesn't.
 */
		scsi_devices[NR_SCSI_DEVICES].borken = 1;
		
		scsi_cmd[0] = TEST_UNIT_READY;
		scsi_cmd[1] = lun << 5;
		scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
		scsi_cmd[4] = 0;

		SCmd.host = shpnt;
		SCmd.target = dev;
		SCmd.lun = lun;

		SCmd.request.dev = 0xffff; /* Mark not busy */
		SCmd.use_sg  = 0;
		SCmd.old_use_sg  = 0;
		SCmd.transfersize = 0;
		SCmd.underflow = 0;
		SCmd.index = NR_SCSI_DEVICES;

		scsi_do_cmd (&SCmd,
			     (void *)  scsi_cmd, (void *) 
			     scsi_result, 256,  scan_scsis_done, 
			     SCSI_TIMEOUT + 400, 5);
		
		while (SCmd.request.dev != 0xfffe);
#if defined(DEBUG) || defined(DEBUG_INIT)
		printk("scsi: scan SCSIS id %d lun %d\n", dev, lun);
		printk("scsi: return code %08x\n", SCmd.result);
#endif


		if(SCmd.result) {
		  if ((driver_byte(SCmd.result)  & DRIVER_SENSE) &&
		      ((SCmd.sense_buffer[0] & 0x70) >> 4) == 7) {
		    if (SCmd.sense_buffer[2] &0xe0)
		      continue; /* No devices here... */
		    if(((SCmd.sense_buffer[2] & 0xf) != NOT_READY) &&
		       ((SCmd.sense_buffer[2] & 0xf) != UNIT_ATTENTION))
		      continue;
		  }
		  else
		    break;
		};

#if defined (DEBUG) || defined(DEBUG_INIT)
		printk("scsi: performing INQUIRY\n");
#endif

		/*
		 * Build an INQUIRY command block.  
		 */
		
		scsi_cmd[0] = INQUIRY;
		scsi_cmd[1] = (lun << 5) & 0xe0;
		scsi_cmd[2] = 0;
		scsi_cmd[3] = 0;
		scsi_cmd[4] = 255;
		scsi_cmd[5] = 0;
		
		SCmd.request.dev = 0xffff; /* Mark not busy */
		
		scsi_do_cmd (&SCmd,
			     (void *)  scsi_cmd, (void *) 
			     scsi_result, 256,  scan_scsis_done, 
			     SCSI_TIMEOUT, 3);
		
		while (SCmd.request.dev != 0xfffe);
		
		the_result = SCmd.result;
		
#if defined(DEBUG) || defined(DEBUG_INIT)
		if (!the_result)
			printk("scsi: INQUIRY successful\n");
		else
			printk("scsi: INQUIRY failed with code %08x\n");
#endif

		if(the_result) break; 

		/* skip other luns on this device */
		
		if (!the_result)
		  {
		    scsi_devices[NR_SCSI_DEVICES].
		      removable = (0x80 & 
				   scsi_result[1]) >> 7;
		    scsi_devices[NR_SCSI_DEVICES].lockable =
		      scsi_devices[NR_SCSI_DEVICES].removable;
		    scsi_devices[NR_SCSI_DEVICES].
		      changed = 0;
		    scsi_devices[NR_SCSI_DEVICES].
		      access_count = 0;
		    scsi_devices[NR_SCSI_DEVICES].
		      busy = 0;
/* 
 *	Currently, all sequential devices are assumed to be tapes,
 *	all random devices disk, with the appropriate read only 
 *	flags set for ROM / WORM treated as RO.
 */ 

		    switch (type = scsi_result[0])
		      {
		      case TYPE_TAPE :
		      case TYPE_DISK :
		      case TYPE_MOD :
			scsi_devices[NR_SCSI_DEVICES].writeable = 1;
			break;
		      case TYPE_WORM :
		      case TYPE_ROM :
			scsi_devices[NR_SCSI_DEVICES].writeable = 0;
			break;
			default :
#if 0
#ifdef DEBUG
			printk("scsi: unknown type %d\n", type);
			print_inquiry(scsi_result);
#endif
#endif
			  type = -1;
		      }

		    scsi_devices[NR_SCSI_DEVICES].random = 
		      (type == TYPE_TAPE) ? 0 : 1;
		    scsi_devices[NR_SCSI_DEVICES].type = type;

		    if (type != -1)
		      {
			print_inquiry(scsi_result);
			switch(type){
			case TYPE_TAPE:
			  printk("Detected scsi tape st%d at scsi%d, id %d, lun %d\n", MAX_ST,
				 shpnt->host_no , dev, lun); 
			  if(NR_ST != -1) ++MAX_ST;
			  break;
			case TYPE_ROM:
			  printk("Detected scsi CD-ROM sr%d at scsi%d, id %d, lun %d\n", MAX_SR,
				 shpnt->host_no , dev, lun); 
			  if(NR_SR != -1) ++MAX_SR;
			  break;
			case TYPE_DISK:
			case TYPE_MOD:
			  printk("Detected scsi disk sd%c at scsi%d, id %d, lun %d\n", 'a'+MAX_SD,
				 shpnt->host_no , dev, lun); 
			  if(NR_SD != -1) ++MAX_SD;
			  break;
			default:
			  break;
			};

			if(NR_SG != -1) ++MAX_SG;

			scsi_devices[NR_SCSI_DEVICES].scsi_level =
			  scsi_result[2] & 0x07;
			if (scsi_devices[NR_SCSI_DEVICES].scsi_level >= 2 ||
			    (scsi_devices[NR_SCSI_DEVICES].scsi_level == 1 &&
			     (scsi_result[3] & 0x0f) == 1))
			  scsi_devices[NR_SCSI_DEVICES].scsi_level++;
/* 
 * Set the tagged_queue flag for SCSI-II devices that purport to support
 * tagged queuing in the INQUIRY data.
 */

			scsi_devices[NR_SCSI_DEVICES].tagged_queue = 0;

			if ((scsi_devices[NR_SCSI_DEVICES].scsi_level >= SCSI_2) &&
			    (scsi_result[7] & 2)) {
			    scsi_devices[NR_SCSI_DEVICES].tagged_supported = 1;
			    scsi_devices[NR_SCSI_DEVICES].current_tag = 0;
			}

/*
 * Accomodate drivers that want to sleep when they should be in a polling
 * loop.
 */

			scsi_devices[NR_SCSI_DEVICES].disconnect = 0;

/*
 * Some revisions of the Texel CD ROM drives have handshaking
 * problems when used with the Seagate controllers.  Before we
 * know what type of device we're talking to, we assume it's 
 * borken and then change it here if it turns out that it isn't
 * a TEXEL drive.
 */

			if(strncmp("TEXEL", (char *) &scsi_result[8], 5) != 0 ||
			  strncmp("CD-ROM", (char *) &scsi_result[16], 6) != 0 
/* 
 * XXX 1.06 has problems, some one should figure out the others too so
 * ALL TEXEL drives don't suffer in performance, especially when I finish
 * integrating my seagate patches which do multiple I_T_L nexuses.
 */

#ifdef notyet
			   || (strncmp("1.06", (char *) &scsi_result[[, 4) != 0)
#endif
			   )
			   scsi_devices[NR_SCSI_DEVICES].borken = 0;


			/* These devices need this "key" to unlock the device

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
91小视频在线| 亚洲精品国产第一综合99久久| 国产精品人成在线观看免费| 视频一区欧美精品| 99热国产精品| 国产女人18毛片水真多成人如厕| 日韩激情视频网站| 欧美亚洲一区二区三区四区| 国产精品美女久久久久aⅴ国产馆 国产精品美女久久久久av爽李琼 国产精品美女久久久久高潮 | 美女mm1313爽爽久久久蜜臀| 色天天综合久久久久综合片| 国产日产欧美精品一区二区三区| 蜜臀av一区二区在线免费观看| 色999日韩国产欧美一区二区| 国产精品色呦呦| 国产一区 二区 三区一级| 欧美一区二区三区日韩视频| 亚洲成a人v欧美综合天堂下载| 99精品偷自拍| 国产精品日产欧美久久久久| 国产福利一区二区| 久久久三级国产网站| 精品亚洲porn| 26uuu国产一区二区三区| 美脚の诱脚舐め脚责91| 欧美一级理论片| 日韩在线a电影| 91精品婷婷国产综合久久竹菊| 亚洲6080在线| 日韩亚洲欧美一区| 久国产精品韩国三级视频| 欧美刺激午夜性久久久久久久| 欧美aaaaaa午夜精品| 精品久久一区二区| 国产精品主播直播| 中国av一区二区三区| 成人精品在线视频观看| 国产精品美女久久久久久| 99精品欧美一区二区三区综合在线| 亚洲国产精品成人综合| 91色视频在线| 午夜精品在线看| 欧美刺激脚交jootjob| 韩国av一区二区三区| 国产欧美日本一区二区三区| 91一区一区三区| 午夜精彩视频在线观看不卡| 日韩欧美一卡二卡| 成人一区二区视频| 亚洲影院在线观看| 欧美哺乳videos| 不卡的电影网站| 一区二区三区在线观看动漫| 91精品婷婷国产综合久久性色| 狠狠久久亚洲欧美| 日韩一区欧美一区| 3d动漫精品啪啪| 国产精品资源在线看| 亚洲欧美一区二区三区久本道91 | 精品国内二区三区| 波多野结衣中文字幕一区| 亚洲综合久久久| 欧美精品一区二区三区很污很色的| 成人高清免费观看| 日韩成人精品视频| 国产精品国产a级| 欧美高清一级片在线| 国产成人99久久亚洲综合精品| 亚洲最新视频在线播放| 精品精品欲导航| 色偷偷久久人人79超碰人人澡| 麻豆一区二区三| 亚洲免费av网站| 久久精品亚洲国产奇米99| 欧美日韩一区二区电影| 国产成人综合亚洲网站| 五月天婷婷综合| 国产精品免费丝袜| 日韩一区二区三区精品视频| 色综合久久99| 国产宾馆实践打屁股91| 视频在线观看一区| 日韩理论电影院| 欧美国产激情一区二区三区蜜月 | 亚洲日本va在线观看| 欧美精品一区二区三区蜜臀| 欧美日韩国产美女| 91亚洲永久精品| 成人午夜视频在线观看| 黑人精品欧美一区二区蜜桃| 蜜臀av一区二区| 亚洲地区一二三色| 伊人性伊人情综合网| 久久精品免费在线观看| 日韩精品资源二区在线| 91麻豆精品国产无毒不卡在线观看 | 免费成人深夜小野草| 亚洲线精品一区二区三区| 一区在线观看免费| 中文字幕欧美国产| 国产三级一区二区| 久久午夜羞羞影院免费观看| 3d成人h动漫网站入口| 欧美色综合网站| 在线免费视频一区二区| 91免费看视频| 91网站最新网址| 色综合天天性综合| 91麻豆免费视频| 99riav一区二区三区| 成人av一区二区三区| 岛国精品在线观看| 成人一级片在线观看| 成人污污视频在线观看| 成人免费av网站| 色综合中文字幕| 91九色最新地址| 欧美日韩一级片在线观看| 欧美色图免费看| 51精品久久久久久久蜜臀| 日韩视频一区二区三区在线播放 | 51精品久久久久久久蜜臀| 在线综合亚洲欧美在线视频| 日韩欧美综合一区| 精品国产一二三区| 国产精品日韩精品欧美在线 | 国产精品久久久久久久久搜平片 | 国产片一区二区三区| 国产精品久久免费看| 亚洲日本va午夜在线电影| 亚洲国产日韩a在线播放| 无码av中文一区二区三区桃花岛| 麻豆久久一区二区| 国产99久久久精品| 91免费看片在线观看| 欧美久久久一区| 久久综合九色综合久久久精品综合 | 久久久激情视频| 亚洲精品国产一区二区精华液| 亚洲综合视频网| 免费观看日韩av| av一二三不卡影片| 91精品国产综合久久香蕉麻豆 | 国产xxx精品视频大全| 91女厕偷拍女厕偷拍高清| 91麻豆精品国产91久久久更新时间| 久久久久99精品国产片| 亚洲精品一二三区| 久久99国产乱子伦精品免费| 成人久久视频在线观看| 欧美一二三区在线观看| 亚洲色图制服诱惑 | 免费观看一级特黄欧美大片| 国产成人免费在线观看| 欧美日本韩国一区二区三区视频 | 午夜精品在线视频一区| 福利91精品一区二区三区| 欧美色综合网站| 国产欧美日韩精品a在线观看| 亚洲bt欧美bt精品777| 成人一区二区三区视频在线观看 | 亚洲欧洲国产专区| 美女一区二区视频| 欧美天天综合网| 国产女同互慰高潮91漫画| 蜜臀av一区二区三区| 欧美色图免费看| 国产精品久久久久久亚洲毛片| 久久精品国产亚洲aⅴ| 欧美自拍偷拍一区| 国产精品你懂的在线| 久久99久久99小草精品免视看| 欧美在线观看禁18| 亚洲欧美日韩一区| 成人免费视频网站在线观看| 日韩美女一区二区三区四区| 香蕉久久夜色精品国产使用方法| 成人精品一区二区三区中文字幕| 2017欧美狠狠色| 麻豆一区二区三区| 日韩一区二区免费在线电影| 五月激情综合婷婷| 欧美日本一道本在线视频| 亚洲专区一二三| 99久久精品免费| 国产精品麻豆视频| bt7086福利一区国产| 国产精品免费丝袜| 成人h动漫精品| 一区在线中文字幕| 99久久久久久| 亚洲日本电影在线| 色狠狠色狠狠综合| 亚洲精品久久7777| 欧美视频第二页| 日韩黄色免费网站| 精品日产卡一卡二卡麻豆| 极品瑜伽女神91| 国产婷婷色一区二区三区四区| 国产美女av一区二区三区|