⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sr.c

📁 linux0.99源代码用于研究linux操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
    };        if (!SCpnt)      return; /* Could not find anything to do */      wake_up(&wait_for_request);/* Queue command */  requeue_sr_request(SCpnt);  };  /* While */}    void requeue_sr_request (Scsi_Cmnd * SCpnt){	unsigned int dev, block, realcount;	unsigned char cmd[10], *buffer, tries;	int this_count, start, end_rec;	tries = 2;      repeat:	if(SCpnt->request.dev <= 0)	  return do_sr_request();	dev =  MINOR(SCpnt->request.dev);	block = SCpnt->request.sector;		buffer = NULL;	this_count = 0;	if (dev >= NR_SR)		{		/* printk("CD-ROM request error: invalid device.\n");			*/		end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);		tries = 2;		goto repeat;		}	if (!scsi_CDs[dev].use)		{		/* printk("CD-ROM request error: device marked not in use.\n");		*/		end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);		tries = 2;		goto repeat;		}	if (scsi_CDs[dev].device->changed)	        {/*  * quietly refuse to do anything to a changed disc until the changed bit has been reset */		/* printk("CD-ROM has been changed.  Prohibiting further I/O.\n");	*/		end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);		tries = 2;		goto repeat;		}		switch (SCpnt->request.cmd)		{		case WRITE: 					end_scsi_request(SCpnt, 0, SCpnt->request.nr_sectors);			goto repeat;			break;		case READ : 		        cmd[0] = READ_6;			break;		default : 			printk ("Unknown sr command %d\r\n", SCpnt->request.cmd);			panic("");		}		cmd[1] = (SCpnt->lun << 5) & 0xe0;/*           Now do the grungy work of figuring out which sectors we need, and	   where in memory we are going to put them.	   The variables we need are:	   this_count= number of 512 byte sectors being read 	   block     = starting cdrom sector to read.	   realcount = # of cdrom sectors to read	   The major difference between a scsi disk and a scsi cdromis that we will always use scatter-gather if we can, because we canwork around the fact that the buffer cache has a block size of 1024,and we have 2048 byte sectors.  This code should work for buffers thatare any multiple of 512 bytes long.  */	SCpnt->use_sg = 0;	if (scsi_hosts[SCpnt->host].sg_tablesize > 0 &&	    (!need_isa_buffer ||	    dma_free_sectors >= 10)) {	  struct buffer_head * bh;	  struct scatterlist * sgpnt;	  int count, this_count_max;	  bh = SCpnt->request.bh;	  this_count = 0;	  count = 0;	  this_count_max = (scsi_CDs[dev].ten ? 0xffff : 0xff) << 4;	  /* Calculate how many links we can use.  First see if we need	   a padding record at the start */	  this_count = SCpnt->request.sector % 4;	  if(this_count) count++;	  while(bh && count < scsi_hosts[SCpnt->host].sg_tablesize) {	    if ((this_count + (bh->b_size >> 9)) > this_count_max) break;	    this_count += (bh->b_size >> 9);	    count++;	    bh = bh->b_reqnext;	  };	  /* Fix up in case of an odd record at the end */	  end_rec = 0;	  if(this_count % 4) {	    if (count < scsi_hosts[SCpnt->host].sg_tablesize) {	      count++;	      end_rec = (4 - (this_count % 4)) << 9;	      this_count += 4 - (this_count % 4);	    } else {	      count--;	      this_count -= (this_count % 4);	    };	  };	  SCpnt->use_sg = count;  /* Number of chains */	  count = 512;/* scsi_malloc can only allocate in chunks of 512 bytes*/	  while( count < (SCpnt->use_sg * sizeof(struct scatterlist))) 	    count = count << 1;	  SCpnt->sglist_len = count;	  sgpnt = (struct scatterlist * ) scsi_malloc(count);	  if (!sgpnt) {	    printk("Warning - running *really* short on DMA buffers\n");	    SCpnt->use_sg = 0;  /* No memory left - bail out */	  } else {	    buffer = (char *) sgpnt;	    count = 0;	    bh = SCpnt->request.bh;	    if(SCpnt->request.sector % 4) {	      sgpnt[count].length = (SCpnt->request.sector % 4) << 9;	      sgpnt[count].address = scsi_malloc(sgpnt[count].length);	      if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");	      sgpnt[count].alt_address = sgpnt[count].address; /* Flag to delete								  if needed */	      count++;	    };	    for(bh = SCpnt->request.bh; count < SCpnt->use_sg; 		count++, bh = bh->b_reqnext) {	      if (bh) { /* Need a placeholder at the end of the record? */		sgpnt[count].address = bh->b_data;		sgpnt[count].length = bh->b_size;		sgpnt[count].alt_address = NULL;	      } else {		sgpnt[count].address = scsi_malloc(end_rec);		if(!sgpnt[count].address) panic("SCSI DMA pool exhausted.");		sgpnt[count].length = end_rec;		sgpnt[count].alt_address = sgpnt[count].address;		if (count+1 != SCpnt->use_sg) panic("Bad sr request list");		break;	      };	      if (((int) sgpnt[count].address) + sgpnt[count].length > 		  ISA_DMA_THRESHOLD & (scsi_hosts[SCpnt->host].unchecked_isa_dma)) {		sgpnt[count].alt_address = sgpnt[count].address;		/* We try and avoid exhausting the DMA pool, since it is easier		   to control usage here.  In other places we might have a more		   pressing need, and we would be screwed if we ran out */		if(dma_free_sectors < (sgpnt[count].length >> 9) + 5) {		  sgpnt[count].address = NULL;		} else {		  sgpnt[count].address = scsi_malloc(sgpnt[count].length);		};/* If we start running low on DMA buffers, we abort the scatter-gather   operation, and free all of the memory we have allocated.  We want to   ensure that all scsi operations are able to do at least a non-scatter/gather   operation */		if(sgpnt[count].address == NULL){ /* Out of dma memory */		  printk("Warning: Running low on SCSI DMA buffers");		  /* Try switching back to a non scatter-gather operation. */		  while(--count){		    if(sgpnt[count].alt_address) 		      scsi_free(sgpnt[count].address, sgpnt[count].length);		  };		  SCpnt->use_sg = 0;		  scsi_free(buffer, SCpnt->sglist_len);		  break;		}; /* if address == NULL */	      };  /* if need DMA fixup */	    };  /* for loop to fill list */#ifdef DEBUG	    printk("SG: %d %d %d %d %d *** ",SCpnt->use_sg, SCpnt->request.sector,		   this_count, 		   SCpnt->request.current_nr_sectors,		   SCpnt->request.nr_sectors);	    for(count=0; count<SCpnt->use_sg; count++)	      printk("SGlist: %d %x %x %x\n", count,		     sgpnt[count].address, 		     sgpnt[count].alt_address, 		     sgpnt[count].length);#endif	  };  /* Able to allocate scatter-gather list */	};		if (SCpnt->use_sg == 0){	  /* We cannot use scatter-gather.  Do this the old fashion way */	  if (!SCpnt->request.bh)  		    this_count = SCpnt->request.nr_sectors;	  else	    this_count = (SCpnt->request.bh->b_size >> 9);	  	  start = block % 4;	  if (start)	    {				  	      this_count = ((this_count > 4 - start) ? 			    (4 - start) : (this_count));	      buffer = scsi_malloc(2048);	    } 	  else if (this_count < 4)	    {	      buffer = scsi_malloc(2048);	    }	  else	    {	      this_count -= this_count % 4;	      buffer = SCpnt->request.buffer;	      if (((int) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD & 		  (scsi_hosts[SCpnt->host].unchecked_isa_dma))		buffer = scsi_malloc(this_count << 9);	    }	};	block = block >> 2; /* These are the sectors that the cdrom uses */	realcount = (this_count + 3) / 4;	if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten) 		{		if (realcount > 0xffff)		        {			realcount = 0xffff;			this_count = realcount * 4;			}		cmd[0] += READ_10 - READ_6 ;		cmd[2] = (unsigned char) (block >> 24) & 0xff;		cmd[3] = (unsigned char) (block >> 16) & 0xff;		cmd[4] = (unsigned char) (block >> 8) & 0xff;		cmd[5] = (unsigned char) block & 0xff;		cmd[6] = cmd[9] = 0;		cmd[7] = (unsigned char) (realcount >> 8) & 0xff;		cmd[8] = (unsigned char) realcount & 0xff;		}	else		{		if (realcount > 0xff)		        {			realcount = 0xff;			this_count = realcount * 4;		        }			cmd[1] |= (unsigned char) ((block >> 16) & 0x1f);		cmd[2] = (unsigned char) ((block >> 8) & 0xff);		cmd[3] = (unsigned char) block & 0xff;		cmd[4] = (unsigned char) realcount;		cmd[5] = 0;		}   #ifdef DEBUG	printk("ReadCD: %d %d %d\n",block, realcount, buffer);#endif	SCpnt->this_count = this_count;	scsi_do_cmd (SCpnt, (void *) cmd, buffer, realcount << 11, 		     rw_intr, SR_TIMEOUT, MAX_RETRIES);}unsigned long sr_init1(unsigned long mem_start, unsigned long mem_end){  scsi_CDs = (Scsi_CD *) mem_start;  mem_start += MAX_SR * sizeof(Scsi_CD);  return mem_start;};void sr_attach(Scsi_Device * SDp){  scsi_CDs[NR_SR++].device = SDp;  if(NR_SR > MAX_SR) panic ("scsi_devices corrupt (sr)");};unsigned long sr_init(unsigned long memory_start, unsigned long memory_end){	int i;	if(MAX_SR == 0) return memory_start;	sr_sizes = (int *) memory_start;	memory_start += MAX_SR * sizeof(int);	memset(sr_sizes, 0, MAX_SR * sizeof(int));	for (i = 0; i < NR_SR; ++i)		{		scsi_CDs[i].capacity = 0x1fffff;		scsi_CDs[i].sector_size = 2048;		scsi_CDs[i].use = 1;		scsi_CDs[i].ten = 1;		scsi_CDs[i].remap = 1;		sr_sizes[i] = scsi_CDs[i].capacity;		}	blk_dev[MAJOR_NR].request_fn = DEVICE_REQUEST;	blk_size[MAJOR_NR] = sr_sizes;		/* If our host adapter is capable of scatter-gather, then we increase	   the read-ahead to 8 blocks (16 sectors).  If not, we use	   a two block (4 sector) read ahead. */	if(scsi_hosts[scsi_CDs[0].device->host_no].sg_tablesize)	  read_ahead[MAJOR_NR] = 16;  /* 16 sector read-ahead */	else	  read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */	blkdev_fops[MAJOR_NR] = &sr_fops; 	return memory_start;}	

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -