📄 tapechar.c
字号:
case MTBSFM: // backward space file, stop at BOT side cqr = ti->discipline->mtbsfm (ti, mt_count); break; case MTFSR: // forward space file cqr = ti->discipline->mtfsr (ti, mt_count); break; case MTBSR: // backward space file cqr = ti->discipline->mtbsr (ti, mt_count); break; case MTNOP: cqr = ti->discipline->mtnop (ti, mt_count); break; case MTEOM: // postion at the end of portion case MTRETEN: // retension the tape cqr = ti->discipline->mteom (ti, mt_count); break; case MTERASE: cqr = ti->discipline->mterase (ti, mt_count); break; case MTSETDENSITY: cqr = ti->discipline->mtsetdensity (ti, mt_count); break; case MTSEEK: cqr = ti->discipline->mtseek (ti, mt_count); break; case MTSETDRVBUFFER: cqr = ti->discipline->mtsetdrvbuffer (ti, mt_count); break; case MTLOCK: cqr = ti->discipline->mtsetdrvbuffer (ti, mt_count); break; case MTUNLOCK: cqr = ti->discipline->mtsetdrvbuffer (ti, mt_count); break; case MTLOAD: cqr = ti->discipline->mtload (ti, mt_count); if (cqr!=NULL) break; // if backend driver has an load function ->use it // if no medium is in, wait until it gets inserted if (ti->medium_is_unloaded) { wait_event_interruptible (ti->wq,ti->medium_is_unloaded==0); } return 0; case MTCOMPRESSION: cqr = ti->discipline->mtcompression (ti, mt_count); break; case MTSETPART: cqr = ti->discipline->mtsetpart (ti, mt_count); break; case MTMKPART: cqr = ti->discipline->mtmkpart (ti, mt_count); break; case MTTELL: // return number of block relative to current file cqr = ti->discipline->mttell (ti, mt_count); break; case MTSETBLK: s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); ti->block_size = mt_count; s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:setblk:"); debug_int_event (tape_debug_area,6,mt_count);#endif return 0; case MTRESET: s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); ti->kernbuf = ti->userbuf = NULL; tapestate_set (ti, TS_IDLE); ti->block_size = 0; s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:devreset:"); debug_int_event (tape_debug_area,6,ti->blk_minor);#endif return 0; default:#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:inv.mtio");#endif return -EINVAL; } if (cqr == NULL) {#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:ccwg fail");#endif return -ENOSPC; } s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); ti->cqr = cqr; ti->wanna_wakeup=0; rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); wait_event_interruptible (ti->wq,ti->wanna_wakeup); ti->cqr = NULL; if (ti->kernbuf != NULL) { kfree (ti->kernbuf); ti->kernbuf = NULL; } tape_free_request (cqr); // if medium was unloaded, update the corresponding variable. switch (mt_op) { case MTOFFL: case MTUNLOAD: ti->medium_is_unloaded=1; } if (signal_pending (current)) { tapestate_set (ti, TS_IDLE); return -ERESTARTSYS; } s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); if (((mt_op == MTEOM) || (mt_op == MTRETEN)) && (tapestate_get (ti) == TS_FAILED)) tapestate_set (ti, TS_DONE); if (tapestate_get (ti) == TS_FAILED) { tapestate_set (ti, TS_IDLE); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); return ti->rc; } if (tapestate_get (ti) == TS_NOT_OPER) { ti->blk_minor=ti->rew_minor=ti->nor_minor=-1; ti->devinfo.irq=-1; s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags); return -ENODEV; } if (tapestate_get (ti) != TS_DONE) { tapestate_set (ti, TS_IDLE); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); return -EIO; } tapestate_set (ti, TS_IDLE); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); switch (mt_op) { case MTRETEN: //need to rewind the tape after moving to eom return tape_mtioctop (filp, MTREW, 1); case MTFSFM: //need to skip back over the filemark return tape_mtioctop (filp, MTBSFM, 1); case MTBSF: //need to skip forward over the filemark return tape_mtioctop (filp, MTFSF, 1); }#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:mtio done");#endif return 0;}/* * Tape device io controls. */inttape_ioctl (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){ long lockflags; tape_info_t *ti; ccw_req_t *cqr; struct mtop op; /* structure for MTIOCTOP */ struct mtpos pos; /* structure for MTIOCPOS */ struct mtget get; int rc;#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:ioct");#endif ti = first_tape_info; while ((ti != NULL) && (ti->rew_minor != MINOR (inode->i_rdev)) && (ti->nor_minor != MINOR (inode->i_rdev))) ti = (tape_info_t *) ti->next; if (ti == NULL) {#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:nodev");#endif return -ENODEV; } // check for discipline ioctl overloading if ((rc = ti->discipline->discipline_ioctl_overload (inode, filp, cmd, arg)) != -EINVAL) {#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:ioverloa");#endif return rc; } switch (cmd) { case MTIOCTOP: /* tape op command */ if (copy_from_user (&op, (char *) arg, sizeof (struct mtop))) { return -EFAULT; } return (tape_mtioctop (filp, op.mt_op, op.mt_count)); case MTIOCPOS: /* query tape position */ cqr = ti->discipline->mttell (ti, 0); s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); ti->cqr = cqr; ti->wanna_wakeup=0; do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); wait_event_interruptible (ti->wq,ti->wanna_wakeup); pos.mt_blkno = ti->rc; ti->cqr = NULL; if (ti->kernbuf != NULL) { kfree (ti->kernbuf); ti->kernbuf = NULL; } tape_free_request (cqr); if (signal_pending (current)) { tapestate_set (ti, TS_IDLE); return -ERESTARTSYS; } s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); tapestate_set (ti, TS_IDLE); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); if (copy_to_user ((char *) arg, &pos, sizeof (struct mtpos))) return -EFAULT; return 0; case MTIOCGET: get.mt_erreg = ti->rc; cqr = ti->discipline->mttell (ti, 0); s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); ti->cqr = cqr; ti->wanna_wakeup=0; do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); wait_event_interruptible (ti->wq,ti->wanna_wakeup); get.mt_blkno = ti->rc; get.mt_fileno = 0; get.mt_type = MT_ISUNKNOWN; get.mt_resid = ti->devstat.rescnt; get.mt_dsreg = ti->devstat.ii.sense.data[3]; get.mt_gstat = 0; if (ti->devstat.ii.sense.data[1] & 0x08) get.mt_gstat &= GMT_BOT (1); // BOT if (ti->devstat.ii.sense.data[1] & 0x02) get.mt_gstat &= GMT_WR_PROT (1); // write protected if (ti->devstat.ii.sense.data[1] & 0x40) get.mt_gstat &= GMT_ONLINE (1); //drive online ti->cqr = NULL; if (ti->kernbuf != NULL) { kfree (ti->kernbuf); ti->kernbuf = NULL; } tape_free_request (cqr); if (signal_pending (current)) { tapestate_set (ti, TS_IDLE); return -ERESTARTSYS; } s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); tapestate_set (ti, TS_IDLE); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); if (copy_to_user ((char *) arg, &get, sizeof (struct mtget))) return -EFAULT; return 0; default:#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,3,"c:ioct inv");#endif return -EINVAL; }}/* * Tape device open function. */inttape_open (struct inode *inode, struct file *filp){ tape_info_t *ti; kdev_t dev; long lockflags; inode = filp->f_dentry->d_inode; ti = first_tape_info; while ((ti != NULL) && (ti->rew_minor != MINOR (inode->i_rdev)) && (ti->nor_minor != MINOR (inode->i_rdev))) ti = (tape_info_t *) ti->next; if (ti == NULL) return -ENODEV;#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:open:"); debug_int_event (tape_debug_area,6,ti->blk_minor);#endif s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); if (tapestate_get (ti) != TS_UNUSED) { s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:dbusy");#endif return -EBUSY; } tapestate_set (ti, TS_IDLE); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); dev = MKDEV (tape_major, MINOR (inode->i_rdev)); /* Get the device */ s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); if (ti->rew_minor == MINOR (inode->i_rdev)) ti->rew_filp = filp; /* save for later reference */ else ti->nor_filp = filp; filp->private_data = ti; /* save the dev.info for later reference */ s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);#ifdef MODULE MOD_INC_USE_COUNT;#endif /* MODULE */ return 0;}/* * Tape device release function. */inttape_release (struct inode *inode, struct file *filp){ long lockflags; tape_info_t *ti,*lastti; ccw_req_t *cqr = NULL; int rc = 0; ti = first_tape_info; while ((ti != NULL) && (ti->rew_minor != MINOR (inode->i_rdev)) && (ti->nor_minor != MINOR (inode->i_rdev))) ti = (tape_info_t *) ti->next; if ((ti != NULL) && (tapestate_get (ti) == TS_NOT_OPER)) { if (ti==first_tape_info) { first_tape_info=ti->next; } else { lastti=first_tape_info; while (lastti->next!=ti) lastti=lastti->next; lastti->next=ti->next; } kfree(ti); goto out; } if ((ti == NULL) || (tapestate_get (ti) != TS_IDLE)) {#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:notidle!");#endif rc = -ENXIO; /* error in tape_release */ goto out; }#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:release:"); debug_int_event (tape_debug_area,6,ti->blk_minor);#endif if (ti->rew_minor == MINOR (inode->i_rdev)) { cqr = ti->discipline->mtrew (ti, 1); if (cqr != NULL) {#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"c:rewrelea");#endif s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); tapestate_set (ti, TS_REW_RELEASE_INIT); ti->cqr = cqr; ti->wanna_wakeup=0; rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); wait_event (ti->wq,ti->wanna_wakeup); ti->cqr = NULL; tape_free_request (cqr); } } s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); tapestate_set (ti, TS_UNUSED); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);out:#ifdef MODULE MOD_DEC_USE_COUNT;#endif /* MODULE */ return rc;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -