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

📄 sr.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
📖 第 1 页 / 共 2 页
字号:
		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 : 			panic ("Unknown sr command %d\n", SCpnt->request.cmd);		}		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 (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 < 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 < 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 = (unsigned char *) sgpnt;	    count = 0;	    bh = SCpnt->request.bh;	    if(SCpnt->request.sector % 4) {	      sgpnt[count].length = (SCpnt->request.sector % 4) << 9;	      sgpnt[count].address = (char *) 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 = (char *) 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 & (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 = (char *) 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 >= 0){		    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 = (unsigned char *) scsi_malloc(2048);	    } 	  else if (this_count < 4)	    {	      buffer = (unsigned char *) scsi_malloc(2048);	    }	  else	    {	      this_count -= this_count % 4;	      buffer = (unsigned char *) SCpnt->request.buffer;	      if (((int) buffer) + (this_count << 9) > ISA_DMA_THRESHOLD & 		  (SCpnt->host->unchecked_isa_dma))		buffer = (unsigned char *) scsi_malloc(this_count << 9);	    }	};	if (scsi_CDs[dev].sector_size == 2048)	  block = block >> 2; /* These are the sectors that the cdrom uses */	else	  block = block & 0xfffffffc;	realcount = (this_count + 3) / 4;	if (scsi_CDs[dev].sector_size == 512) realcount = realcount << 2;	if (((realcount > 0xff) || (block > 0x1fffff)) && scsi_CDs[dev].ten) 		{		if (realcount > 0xffff)		        {			realcount = 0xffff;			this_count = realcount * (scsi_CDs[dev].sector_size >> 9);			}		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 * (scsi_CDs[dev].sector_size >> 9);		        }			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{ 	int i;	printk("ReadCD: %d %d %d %d\n",block, realcount, buffer, this_count);	printk("Use sg: %d\n", SCpnt->use_sg);	printk("Dumping command: ");	for(i=0; i<12; i++) printk("%2.2x ", cmd[i]);	printk("\n");};#endif	SCpnt->this_count = this_count;	scsi_do_cmd (SCpnt, (void *) cmd, buffer, 		     realcount * scsi_CDs[dev].sector_size, 		     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)");};static void sr_init_done (Scsi_Cmnd * SCpnt){  struct request * req;  struct task_struct * p;    req = &SCpnt->request;  req->dev = 0xfffe; /* Busy, but indicate request done */    if ((p = req->waiting) != NULL) {    req->waiting = NULL;    p->state = TASK_RUNNING;    if (p->counter > current->counter)      need_resched = 1;  }}static void get_sectorsize(int i){  unsigned char cmd[10];  unsigned char buffer[513];  int the_result, retries;  Scsi_Cmnd * SCpnt;    SCpnt = allocate_device(NULL, scsi_CDs[i].device->index, 1);  retries = 3;  do {    cmd[0] = READ_CAPACITY;    cmd[1] = (scsi_CDs[i].device->lun << 5) & 0xe0;    memset ((void *) &cmd[2], 0, 8);    SCpnt->request.dev = 0xffff;  /* Mark as really busy */        memset(buffer, 0, 8);    scsi_do_cmd (SCpnt,		 (void *) cmd, (void *) buffer,		 512, sr_init_done,  SR_TIMEOUT,		 MAX_RETRIES);        if (current == task[0])      while(SCpnt->request.dev != 0xfffe);    else      if (SCpnt->request.dev != 0xfffe){	SCpnt->request.waiting = current;	current->state = TASK_UNINTERRUPTIBLE;	while (SCpnt->request.dev != 0xfffe) schedule();      };        the_result = SCpnt->result;    retries--;      } while(the_result && retries);    SCpnt->request.dev = -1;  /* Mark as not busy */    wake_up(&scsi_devices[SCpnt->index].device_wait);   if (the_result) {    scsi_CDs[i].capacity = 0x1fffff;    scsi_CDs[i].sector_size = 2048;  /* A guess, just in case */    scsi_CDs[i].needs_sector_size = 1;  } else {    scsi_CDs[i].capacity = (buffer[0] << 24) |      (buffer[1] << 16) | (buffer[2] << 8) | buffer[3];    scsi_CDs[i].sector_size = (buffer[4] << 24) |      (buffer[5] << 16) | (buffer[6] << 8) | buffer[7];    if(scsi_CDs[i].sector_size == 0) scsi_CDs[i].sector_size = 2048;    if(scsi_CDs[i].sector_size != 2048 &&        scsi_CDs[i].sector_size != 512) {      printk ("scd%d : unsupported sector size %d.\n",	      i, scsi_CDs[i].sector_size);      scsi_CDs[i].capacity = 0;      scsi_CDs[i].needs_sector_size = 1;    };    if(scsi_CDs[i].sector_size == 2048)      scsi_CDs[i].capacity *= 4;    scsi_CDs[i].needs_sector_size = 0;  };}unsigned long sr_init(unsigned long memory_start, unsigned long memory_end){	int i;	if (register_blkdev(MAJOR_NR,"sr",&sr_fops)) {		printk("Unable to get major %d for SCSI-CD\n",MAJOR_NR);		return memory_start;	}	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));	sr_blocksizes = (int *) memory_start;	memory_start += MAX_SR * sizeof(int);	for(i=0;i<MAX_SR;i++) sr_blocksizes[i] = 2048;	blksize_size[MAJOR_NR] = sr_blocksizes;	for (i = 0; i < NR_SR; ++i)		{		  get_sectorsize(i);		  printk("Scd sectorsize = %d bytes\n", scsi_CDs[i].sector_size);		  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 16 blocks (32 sectors).  If not, we use	   a two block (4 sector) read ahead. */	if(scsi_CDs[0].device->host->sg_tablesize)	  read_ahead[MAJOR_NR] = 32;  /* 32 sector read-ahead.  Always removable. */	else	  read_ahead[MAJOR_NR] = 4;  /* 4 sector read-ahead */	return memory_start;}	

⌨️ 快捷键说明

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