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

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

?? scsi.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
?? 第 1 頁 / 共 4 頁
字號:
			   so we can use it */
			if(memcmp("INSITE", &scsi_result[8], 6) == 0 &&
			   (memcmp("Floptical   F*8I", &scsi_result[16], 16) == 0
			    || memcmp("I325VM", &scsi_result[16], 6) == 0)) {
			  printk("Unlocked floptical drive.\n");
			  scsi_devices[NR_SCSI_DEVICES].lockable = 0;
			  scsi_cmd[0] = MODE_SENSE;
			  scsi_cmd[1] = (lun << 5) & 0xe0;
			  scsi_cmd[2] = 0x2e;
			  scsi_cmd[3] = 0;
			  scsi_cmd[4] = 0x2a;
			  scsi_cmd[5] = 0;
		
			  SCmd.request.dev = 0xffff; /* Mark not busy */
			  
			  scsi_do_cmd (&SCmd,
				       (void *)  scsi_cmd, (void *) 
				       scsi_result, 0x2a,  scan_scsis_done, 
				       SCSI_TIMEOUT, 3);
		
			  while (SCmd.request.dev != 0xfffe);
			};

			++NR_SCSI_DEVICES;
			/* Some scsi devices cannot be polled for lun != 0
			   due to firmware bugs */
			if(blacklisted(scsi_result)) break;
			/* Old drives like the MAXTOR XT-3280 say vers=0 */
			if ((scsi_result[2] & 0x07) == 0)
			    break;
			/* Some scsi-1 peripherals do not handle lun != 0.
			   I am assuming that scsi-2 peripherals do better */
			if((scsi_result[2] & 0x07) == 1 && 
			   (scsi_result[3] & 0x0f) == 0) break;
			}
		  }       /* if result == DID_OK ends */
	      }       /* for lun ends */
	shpnt->host_queue = NULL;  /* No longer needed here */
      }      	/* if present */  
  
  printk("scsi : detected ");
  if(NR_SD != -1)
    printk("%d SCSI disk%s ", MAX_SD, (MAX_SD != 1) ? "s" : "");
	 
  if(NR_ST != -1)
    printk("%d tape%s ", MAX_ST, (MAX_ST != 1) ? "s" : "");

  if(NR_SR != -1)
    printk("%d CD-ROM drive%s ", MAX_SR, (MAX_SR != 1) ? "s" : "");

  printk("total.\n");
  in_scan = 0;
}       /* scan_scsis  ends */

/*
 *	Flag bits for the internal_timeout array 
 */

#define NORMAL_TIMEOUT 0
#define IN_ABORT 1
#define IN_RESET 2
/*
	This is our time out function, called when the timer expires for a 
	given host adapter.  It will attempt to abort the currently executing 
	command, that failing perform a kernel panic.
*/ 

static void scsi_times_out (Scsi_Cmnd * SCpnt)
	{
	
 	switch (SCpnt->internal_timeout & (IN_ABORT | IN_RESET))
		{
		case NORMAL_TIMEOUT:
			if (!in_scan)
			      printk("SCSI host %d timed out - aborting command\n",
				SCpnt->host->host_no);
			
			if (!scsi_abort	(SCpnt, DID_TIME_OUT))
				return;				
		case IN_ABORT:
			printk("SCSI host %d abort() timed out - reseting\n",
				SCpnt->host->host_no);
			if (!scsi_reset (SCpnt)) 
				return;
		case IN_RESET:
		case (IN_ABORT | IN_RESET):
			panic("Unable to reset scsi host %d\n",SCpnt->host->host_no);
		default:
			INTERNAL_ERROR;
		}
					
	}


/* This function takes a quick look at a request, and decides if it
can be queued now, or if there would be a stall while waiting for
something else to finish.  This routine assumes that interrupts are
turned off when entering the routine.  It is the responsibility
of the calling code to ensure that this is the case. */

