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

📄 st.c

📁 linux0.99源代码用于研究linux操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
	scsi_tapes[dev].buffer->b_data[10] * 256 + scsi_tapes[dev].buffer->b_data[11];#ifdef DEBUG      printk("st%d: Density %x, tape length: %x, blocksize: %d\n", dev,	     scsi_tapes[dev].buffer->b_data[4], scsi_tapes[dev].buffer->b_data[5] *	     65536 + scsi_tapes[dev].buffer->b_data[6] * 256 +	     scsi_tapes[dev].buffer->b_data[7], scsi_tapes[dev].buffer->b_data[9] *	     65536 + scsi_tapes[dev].buffer->b_data[10] * 256 +	     scsi_tapes[dev].buffer->b_data[11]);#endif      if (scsi_tapes[dev].block_size > ST_BUFFER_SIZE) {	printk("st%d: Blocksize %d too large for buffer.\n", dev,	       scsi_tapes[dev].block_size);	scsi_tapes[dev].buffer->in_use = 0;	scsi_tapes[dev].in_use = 0;	return (-EIO);      }      if (scsi_tapes[dev].block_size == 0) {	printk("st%d: Fixing block size to 512 bytes.\n", dev);	if (st_int_ioctl(inode, filp, MTSETBLK, ST_BLOCK_SIZE)) {	  printk("st%d: Can't set fixed block size.\n", dev);	  scsi_tapes[dev].buffer->in_use = 0;	  scsi_tapes[dev].in_use = 0;	  return (-EIO);	}	scsi_tapes[dev].block_size = ST_BLOCK_SIZE;      }    }    else      scsi_tapes[dev].block_size = ST_BLOCK_SIZE;    scsi_tapes[dev].buffer->buffer_blocks =      ST_BUFFER_SIZE / scsi_tapes[dev].block_size;    scsi_tapes[dev].buffer->buffer_size =      scsi_tapes[dev].buffer->buffer_blocks * scsi_tapes[dev].block_size;    scsi_tapes[dev].buffer->buffer_bytes = scsi_tapes[dev].buffer->read_pointer = 0;#ifdef DEBUG    printk("st%d: Block size: %d, buffer size: %d (%d blocks).\n", dev,	   scsi_tapes[dev].block_size, scsi_tapes[dev].buffer->buffer_size,	   scsi_tapes[dev].buffer->buffer_blocks);#endif    if (scsi_tapes[dev].buffer->b_data[2] & 0x80) {      scsi_tapes[dev].write_prot = 1;#ifdef DEBUG      printk( "st%d: Write protected\n", dev);#endif    }    return 0;}/* Close the device*/static void scsi_tape_close(struct inode * inode, struct file * filp){    int dev;    int result;    int rewind;    static unsigned char cmd[10];    Scsi_Cmnd * SCpnt;       dev = inode->i_rdev;    rewind = (dev & 0x80) == 0;    dev = dev & 127;    if ( scsi_tapes[dev].rw == 2) {      result = flush_write_buffer(dev);#ifdef DEBUG      printk("st%d: File length %d bytes.\n", dev, filp->f_pos);#endif      if (!result) {	SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);	SCpnt->sense_buffer[0] = 0;	memset(cmd, 0, 10);	cmd[0] = WRITE_FILEMARKS;	cmd[4] = 1;	SCpnt->request.dev = dev;	scsi_do_cmd( SCpnt,		    (void *) cmd, (void *) scsi_tapes[dev].buffer->b_data,		    ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_RETRIES);	if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );	if (SCpnt->result) {	  printk("st%d: Error on write filemark:\n", dev);#ifdef DEBUG	  st_chk_result(dev, SCpnt->result, SCpnt->sense_buffer);#endif	}	SCpnt->request.dev = -1;  /* Mark as not busy */      }#ifdef DEBUG      printk("st%d: Buffer flushed, EOF written\n", dev);#endif    }    else if (!rewind && scsi_tapes[dev].eof && !scsi_tapes[dev].eof_hit)      st_int_ioctl(inode, filp, MTBSF, 1);               /* Back over the EOF hit inadvertently */    if (rewind)      st_int_ioctl(inode, filp, MTREW, 1);    scsi_tapes[dev].buffer->in_use = 0;    scsi_tapes[dev].in_use = 0;    return;}/* Write command */int st_write(struct inode * inode, struct file * filp, char * buf, int count){    int dev;    int total, do_count, blks, retval;    static unsigned char cmd[10];    char *b_point;    Scsi_Cmnd * SCpnt;    dev = inode->i_rdev & 127;#ifdef DEBUG    if (!scsi_tapes[dev].in_use) {      printk("st%d: Incorrect device.\n", dev);      return (-EIO);    }#endif    if (scsi_tapes[dev].write_prot)      return (-EACCES);    if (scsi_tapes[dev].rw == 1) {      retval = flush_buffer(inode, filp, 0);      if (retval)	return retval;      scsi_tapes[dev].rw = 2;    }#if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS    if (scsi_tapes[dev].buffer->writing) {      write_behind_check(dev);      if (scsi_tapes[dev].buffer->last_result) {#ifdef DEBUG	printk("st%d: Async write error %x.\n", dev,	       scsi_tapes[dev].buffer->last_result);#endif	/*if (scsi_tapes[dev].buffer->last_result = 0x7fffffff)	  retval = (-ENOSPC);	else */	  retval = (-EIO);	return retval;      }    }#endif    SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);    total = count;    memset(cmd, 0, 10);    cmd[0] = WRITE_6;    cmd[1] = 1;    scsi_tapes[dev].rw = 2;    b_point = buf;    while((scsi_tapes[dev].buffer->buffer_bytes + count) >=	  scsi_tapes[dev].buffer->buffer_size) {      do_count = scsi_tapes[dev].buffer->buffer_size -	scsi_tapes[dev].buffer->buffer_bytes;      memcpy_fromfs(scsi_tapes[dev].buffer->b_data +		    scsi_tapes[dev].buffer->buffer_bytes,b_point,do_count);      blks = scsi_tapes[dev].buffer->buffer_blocks;      cmd[2] = blks >> 16;      cmd[3] = blks >> 8;      cmd[4] = blks;      SCpnt->sense_buffer[0] = 0;      SCpnt->request.dev = dev;      scsi_do_cmd (SCpnt,		   (void *) cmd, scsi_tapes[dev].buffer->b_data,		   scsi_tapes[dev].buffer->buffer_size,		   st_sleep_done, ST_TIMEOUT, MAX_RETRIES);      if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );      if (SCpnt->result || SCpnt->sense_buffer[0] != 0) {#ifdef DEBUG	printk("st%d: Error on write:\n", dev);	st_chk_result(dev, SCpnt->result, SCpnt->sense_buffer);#endif	if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&	    (SCpnt->sense_buffer[2] & 0x40))	  retval = (-ENOSPC); /* EOM */	else	  retval = (-EIO);	SCpnt->request.dev = -1;  /* Mark as not busy */	if (count < total)	  return total - count;	else	  return retval;      }      filp->f_pos += do_count;      b_point += do_count;      count -= do_count;      scsi_tapes[dev].buffer->buffer_bytes = 0;      scsi_tapes[dev].dirty = 0;    }    if (count != 0) {      scsi_tapes[dev].dirty = 1;      memcpy_fromfs(scsi_tapes[dev].buffer->b_data +		    scsi_tapes[dev].buffer->buffer_bytes,b_point,count);      filp->f_pos += count;      scsi_tapes[dev].buffer->buffer_bytes += count;      count = 0;    }    do_count = st_chk_result(dev, SCpnt->result, SCpnt->sense_buffer);    if (do_count) {      SCpnt->request.dev = -1;      return do_count;    }#if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS    if (scsi_tapes[dev].buffer->buffer_bytes >= ST_WRITE_THRESHOLD) {      /* Schedule an asynchronous write */      scsi_tapes[dev].buffer->writing = (scsi_tapes[dev].buffer->buffer_bytes /	scsi_tapes[dev].block_size) * scsi_tapes[dev].block_size;      scsi_tapes[dev].dirty = 0;      blks = scsi_tapes[dev].buffer->writing / scsi_tapes[dev].block_size;      cmd[2] = blks >> 16;      cmd[3] = blks >> 8;      cmd[4] = blks;      SCpnt->result = scsi_tapes[dev].buffer->last_result = -1;      SCpnt->sense_buffer[0] = 0;      SCpnt->request.dev = dev;      scsi_do_cmd (SCpnt,		   (void *) cmd, scsi_tapes[dev].buffer->b_data,		   scsi_tapes[dev].buffer->writing,		   st_sleep_done, ST_TIMEOUT, MAX_RETRIES);    }    else#endif      SCpnt->request.dev = -1;  /* Mark as not busy */    return( total);}   /* Read command */int st_read(struct inode * inode, struct file * filp, char * buf, int count){    int dev;    int total;    int transfer, blks;    static unsigned char cmd[10];    Scsi_Cmnd * SCpnt;    dev = inode->i_rdev & 127;#ifdef DEBUG    if (!scsi_tapes[dev].in_use) {      printk("st%d: Incorrect device.\n", dev);      return (-EIO);    }#endif    if (scsi_tapes[dev].rw == 2) {      transfer = flush_buffer(inode, filp, 0);      if (transfer)	return transfer;      scsi_tapes[dev].rw = 1;    }#ifdef DEBUG    if (scsi_tapes[dev].eof)      printk("st%d: EOF flag up. Bytes %d\n", dev,	     scsi_tapes[dev].buffer->buffer_bytes);#endif    if ((scsi_tapes[dev].buffer->buffer_bytes == 0) && scsi_tapes[dev].eof) {      if (scsi_tapes[dev].eof == 1)	return 0;      else /* EOM or blank check */	return (-EIO);    }    scsi_tapes[dev].rw = 1;    SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);    for (total = 0; total < count; ) {      if (scsi_tapes[dev].buffer->buffer_bytes == 0 && scsi_tapes[dev].eof == 0) {	memset(cmd, 0, 10);	cmd[0] = READ_6;	cmd[1] = 1;	blks = scsi_tapes[dev].buffer->buffer_blocks;	cmd[2] = blks >> 16;	cmd[3] = blks >> 8;	cmd[4] = blks;	SCpnt->sense_buffer[0] = 0;	SCpnt->request.dev = dev;	scsi_do_cmd (SCpnt,		     (void *) cmd, scsi_tapes[dev].buffer->b_data,		     scsi_tapes[dev].buffer->buffer_size,		     st_sleep_done, ST_TIMEOUT, MAX_RETRIES);	if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );	scsi_tapes[dev].buffer->read_pointer = 0;	if (SCpnt->result != 0 || SCpnt->sense_buffer[0] != 0) {#ifdef DEBUG	  printk("st%d: Sense: %2x %2x %2x %2x %2x %2x %2x %2x\n", dev,		 SCpnt->sense_buffer[0], SCpnt->sense_buffer[1],		 SCpnt->sense_buffer[2], SCpnt->sense_buffer[3],		 SCpnt->sense_buffer[4], SCpnt->sense_buffer[5],		 SCpnt->sense_buffer[6], SCpnt->sense_buffer[7]);#endif	  if ((SCpnt->sense_buffer[0] & 0x70) == 0x70) { /* extended sense */	    if ((SCpnt->sense_buffer[2] & 0xe0) != 0) { /* EOF, EOM, or ILI */	      transfer = (SCpnt->sense_buffer[3] << 24) |		(SCpnt->sense_buffer[4] << 16) |		  (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6];	      if (SCpnt->sense_buffer[2] & 0x20) {		printk("st%d: Incorrect block size.\n", dev);		SCpnt->request.dev = -1;  /* Mark as not busy */		return (-EIO);	      }	      else if (SCpnt->sense_buffer[2] & 0x40) {		scsi_tapes[dev].eof = 2; /* What should be done at EOM ? */		scsi_tapes[dev].buffer->buffer_bytes =		  (scsi_tapes[dev].buffer->buffer_blocks - transfer) *		    scsi_tapes[dev].block_size;#ifdef DEBUG		printk("st%d: EOM detected (%d blocks read).\n", dev,		       scsi_tapes[dev].buffer->buffer_blocks - transfer);#endif	      }	      else if (SCpnt->sense_buffer[2] & 0x80) {		scsi_tapes[dev].eof = 1;		scsi_tapes[dev].buffer->buffer_bytes =		  (scsi_tapes[dev].buffer->buffer_blocks - transfer) *		    scsi_tapes[dev].block_size;#ifdef DEBUG		printk("st%d: EOF detected (%d blocks read, transferred %d bytes).\n",		       dev, scsi_tapes[dev].buffer->buffer_blocks - transfer, total);#endif	      } /* end of EOF, EOM, ILI test */	    }	    else { /* nonzero sense key */#ifdef DEBUG	      printk("st%d: Tape error. Sense key %x\n", dev,		     SCpnt->sense_buffer[2] & 0x0f);	      decode_sns(dev, SCpnt->sense_buffer);#endif	      SCpnt->request.dev = -1;	      if (total)		return total;	      else		return -EIO;	    }	  }	  else {	    transfer = st_chk_result(dev, SCpnt->result, SCpnt->sense_buffer);	    SCpnt->request.dev = -1;  /* Mark as not busy */	    return transfer;	  }	}	else	  scsi_tapes[dev].buffer->buffer_bytes = scsi_tapes[dev].buffer->buffer_size;      } /* if (SCpnt->result != 0 || SCpnt->sense_buffer[0] != 0) */      if (scsi_tapes[dev].buffer->buffer_bytes > 0) {#ifdef DEBUG	if (scsi_tapes[dev].eof)	  printk("st%d: EOF up. Left %d, needed %d.\n", dev,		 scsi_tapes[dev].buffer->buffer_bytes, count - total);#endif	transfer = scsi_tapes[dev].buffer->buffer_bytes < count - total ?	  scsi_tapes[dev].buffer->buffer_bytes : count - total;	memcpy_tofs(buf, scsi_tapes[dev].buffer->b_data +		    scsi_tapes[dev].buffer->read_pointer,transfer);	filp->f_pos += transfer;	buf += transfer;	total += transfer;	scsi_tapes[dev].buffer->buffer_bytes -= transfer;	scsi_tapes[dev].buffer->read_pointer += transfer;      }      else if (scsi_tapes[dev].eof) {	scsi_tapes[dev].eof_hit = 1;	SCpnt->request.dev = -1;  /* Mark as not busy */	if (total)	  return total;	else	  return (-EIO);      }    } /* for (total = 0; total < count; ) */    SCpnt->request.dev = -1;  /* Mark as not busy */    return total;}/* Internal ioctl function */static int st_int_ioctl(struct inode * inode,struct file * file,	     unsigned int cmd_in, unsigned int arg){

⌨️ 快捷键说明

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