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

📄 st.c

📁 LINUX1.0内核源代码,学习LINUX编程的一定要看。
💻 C
📖 第 1 页 / 共 3 页
字号:
      printk(	"st%d: Density %x, tape length: %x, blocksize: %d, drv buffer: %d\n",	     dev, STp->density, (STp->buffer)->b_data[5] * 65536 +	     (STp->buffer)->b_data[6] * 256 + (STp->buffer)->b_data[7],	     STp->block_size, STp->drv_buffer);#endif      if (STp->block_size > ST_BUFFER_SIZE) {	printk("st%d: Blocksize %d too large for buffer.\n", dev,	       STp->block_size);	(STp->buffer)->in_use = 0;	STp->in_use = 0;	return (-EIO);      }    }    else      STp->block_size = ST_BLOCK_SIZE;    if (STp->block_size > 0) {      (STp->buffer)->buffer_blocks = ST_BUFFER_SIZE / STp->block_size;      (STp->buffer)->buffer_size =	(STp->buffer)->buffer_blocks * STp->block_size;    }    else {      (STp->buffer)->buffer_blocks = 1;      (STp->buffer)->buffer_size = ST_BUFFER_SIZE;    }    (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0;#ifdef DEBUG    printk("st%d: Block size: %d, buffer size: %d (%d blocks).\n", dev,	   STp->block_size, (STp->buffer)->buffer_size,	   (STp->buffer)->buffer_blocks);#endif    if ((STp->buffer)->b_data[2] & 0x80) {      STp->write_prot = 1;#ifdef DEBUG      printk( "st%d: Write protected\n", dev);#endif    }    return 0;}/* Close the device*/	static voidscsi_tape_close(struct inode * inode, struct file * filp){    int dev;    int result;    int rewind;    static unsigned char cmd[10];    Scsi_Cmnd * SCpnt;    Scsi_Tape * STp;       dev = MINOR(inode->i_rdev);    rewind = (dev & 0x80) == 0;    dev = dev & 127;    STp = &(scsi_tapes[dev]);    if ( STp->rw == ST_WRITING) {      result = flush_write_buffer(dev);#ifdef DEBUG      printk("st%d: File length %d bytes.\n", dev, filp->f_pos);#endif      if (result == 0 || result == (-ENOSPC)) {	SCpnt = allocate_device(NULL, (STp->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 *) (STp->buffer)->b_data,		    ST_BLOCK_SIZE, st_sleep_done, ST_TIMEOUT, MAX_RETRIES);	if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );	if ((STp->buffer)->last_result_fatal != 0)	  printk("st%d: Error on write filemark.\n", dev);	SCpnt->request.dev = -1;  /* Mark as not busy */      }#ifdef DEBUG      printk("st%d: Buffer flushed, EOF written\n", dev);#endif    }    else if (!rewind) {#ifndef ST_IN_FILE_POS      if ((STp->eof == ST_FM) && !STp->eof_hit)	st_int_ioctl(inode, filp, MTBSF, 1); /* Back over the EOF hit */#else      flush_buffer(inode, filp, 0);#endif    }    if (rewind)      st_int_ioctl(inode, filp, MTREW, 1);    (STp->buffer)->in_use = 0;    STp->in_use = 0;    return;}/* Write command */	static intst_write(struct inode * inode, struct file * filp, char * buf, int count){    int dev;    int total, do_count, blks, retval, transfer;    int write_threshold;    static unsigned char cmd[10];    char *b_point;    Scsi_Cmnd * SCpnt;    Scsi_Tape * STp;    dev = MINOR(inode->i_rdev) & 127;    STp = &(scsi_tapes[dev]);#ifdef DEBUG    if (!STp->in_use) {      printk("st%d: Incorrect device.\n", dev);      return (-EIO);    }#endif    if (STp->write_prot)      return (-EACCES);    if (STp->block_size == 0 && count > ST_BUFFER_SIZE)      return (-EOVERFLOW);    if (STp->rw == ST_READING) {      retval = flush_buffer(inode, filp, 0);      if (retval)	return retval;      STp->rw = ST_WRITING;    }#if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS    if ((STp->buffer)->writing) {      write_behind_check(dev);      if ((STp->buffer)->last_result_fatal) {#ifdef DEBUG	printk("st%d: Async write error %x.\n", dev,	       (STp->buffer)->last_result);#endif	if ((STp->buffer)->last_result == INT_MAX) {	  retval = (-ENOSPC);  /* All has been written */	  STp->eof = ST_EOM_OK;	}	else	  retval = (-EIO);	return retval;      }    }#endif    if (STp->eof == ST_EOM_OK)      return (-ENOSPC);    else if (STp->eof == ST_EOM_ERROR)      return (-EIO);#ifdef ST_NO_DELAYED_WRITES    if (STp->block_size != 0 && (count % STp->block_size) != 0)      return (-EIO);   /* Write must be integral number of blocks */    write_threshold = 1;#else    write_threshold = (STp->buffer)->buffer_size;#endif    SCpnt = allocate_device(NULL, (STp->device)->index, 1);    total = count;    memset(cmd, 0, 10);    cmd[0] = WRITE_6;    cmd[1] = (STp->block_size != 0);    STp->rw = ST_WRITING;    b_point = buf;    while(#if ST_WRITE_THRESHOLD_BLOCKS  < ST_BUFFER_BLOCKS	  STp->block_size != 0 &&	  ((STp->buffer)->buffer_bytes + count) >	  write_threshold)#else	  (STp->block_size == 0 && count > 0) ||	  ((STp->buffer)->buffer_bytes + count) >=	  write_threshold)#endif    {      if (STp->block_size == 0)	do_count = count;      else {	do_count = (STp->buffer)->buffer_size - (STp->buffer)->buffer_bytes;	if (do_count > count)	  do_count = count;      }      memcpy_fromfs((STp->buffer)->b_data +		    (STp->buffer)->buffer_bytes, b_point, do_count);      if (STp->block_size == 0)        blks = do_count;      else	blks = ((STp->buffer)->buffer_bytes + do_count) /	  STp->block_size;      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, (STp->buffer)->b_data,		   (STp->buffer)->buffer_size,		   st_sleep_done, ST_TIMEOUT, MAX_RETRIES);      if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );      if ((STp->buffer)->last_result_fatal != 0) {#ifdef DEBUG	printk("st%d: Error on write:\n", dev);#endif	if ((SCpnt->sense_buffer[0] & 0x70) == 0x70 &&	    (SCpnt->sense_buffer[2] & 0x40)) {	  if (STp->block_size != 0 && (SCpnt->sense_buffer[0] & 0x80) != 0)	    transfer = (SCpnt->sense_buffer[3] << 24) |	      (SCpnt->sense_buffer[4] << 16) |		(SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6];	  else if (STp->block_size == 0 &&		   (SCpnt->sense_buffer[2] & 0x0f) == VOLUME_OVERFLOW)	    transfer = do_count;	  else	    transfer = 0;	  if (STp->block_size != 0)	    transfer *= STp->block_size;	  if (transfer <= do_count) {	    filp->f_pos += do_count - transfer;	    count -= do_count - transfer;	    STp->eof = ST_EOM_OK;	    retval = (-ENOSPC); /* EOM within current request */#ifdef DEBUG	    printk("st%d: EOM with %d bytes unwritten.\n",		   dev, transfer);#endif	  }	  else {	    STp->eof = ST_EOM_ERROR;	    retval = (-EIO); /* EOM for old data */#ifdef DEBUG	    printk("st%d: EOM with lost data.\n", dev);#endif	  }	}	else	  retval = (-EIO);	SCpnt->request.dev = -1;  /* Mark as not busy */	(STp->buffer)->buffer_bytes = 0;	STp->dirty = 0;	if (count < total)	  return total - count;	else	  return retval;      }      filp->f_pos += do_count;      b_point += do_count;      count -= do_count;      (STp->buffer)->buffer_bytes = 0;      STp->dirty = 0;    }    if (count != 0) {      STp->dirty = 1;      memcpy_fromfs((STp->buffer)->b_data +		    (STp->buffer)->buffer_bytes,b_point,count);      filp->f_pos += count;      (STp->buffer)->buffer_bytes += count;      count = 0;    }    if ((STp->buffer)->last_result_fatal != 0) {      SCpnt->request.dev = -1;      return (STp->buffer)->last_result_fatal;    }#if ST_WRITE_THRESHOLD_BLOCKS < ST_BUFFER_BLOCKS    if ((STp->buffer)->buffer_bytes >= ST_WRITE_THRESHOLD ||	STp->block_size == 0) {      /* Schedule an asynchronous write */      if (STp->block_size == 0)	(STp->buffer)->writing = (STp->buffer)->buffer_bytes;      else	(STp->buffer)->writing = ((STp->buffer)->buffer_bytes /	  STp->block_size) * STp->block_size;      STp->dirty = 0;      if (STp->block_size == 0)	blks = (STp->buffer)->writing;      else	blks = (STp->buffer)->writing / STp->block_size;      cmd[2] = blks >> 16;      cmd[3] = blks >> 8;      cmd[4] = blks;      SCpnt->result = (STp->buffer)->last_result = -1;      SCpnt->sense_buffer[0] = 0;      SCpnt->request.dev = dev;      scsi_do_cmd (SCpnt,		   (void *) cmd, (STp->buffer)->b_data,		   (STp->buffer)->writing,		   st_sleep_done, ST_TIMEOUT, MAX_RETRIES);    }    else#endif      SCpnt->request.dev = -1;  /* Mark as not busy */    return( total);}   /* Read command */	static intst_read(struct inode * inode, struct file * filp, char * buf, int count){    int dev;    int total;    int transfer, blks, bytes;    static unsigned char cmd[10];    Scsi_Cmnd * SCpnt;    Scsi_Tape * STp;    dev = MINOR(inode->i_rdev) & 127;    STp = &(scsi_tapes[dev]);#ifdef DEBUG    if (!STp->in_use) {      printk("st%d: Incorrect device.\n", dev);      return (-EIO);    }#endif    if (STp->block_size == 0 && count > ST_BUFFER_SIZE)      return (-EOVERFLOW);    if (STp->rw == ST_WRITING) {      transfer = flush_buffer(inode, filp, 0);      if (transfer)	return transfer;      STp->rw = ST_READING;    }#ifdef DEBUG    if (STp->eof != ST_NOEOF)      printk("st%d: EOF flag up. Bytes %d\n", dev,	     (STp->buffer)->buffer_bytes);#endif    if (((STp->buffer)->buffer_bytes == 0) &&	STp->eof == ST_EOM_OK)  /* EOM or Blank Check */      return (-EIO);    STp->rw = ST_READING;    SCpnt = allocate_device(NULL, (STp->device)->index, 1);    for (total = 0; total < count; ) {      if ((STp->buffer)->buffer_bytes == 0 &&	  STp->eof == ST_NOEOF) {	memset(cmd, 0, 10);	cmd[0] = READ_6;	cmd[1] = (STp->block_size != 0);	if (STp->block_size == 0)	  blks = bytes = count;	else {	  blks = (STp->buffer)->buffer_blocks;	  bytes = blks * STp->block_size;	}	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, (STp->buffer)->b_data,		     (STp->buffer)->buffer_size,		     st_sleep_done, ST_TIMEOUT, MAX_RETRIES);	if (SCpnt->request.dev == dev) sleep_on( &(STp->waiting) );	(STp->buffer)->read_pointer = 0;	STp->eof_hit = 0;	if ((STp->buffer)->last_result_fatal) {#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 */	      if ((SCpnt->sense_buffer[0] & 0x80) != 0)		transfer = (SCpnt->sense_buffer[3] << 24) |		  (SCpnt->sense_buffer[4] << 16) |		    (SCpnt->sense_buffer[5] << 8) | SCpnt->sense_buffer[6];	      else		transfer = 0;	      if (STp->block_size == 0 &&		  (SCpnt->sense_buffer[2] & 0x0f) == MEDIUM_ERROR)		transfer = bytes;	      if (SCpnt->sense_buffer[2] & 0x20) {		if (STp->block_size == 0) {		  if (transfer <= 0)		    transfer = 0;		  (STp->buffer)->buffer_bytes = count - transfer;		}		else {		  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) {		STp->eof = ST_EOM_OK;		if (STp->block_size == 0)		  (STp->buffer)->buffer_bytes = count - transfer;		else		  (STp->buffer)->buffer_bytes =		    ((STp->buffer)->buffer_blocks - transfer) *		      STp->block_size;#ifdef DEBUG		printk("st%d: EOM detected (%d bytes read).\n", dev,		       (STp->buffer)->buffer_bytes);#endif	      }	      else if (SCpnt->sense_buffer[2] & 0x80) {		STp->eof = ST_FM;		if (STp->block_size == 0)		  (STp->buffer)->buffer_bytes = 0;		else		  (STp->buffer)->buffer_bytes =		    ((STp->buffer)->buffer_blocks - transfer) *		      STp->block_size;#ifdef DEBUG		printk(		 "st%d: EOF detected (%d bytes read, transferred %d bytes).\n",		       dev, (STp->buffer)->buffer_bytes, total);#endif	      } /* end of EOF, EOM, ILI test */	    }	    else { /* nonzero sense key */#ifdef DEBUG	      printk("st%d: Tape error while reading.\n", dev);#endif	      SCpnt->request.dev = -1;	      if (total)		return total;	      else		return -EIO;	    }	  }	  else {	    transfer = (STp->buffer)->last_result_fatal;	    SCpnt->request.dev = -1;  /* Mark as not busy */	    return transfer;	  }	}	else /* Read successful */	  (STp->buffer)->buffer_bytes = bytes;      } /* if ((STp->buffer)->buffer_bytes == 0 &&	   STp->eof == ST_NOEOF) */      if ((STp->buffer)->buffer_bytes > 0) {#ifdef DEBUG	if (STp->eof != ST_NOEOF)	  printk("st%d: EOF up. Left %d, needed %d.\n", dev,		 (STp->buffer)->buffer_bytes, count - total);#endif

⌨️ 快捷键说明

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