Scsi_Cmnd * request_queueable (struct request * req, int index)
{
  Scsi_Cmnd * SCpnt = NULL;
  int tablesize;
  struct buffer_head * bh;

  if ((index < 0) ||  (index > NR_SCSI_DEVICES))
    panic ("Index number in allocate_device() is out of range.\n");
  
  if (req && req->dev <= 0)
    panic("Invalid device in allocate_device");
  
  SCpnt =  scsi_devices[index].host->host_queue;
    while(SCpnt){
      if(SCpnt->target == scsi_devices[index].id &&
	 SCpnt->lun == scsi_devices[index].lun)
	if(SCpnt->request.dev < 0) break;
      SCpnt = SCpnt->next;
    };

  if (!SCpnt) return NULL;

  if (scsi_devices[index].host->hostt->can_queue
      && scsi_devices[index].host->host_busy >= scsi_devices[index].host->hostt->can_queue) return NULL;

  if (req) {
    memcpy(&SCpnt->request, req, sizeof(struct request));
    tablesize = scsi_devices[index].host->sg_tablesize;
    bh = req->bh;
    if(!tablesize) bh = NULL;
    /* Take a quick look through the table to see how big it is.  We already
       have our copy of req, so we can mess with that if we want to.  */
    while(req->nr_sectors && bh){
	    tablesize--;
	    req->nr_sectors -= bh->b_size >> 9;
	    req->sector += bh->b_size >> 9;
	    if(!tablesize) break;
	    bh = bh->b_reqnext;
    };
    if(req->nr_sectors && bh && bh->b_reqnext){  /* Any leftovers? */
      SCpnt->request.bhtail = bh;
      req->bh = bh->b_reqnext; /* Divide request */
      bh->b_reqnext = NULL;
      bh = req->bh;

      /* Now reset things so that req looks OK */
      SCpnt->request.nr_sectors -= req->nr_sectors;
      req->current_nr_sectors = bh->b_size >> 9;
      req->buffer = bh->b_data;
      SCpnt->request.waiting = NULL; /* Wait until whole thing done */
    } else
      req->dev = -1;
      
  } else {
    SCpnt->request.dev = 0xffff; /* Busy, but no request */
    SCpnt->request.waiting = NULL;  /* And no one is waiting for the device either */
  };

  SCpnt->use_sg = 0;  /* Reset the scatter-gather flag */
  SCpnt->old_use_sg  = 0;
  SCpnt->transfersize = 0;
  SCpnt->underflow = 0;
  return SCpnt;
}

/* This function returns a structure pointer that will be valid for
the device.  The wait parameter tells us whether we should wait for
the unit to become free or not.  We are also able to tell this routine
not to return a descriptor if the host is unable to accept any more
commands for the time being.  We need to keep in mind that there is no
guarantee that the host remain not busy.  Keep in mind the
request_queueable function also knows the internal allocation scheme
of the packets for each device */

Scsi_Cmnd * allocate_device (struct request ** reqp, int index, int wait)
{
  int dev = -1;
  struct request * req = NULL;
  int tablesize;
  struct buffer_head * bh;
  struct Scsi_Host * host;
  Scsi_Cmnd * SCpnt = NULL;
  Scsi_Cmnd * SCwait = NULL;

  if ((index < 0) ||  (index > NR_SCSI_DEVICES))
    panic ("Index number in allocate_device() is out of range.\n");
  
  if (reqp) req = *reqp;

    /* See if this request has already been queued by an interrupt routine */
  if (req && (dev = req->dev) <= 0) return NULL;
  
  host = scsi_devices[index].host;
  
  while (1==1){
    SCpnt = host->host_queue;
    while(SCpnt){
      if(SCpnt->target == scsi_devices[index].id &&
	 SCpnt->lun == scsi_devices[index].lun) {
	SCwait = SCpnt;
	if(SCpnt->request.dev < 0) break;
      };
      SCpnt = SCpnt->next;
    };
    cli();
    /* See if this request has already been queued by an interrupt routine */
    if (req && ((req->dev < 0) || (req->dev != dev))) {
      sti();
      return NULL;
    };
    if (!SCpnt || SCpnt->request.dev >= 0)  /* Might have changed */
      {
	sti();
	if(!wait) return NULL;
	if (!SCwait) {
	  printk("Attempt to allocate device index %d, target %d, lun %d\n",
		 index, scsi_devices[index].id ,scsi_devices[index].lun);
	  panic("No device found in allocate_device\n");
	};
	SCSI_SLEEP(&scsi_devices[SCwait->index].device_wait, 
		   (SCwait->request.dev > 0));
      } else {
	if (req) {
	  memcpy(&SCpnt->request, req, sizeof(struct request));
	  tablesize = scsi_devices[index].host->sg_tablesize;
	  bh = req->bh;
	  if(!tablesize) bh = NULL;
	  /* Take a quick look through the table to see how big it is.  We already
	     have our copy of req, so we can mess with that if we want to.  */
	  while(req->nr_sectors && bh){
	    tablesize--;
	    req->nr_sectors -= bh->b_size >> 9;
	    req->sector += bh->b_size >> 9;
	    if(!tablesize) break;
	    bh = bh->b_reqnext;
	  };
	  if(req->nr_sectors && bh && bh->b_reqnext){  /* Any leftovers? */
	    SCpnt->request.bhtail = bh;
	    req->bh = bh->b_reqnext; /* Divide request */
	    bh->b_reqnext = NULL;
	    bh = req->bh;
	    /* Now reset things so that req looks OK */
	    SCpnt->request.nr_sectors -= req->nr_sectors;
	    req->current_nr_sectors = bh->b_size >> 9;
	    req->buffer = bh->b_data;
	    SCpnt->request.waiting = NULL; /* Wait until whole thing done */
	  }
	  else 
	    {
	      req->dev = -1;
	      *reqp = req->next;
	    };
	} else {
	  SCpnt->request.dev = 0xffff; /* Busy */
	  SCpnt->request.waiting = NULL;  /* And no one is waiting for this to complete */
	};
	sti();
	break;
      };
  };

  SCpnt->use_sg = 0;  /* Reset the scatter-gather flag */
  SCpnt->old_use_sg  = 0;
  SCpnt->transfersize = 0;      /* No default transfer size */
  SCpnt->underflow = 0;         /* Do not flag underflow conditions */
  return SCpnt;
}

