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

📄 st.c

📁 linux0.99源代码用于研究linux操作系统
💻 C
📖 第 1 页 / 共 3 页
字号:
   int dev = inode->i_rdev;   int timeout = ST_LONG_TIMEOUT;   long ltmp;   int ioctl_result;   unsigned char cmd[10];   Scsi_Cmnd * SCpnt;   dev = dev & 127;   SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);   memset(cmd, 0, 10);   switch (cmd_in) {     case MTFSF:     case MTFSFM:       cmd[0] = SPACE;       cmd[1] = 0x01; /* Space FileMarks */       cmd[2] = (arg >> 16);       cmd[3] = (arg >> 8);       cmd[4] = arg;#ifdef DEBUG       printk("st%d: Spacing tape forward %d files.\n", dev,	      cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);#endif       break;      case MTBSF:     case MTBSFM:       cmd[0] = SPACE;       cmd[1] = 0x01; /* Space FileMarks */       ltmp = (-arg);       cmd[2] = (ltmp >> 16);       cmd[3] = (ltmp >> 8);       cmd[4] = ltmp;#ifdef DEBUG       if (cmd[2] & 0x80)	 ltmp = 0xff000000;       ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];       printk("st%d: Spacing tape backward %d files.\n", dev, (-ltmp));#endif       break;       case MTFSR:       cmd[0] = SPACE;       cmd[1] = 0x00; /* Space Blocks */       cmd[2] = (arg >> 16);       cmd[3] = (arg >> 8);       cmd[4] = arg;#ifdef DEBUG       printk("st%d: Spacing tape forward %d blocks.\n", dev,	      cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);#endif       break;      case MTBSR:       cmd[0] = SPACE;       cmd[1] = 0x00; /* Space Blocks */       ltmp = (-arg);       cmd[2] = (ltmp >> 16);       cmd[3] = (ltmp >> 8);       cmd[4] = ltmp;       SCpnt->result = -1;#ifdef DEBUG       if (cmd[2] & 0x80)	 ltmp = 0xff000000;       ltmp = ltmp | (cmd[2] << 16) | (cmd[3] << 8) | cmd[4];       printk("st%d: Spacing tape backward %d blocks.\n", dev, (-ltmp));#endif       break;      case MTWEOF:       if (scsi_tapes[dev].write_prot)	 return (-EACCES);       cmd[0] = WRITE_FILEMARKS;       cmd[2] = (arg >> 16);       cmd[3] = (arg >> 8);       cmd[4] = arg;       timeout = ST_TIMEOUT;#ifdef DEBUG       printk("st%d: Writing %d filemarks.\n", dev,	      cmd[2] * 65536 + cmd[3] * 256 + cmd[4]);#endif       break;      case MTREW:       cmd[0] = REZERO_UNIT;#ifdef ST_NOWAIT       cmd[1] = 1;  /* Don't wait for completion */       timeout = ST_TIMEOUT;#endif#ifdef DEBUG       printk("st%d: Rewinding tape.\n", dev);#endif       break;      case MTOFFL:       cmd[0] = START_STOP;#ifdef ST_NOWAIT       cmd[1] = 1;  /* Don't wait for completion */       timeout = ST_TIMEOUT;#endif#ifdef DEBUG       printk("st%d: Unloading tape.\n", dev);#endif       break;      case MTNOP:#ifdef DEBUG       printk("st%d: No op on tape.\n", dev);#endif       return 0;  /* Should do something ? */       break;     case MTRETEN:       cmd[0] = START_STOP;#ifdef ST_NOWAIT       cmd[1] = 1;  /* Don't wait for completion */       timeout = ST_TIMEOUT;#endif       cmd[4] = 3;#ifdef DEBUG       printk("st%d: Retensioning tape.\n", dev);#endif       break;      case MTEOM:       cmd[0] = SPACE;       cmd[1] = 3;#ifdef DEBUG       printk("st%d: Spacing to end of tape media.\n", dev);#endif       break;      case MTERASE:       if (scsi_tapes[dev].write_prot)	 return (-EACCES);       cmd[0] = ERASE;       cmd[1] = 1;  /* To the end of tape */#ifdef DEBUG       printk("st%d: Erasing tape.\n", dev);#endif       break;     case MTSEEK:       if (scsi_tapes[dev].device->scsi_level < SCSI_2) {	 cmd[0] = QFA_SEEK_BLOCK;	 cmd[2] = (arg >> 16);	 cmd[3] = (arg >> 8);	 cmd[4] = arg;	 cmd[5] = 0;       }       else {	 cmd[0] = SEEK_10;	 cmd[1] = 4;	 cmd[3] = (arg >> 24);	 cmd[4] = (arg >> 16);	 cmd[5] = (arg >> 8);	 cmd[6] = arg;       }#ifdef ST_NOWAIT       cmd[1] |= 1;  /* Don't wait for completion */       timeout = ST_TIMEOUT;#endif#ifdef DEBUG       printk("st%d: Seeking tape to block %d.\n", dev, arg);#endif       break;     case MTSETBLK:  /* Set block length */     case MTSETDENSITY: /* Set tape density */       if (scsi_tapes[dev].dirty || scsi_tapes[dev].buffer->buffer_bytes != 0)	 return (-EIO);   /* Not allowed if data in buffer */       if (cmd_in == MTSETBLK &&	   (arg < scsi_tapes[dev].min_block || arg > scsi_tapes[dev].max_block ||	    arg > ST_BUFFER_SIZE)) {	 printk("st%d: Illegal block size.\n", dev);	 return (-EINVAL);       }       cmd[0] = MODE_SELECT;       cmd[4] = 12;       memset(scsi_tapes[dev].buffer->b_data, 0, 12);       scsi_tapes[dev].buffer->b_data[2] = 0x10;  /* buffered mode */       scsi_tapes[dev].buffer->b_data[3] = 8;     /* block descriptor length */       if (cmd_in == MTSETBLK)	 ltmp = arg;       else {	 scsi_tapes[dev].buffer->b_data[4] = arg;	 ltmp = scsi_tapes[dev].block_size;       }       scsi_tapes[dev].buffer->b_data[9] = (ltmp >> 16);       scsi_tapes[dev].buffer->b_data[10] = (ltmp >> 8);       scsi_tapes[dev].buffer->b_data[11] = ltmp;       timeout = ST_TIMEOUT;#ifdef DEBUG       if (cmd_in == MTSETBLK)	 printk("st%d: Setting block size to %d bytes.\n", dev,		scsi_tapes[dev].buffer->b_data[9] * 65536 +		scsi_tapes[dev].buffer->b_data[10] * 256 +		scsi_tapes[dev].buffer->b_data[11]);       else	 printk("st%d: Setting density code to %x.\n", dev,		scsi_tapes[dev].buffer->b_data[4]);#endif       break;     default:       printk("st%d: Unknown st_ioctl command %x.\n", dev, cmd_in);       SCpnt->request.dev = -1;  /* Mark as not busy */       return (-ENOSYS);     }   SCpnt->sense_buffer[0] = 0;   SCpnt->request.dev = dev;   scsi_do_cmd(SCpnt,	       (void *) cmd, (void *) scsi_tapes[dev].buffer->b_data, ST_BLOCK_SIZE,	       st_sleep_done, timeout, MAX_RETRIES);   if (SCpnt->request.dev == dev) sleep_on( &scsi_tapes[dev].waiting );   SCpnt->request.dev = -1;  /* Mark as not busy */   ioctl_result = st_chk_result(dev, SCpnt->result, SCpnt->sense_buffer);   if (!ioctl_result) {     if (cmd_in == MTBSFM)       ioctl_result = st_int_ioctl(inode, file, MTFSF, 1);     else if (cmd_in == MTSETBLK) {       scsi_tapes[dev].block_size = arg;       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;     }     if (cmd_in == MTEOM || cmd_in == MTWEOF) {       scsi_tapes[dev].eof = 2;       scsi_tapes[dev].eof_hit = 0;     }     else if (cmd_in != MTSETBLK && cmd_in != MTNOP) {       scsi_tapes[dev].eof = 0;       scsi_tapes[dev].eof_hit = 0;     }   }   return ioctl_result ;}/* The ioctl command */static int st_ioctl(struct inode * inode,struct file * file,	     unsigned int cmd_in, unsigned int arg){   int dev = inode->i_rdev;   int i, cmd, result;   struct mtop mtc;   struct mtpos mt_pos;   unsigned char scmd[10];   Scsi_Cmnd *SCpnt;   dev = dev & 127;#ifdef DEBUG   if (!scsi_tapes[dev].in_use) {     printk("st%d: Incorrect device.\n", dev);     return (-EIO);   }#endif   cmd = cmd_in & IOCCMD_MASK;   if (cmd == (MTIOCTOP & IOCCMD_MASK)) {     if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(mtc))       return (-EINVAL);     verify_area((void *)arg, sizeof(mtc));     memcpy_fromfs((char *) &mtc, (char *)arg, sizeof(struct mtop));     i = flush_buffer(inode, file, mtc.mt_op == MTSEEK ||		      mtc.mt_op == MTREW || mtc.mt_op == MTOFFL ||		      mtc.mt_op == MTRETEN || mtc.mt_op == MTEOM);     if (i < 0)       return i;     return st_int_ioctl(inode, file, mtc.mt_op, mtc.mt_count);   }   else if (cmd == (MTIOCGET & IOCCMD_MASK)) {     if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtget))       return (-EINVAL);     verify_area((void *)arg, sizeof(struct mtget));     memcpy_tofs((char *)arg, (char *)scsi_tapes[dev].buffer->mt_status,		 sizeof(struct mtget));     return 0;   }   else if (cmd == (MTIOCPOS & IOCCMD_MASK)) {#ifdef DEBUG     printk("st%d: get tape position.\n", dev);#endif     if (((cmd_in & IOCSIZE_MASK) >> IOCSIZE_SHIFT) != sizeof(struct mtpos))       return (-EINVAL);     i = flush_buffer(inode, file, 0);     if (i < 0)       return i;     verify_area((void *)arg, sizeof(struct mtpos));     SCpnt = allocate_device(NULL, scsi_tapes[dev].device->index, 1);     SCpnt->sense_buffer[0]=0;     memset (scmd, 0, 10);     if (scsi_tapes[dev].device->scsi_level < SCSI_2) {       scmd[0] = QFA_REQUEST_BLOCK;       scmd[4] = 3;     }     else {       scmd[0] = READ_POSITION;       scmd[1] = 1;     }     SCpnt->request.dev = dev;     SCpnt->sense_buffer[0] = 0;     scsi_do_cmd(SCpnt,		 (void *) scmd, (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 || SCpnt->sense_buffer[0]) {       mt_pos.mt_blkno = (-1);#ifdef DEBUG       printk("st%d: Can't read tape position.\n", dev);#endif       result = (-EIO);     }     else {       result = 0;       if (scsi_tapes[dev].device->scsi_level < SCSI_2)	 mt_pos.mt_blkno = (scsi_tapes[dev].buffer->b_data[0] << 16) 	   + (scsi_tapes[dev].buffer->b_data[1] << 8) 	     + scsi_tapes[dev].buffer->b_data[2];       else	 mt_pos.mt_blkno = (scsi_tapes[dev].buffer->b_data[4] << 24)	   + (scsi_tapes[dev].buffer->b_data[5] << 16) 	     + (scsi_tapes[dev].buffer->b_data[6] << 8) 	       + scsi_tapes[dev].buffer->b_data[7];     }     SCpnt->request.dev = -1;  /* Mark as not busy */     memcpy_tofs((char *)arg, (char *) (&mt_pos), sizeof(struct mtpos));     return result;   }   else     return (-EINVAL);}static struct file_operations st_fops = {   NULL,            /* lseek - default */   st_read,         /* read - general block-dev read */   st_write,        /* write - general block-dev write */   NULL,            /* readdir - bad */   NULL,            /* select */   st_ioctl,        /* ioctl */   NULL,            /* mmap */   scsi_tape_open,  /* open */   scsi_tape_close  /* release */};void st_attach(Scsi_Device * SDp){  scsi_tapes[NR_ST++].device = SDp;  if(NR_ST > MAX_ST) panic ("scsi_devices corrupt (st)");};unsigned long st_init1(unsigned long mem_start, unsigned long mem_end){  scsi_tapes = (Scsi_Tape *) mem_start;  mem_start += MAX_ST * sizeof(Scsi_Tape);  return mem_start;};/* Driver initialization */unsigned long st_init(unsigned long mem_start, unsigned long mem_end){  int i;  if (NR_ST == 0) return mem_start;#ifdef DEBUG  printk("st: Init tape.\n");#endif  chrdev_fops[MAJOR_NR] = &st_fops;  for (i=0; i < NR_ST; ++i) {    scsi_tapes[i].capacity = 0xfffff;    scsi_tapes[i].dirty = 0;    scsi_tapes[i].rw = 0;    scsi_tapes[i].eof = 0;    scsi_tapes[i].waiting = NULL;    scsi_tapes[i].in_use = 0;  }  /* Allocate the buffers */  if (NR_ST == 1)    st_nbr_buffers = 1;  else    st_nbr_buffers = 2;  for (i=0; i < st_nbr_buffers; i++) {    st_buffers[i] = (ST_buffer *) mem_start;#ifdef DEBUG    printk("st: Buffer address: %x\n", st_buffers[i]);#endif    mem_start += sizeof(ST_buffer) - 1 + ST_BUFFER_BLOCKS * ST_BLOCK_SIZE;    st_buffers[i]->mt_status = (struct mtget *) mem_start;    mem_start += sizeof(struct mtget);    st_buffers[i]->in_use = 0;    st_buffers[i]->writing = 0;    /* "generic" status */    memset((void *) st_buffers[i]->mt_status, 0, sizeof(struct mtget));    st_buffers[i]->mt_status->mt_type = MT_ISSCSI1;  }  return mem_start;}

⌨️ 快捷键说明

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