/*
	This is inline because we have stack problemes if we recurse to deeply.
*/
			 
inline void internal_cmnd (Scsi_Cmnd * SCpnt)
	{
	int temp;
	struct Scsi_Host * host;
#ifdef DEBUG_DELAY	
	int clock;
#endif

	if ((unsigned long) &SCpnt < current->kernel_stack_page)
	  panic("Kernel stack overflow.");

	host = SCpnt->host;

/*
	We will wait MIN_RESET_DELAY clock ticks after the last reset so 
	we can avoid the drive not being ready.
*/ 
temp = host->last_reset;
while (jiffies < temp);

update_timeout(SCpnt, SCpnt->timeout_per_command);

/*
	We will use a queued command if possible, otherwise we will emulate the
	queing and calling of completion function ourselves. 
*/
#ifdef DEBUG
	printk("internal_cmnd (host = %d, target = %d, command = %08x, buffer =  %08x, \n"
		"bufflen = %d, done = %08x)\n", SCpnt->host->host_no, SCpnt->target, SCpnt->cmnd, SCpnt->buffer, SCpnt->bufflen, SCpnt->done);
#endif

        if (host->hostt->can_queue)
		{
#ifdef DEBUG
	printk("queuecommand : routine at %08x\n", 
		host->hostt->queuecommand);
#endif
                host->hostt->queuecommand (SCpnt, scsi_done);
		}
	else
		{

#ifdef DEBUG
	printk("command() :  routine at %08x\n", host->hostt->command);
#endif
		temp=host->hostt->command (SCpnt);
	        SCpnt->result = temp;
#ifdef DEBUG_DELAY
	clock = jiffies + 400;
	while (jiffies < clock);
	printk("done(host = %d, result = %04x) : routine at %08x\n", host->host_no, temp, done);
#endif
	        scsi_done(SCpnt);
		}	
#ifdef DEBUG
	printk("leaving internal_cmnd()\n");
#endif
	}	

static void scsi_request_sense (Scsi_Cmnd * SCpnt)
	{
	cli();
	SCpnt->flags |= WAS_SENSE | ASKED_FOR_SENSE;
	update_timeout(SCpnt, SENSE_TIMEOUT);
	sti();
	

	memcpy ((void *) SCpnt->cmnd , (void *) generic_sense,
		sizeof(generic_sense));

	SCpnt->cmnd[1] = SCpnt->lun << 5;	
	SCpnt->cmnd[4] = sizeof(SCpnt->sense_buffer);

	SCpnt->request_buffer = &SCpnt->sense_buffer;
	SCpnt->request_bufflen = sizeof(SCpnt->sense_buffer);
	SCpnt->use_sg = 0;
	internal_cmnd (SCpnt);
	SCpnt->use_sg = SCpnt->old_use_sg;
	}



/*
	scsi_do_cmd sends all the commands out to the low-level driver.  It 
	handles the specifics required for each low level driver - ie queued 
	or non queud.  It also prevents conflicts when different high level 
	drivers go for the same host at the same time.
*/

void scsi_do_cmd (Scsi_Cmnd * SCpnt, const void *cmnd , 
		  void *buffer, unsigned bufflen, void (*done)(Scsi_Cmnd *),
		  int timeout, int retries 
		   )
        {
	struct Scsi_Host * host = SCpnt->host;

#ifdef DEBUG
	{
	int i;	
	int target = SCpnt->target;
	printk ("scsi_do_cmd (host = %d, target = %d, buffer =%08x, "
		"bufflen = %d, done = %08x, timeout = %d, retries = %d)\n"
		"command : " , host->host_no, target, buffer, bufflen, done, timeout, retries);
	for (i = 0; i < 10; ++i)
		printk ("%02x  ", ((unsigned char *) cmnd)[i]); 
	printk("\n");
      };
#endif
	
	if (!host)
		{
		panic ("Invalid or not present host. %d\n", host->host_no);
		}

	
/*
	We must prevent reentrancy to the lowlevel host driver.  This prevents 
	it - we enter a loop until the host we want to talk to is not busy.   
	Race conditions are prevented, as interrupts are disabled inbetween the
	time we check for the host being not busy, and the time we mark it busy
	ourselves.
*/

	while (1==1){
	  cli();
	  if (host->hostt->can_queue
	      && host->host_busy >= host->hostt->can_queue)
	    {
	      sti();
	      SCSI_SLEEP(&host->host_wait, 
			 (host->host_busy >= host->hostt->can_queue));
	    } else {
	      host->host_busy++;
	      sti();
	      break;
	    };
      };
/*
	Our own function scsi_done (which marks the host as not busy, disables 
	the timeout counter, etc) will be called by us or by the 
	scsi_hosts[host].queuecommand() function needs to also call
	the completion function for the high level driver.

*/

	memcpy ((void *) SCpnt->data_cmnd , (void *) cmnd, 12);
#if 0
	SCpnt->host = host;
	SCpnt->target = target;
	SCpnt->lun = (SCpnt->data_cmnd[1] >> 5);
#endif
	SCpnt->bufflen = bufflen;
	SCpnt->buffer = buffer;
	SCpnt->flags=0;
	SCpnt->retries=0;
	SCpnt->allowed=retries;
	SCpnt->done = done;
	SCpnt->timeout_per_command = timeout;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲美女淫视频| 91视频国产观看| 成人av在线播放网站| 91网上在线视频| 久久久久久久久久久久电影| 亚洲资源中文字幕| 国产成人免费视| 555www色欧美视频| 亚洲精品免费视频| 国产成a人亚洲| 日韩视频免费观看高清在线视频| 日韩美女啊v在线免费观看| 韩国毛片一区二区三区| 欧美日韩在线亚洲一区蜜芽| 国产午夜精品理论片a级大结局| 亚洲成av人片在线| 91毛片在线观看| 中文字幕不卡的av| 国产剧情一区二区三区| 欧美一区二区三级| 天堂资源在线中文精品| av电影一区二区| 亚洲国产精品精华液ab| 狠狠色丁香久久婷婷综合_中| 538在线一区二区精品国产| 亚洲第一搞黄网站| 欧美视频自拍偷拍| 伊人夜夜躁av伊人久久| 99re热这里只有精品视频| 国产精品婷婷午夜在线观看| 国产福利精品导航| 久久久久国产成人精品亚洲午夜 | 69堂国产成人免费视频| 亚洲va韩国va欧美va精品| 欧美日韩国产小视频| 亚洲一区二区四区蜜桃| 国内精品视频666| 久久婷婷成人综合色| 免费av网站大全久久| 日韩美女在线视频| 国产一区二区三区黄视频 | 麻豆精品在线看| 欧美一区二区三区思思人 | 中文字幕欧美一| 99久久精品久久久久久清纯| 中文字幕综合网| 欧美曰成人黄网| 亚洲无人区一区| 欧美丰满少妇xxxbbb| 蜜桃久久久久久| 国产网站一区二区| 99精品国产91久久久久久| 亚洲女人****多毛耸耸8| 欧美日韩免费高清一区色橹橹| 亚洲二区在线观看| 精品久久久久久久久久久久久久久久久 | 中文字幕精品在线不卡| 色婷婷亚洲精品| 亚洲成人自拍一区| 欧美一区二区视频观看视频| 国产精品一级二级三级| 日韩一区在线看| 91精品国产一区二区三区香蕉| 国内精品久久久久影院色| 国产精品视频免费看| 在线精品视频一区二区| 久久99精品久久只有精品| 国产精品理论在线观看| 欧美丰满一区二区免费视频| 国产不卡一区视频| 亚洲一区二区三区四区在线观看 | 国产女同性恋一区二区| 91理论电影在线观看| 麻豆91在线播放免费| 亚洲桃色在线一区| 亚洲精品在线电影| 91久久线看在观草草青青 | 国产欧美一区二区精品性色| 91久久香蕉国产日韩欧美9色| 极品销魂美女一区二区三区| 亚洲少妇最新在线视频| 精品欧美一区二区久久| 在线看日本不卡| 成人午夜电影小说| 青青草国产成人av片免费| 亚洲日本丝袜连裤袜办公室| 精品国产成人在线影院| 欧美性三三影院| 99精品视频在线播放观看| 麻豆精品视频在线| 亚洲国产成人高清精品| 综合中文字幕亚洲| 欧美成人激情免费网| 欧美亚洲综合久久| 91丨porny丨中文| 国产成人一区二区精品非洲| 日本欧美一区二区三区| 亚洲图片一区二区| 一区二区三区四区视频精品免费| 久久久久久久一区| 精品日韩av一区二区| 欧美日韩三级一区二区| 欧美午夜影院一区| 一本一道波多野结衣一区二区| 国产盗摄精品一区二区三区在线| 蜜桃一区二区三区四区| 视频一区二区国产| 日韩**一区毛片| 日本午夜一本久久久综合| 午夜精品久久久久久久99水蜜桃 | 欧美日韩久久久| 在线视频中文字幕一区二区| 91亚洲精华国产精华精华液| 成人免费视频播放| 91亚洲精品久久久蜜桃| 97国产一区二区| 91欧美激情一区二区三区成人| av在线播放成人| 99精品视频在线播放观看| 99精品在线免费| 色噜噜狠狠色综合欧洲selulu| 91视频91自| 91高清视频在线| 欧美三区免费完整视频在线观看| 欧美三级日韩三级国产三级| 欧美电影在线免费观看| 91精品国产综合久久蜜臀| 欧美一区二区三区小说| 日韩欧美国产电影| 国产区在线观看成人精品| 国产精品天干天干在线综合| 一区二区三区四区中文字幕| 一区二区高清免费观看影视大全| 亚洲一区二区三区四区在线 | 日韩电影在线一区| 久久99精品久久久久久| 国产精品18久久久久久久网站| 成人免费福利片| 91久久精品一区二区二区| 欧美日韩在线观看一区二区| 日韩欧美123| 国产精品网站在线| 亚洲国产精品麻豆| 精品一区精品二区高清| 高清不卡在线观看| 欧美亚洲综合网| 精品999在线播放| 亚洲欧美乱综合| 狂野欧美性猛交blacked| 99久久综合国产精品| 欧美狂野另类xxxxoooo| 欧美精品一区二区高清在线观看| 国产精品麻豆99久久久久久| 亚洲尤物在线视频观看| 黄色日韩网站视频| 色综合久久久久| 精品久久久久久久久久久院品网| 成人免费在线视频| 捆绑紧缚一区二区三区视频| av不卡一区二区三区| 91精品国产综合久久久久久久| 久久九九久精品国产免费直播| 一区二区三区四区视频精品免费| 国内精品免费在线观看| 欧美网站大全在线观看| 国产精品免费免费| 日本aⅴ免费视频一区二区三区| www..com久久爱| 欧美www视频| 天堂一区二区在线| 91色porny在线视频| 精品国产自在久精品国产| 一区二区三区电影在线播| 国产999精品久久久久久绿帽| 3751色影院一区二区三区| 国产精品黄色在线观看| 国产精品77777| 在线播放国产精品二区一二区四区| 中文字幕av在线一区二区三区| 美国三级日本三级久久99| 欧美日韩国产另类不卡| 亚洲欧美另类在线| 成人av在线网| 久久久久久久久久久久电影| 美女网站色91| 日韩视频一区二区三区在线播放 | 国产精品99久久久久久宅男| 911精品国产一区二区在线| 亚洲国产综合在线| 91视频在线看| 亚洲视频香蕉人妖| 91美女在线视频| 亚洲视频一区二区免费在线观看 | 欧美喷潮久久久xxxxx| 亚洲综合视频网| 色婷婷av一区二区三区gif| 亚洲男人天堂av网| 91成人在线精品| 亚洲自拍另类综合| 欧美日韩激情一区二区|