📄 tapeblock.c
字号:
if (ti->request_queue==NULL) {#endif // nothing more to do or device has dissapeared;)#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"b:Qempty");#endif tapestate_set(ti,TS_IDLE); return; } // queue is not empty, fetch a request and start IO! req=ti->current_request=tape_next_request(&ti->request_queue); if (req==NULL) { BUG(); // Yo. The queue was not reported empy, but no request found. This is _bad_. } if (req->cmd!=READ) { // we only support reading tapestate_set(ti,TS_FAILED); tapeblock_end_request (ti); // check state, inform user, free mem, dev=idl tapestate_set(ti,TS_BLOCK_INIT); schedule_tapeblock_exec_IO(ti); return; } ti->cqr=ti->discipline->bread(req,ti,tapeblock_major); //build channel program from request if (!ti->cqr) { // ccw generation failed. we try again later.#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,3,"b:cqrNULL");#endif schedule_tapeblock_exec_IO(ti); ti->current_request=NULL; return; } ti->blk_retries = TAPEBLOCK_RETRIES; rc= do_IO (ti->devinfo.irq, ti->cqr->cpaddr, (unsigned long) ti->cqr, 0x00, ti->cqr->options); if (rc) { // okay. ssch failed. we try later.#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,3,"b:doIOfail");#endif ti->discipline->free_bread(ti->cqr,ti); ti->cqr=NULL; ti->current_request=NULL; schedule_tapeblock_exec_IO(ti); return; } // our request is in IO. we remove it from the queue and exit tape_dequeue_request (&ti->request_queue,req);}static void do_tape_request (request_queue_t * queue) { tape_info_t* ti; long lockflags; for (ti=first_tape_info; ((ti!=NULL) && ((&ti->request_queue)!=queue)); ti=ti->next); if (ti==NULL) BUG(); s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); if (tapestate_get(ti)!=TS_IDLE) { s390irq_spin_unlock_irqrestore(ti->devinfo.irq,lockflags); return; } if (tapestate_get(ti)!=TS_IDLE) BUG(); tapestate_set(ti,TS_BLOCK_INIT); tapeblock_exec_IO(ti); s390irq_spin_unlock_irqrestore(ti->devinfo.irq,lockflags);}static voidrun_tapeblock_exec_IO (tape_info_t* ti) { long flags_390irq,flags_ior; spin_lock_irqsave (&io_request_lock, flags_ior); s390irq_spin_lock_irqsave(ti->devinfo.irq,flags_390irq); atomic_set(&ti->bh_scheduled,0); tapeblock_exec_IO(ti); s390irq_spin_unlock_irqrestore(ti->devinfo.irq,flags_390irq); spin_unlock_irqrestore (&io_request_lock, flags_ior);}voidschedule_tapeblock_exec_IO (tape_info_t *ti){ /* Protect against rescheduling, when already running */ if (atomic_compare_and_swap(0,1,&ti->bh_scheduled)) { return; }#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98)) INIT_LIST_HEAD(&ti->bh_tq.list);#endif ti->bh_tq.sync = 0; ti->bh_tq.routine = (void *) (void *) run_tapeblock_exec_IO; ti->bh_tq.data = ti; queue_task (&ti->bh_tq, &tq_immediate); mark_bh (IMMEDIATE_BH); return;}/* wrappers around do_tape_request for different kernel versions */#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98))static void tape_request_fn (void) { tape_info_t* ti=first_tape_info; while (ti!=NULL) { do_tape_request(&ti->request_queue); ti=ti->next; }}#elsestatic void tape_request_fn (request_queue_t* queue) { do_tape_request(queue);}#endifstatic request_queue_t* tapeblock_getqueue (kdev_t kdev) { tape_info_t* ti=first_tape_info; while ((ti!=NULL) && (MINOR(kdev)!=ti->blk_minor)) ti=ti->next; if (ti!=NULL) return &ti->request_queue; return NULL;}int tapeblock_mediumdetect(tape_info_t* ti) { ccw_req_t* cqr; int losize=1,hisize=1,rc; long lockflags;#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,3,"b:medDet");#endif PRINT_WARN("Detecting media size. This will take _long_, so get yourself a coffee...\n"); while (1) { //is interruped by break hisize=hisize << 1; // try twice the size tested before cqr=ti->discipline->mtseek (ti, hisize); if (cqr == NULL) {#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"b: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); if (rc) return -EIO; wait_event_interruptible (ti->wq,ti->wanna_wakeup); ti->cqr = NULL; tape_free_request (cqr); if (ti->kernbuf) { kfree (ti->kernbuf); ti->kernbuf=NULL; } if (signal_pending (current)) { tapestate_set (ti, TS_IDLE); return -ERESTARTSYS; } s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); if (tapestate_get (ti) == TS_FAILED) { tapestate_set (ti, TS_IDLE); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); break; } 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); losize=hisize; } cqr = ti->discipline->mtrew (ti, 1); if (cqr == NULL) {#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"b: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; tape_free_request (cqr); if (signal_pending (current)) { tapestate_set (ti, TS_IDLE); return -ERESTARTSYS; } s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); if (tapestate_get (ti) == TS_FAILED) { tapestate_set (ti, TS_IDLE); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); return -EIO; } 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); while (losize!=hisize) { cqr=ti->discipline->mtseek (ti, (hisize+losize)/2+1); if (cqr == NULL) {#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"b: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); if (rc) return -EIO; wait_event_interruptible (ti->wq,ti->wanna_wakeup); ti->cqr = NULL; tape_free_request (cqr); if (ti->kernbuf) { kfree (ti->kernbuf); ti->kernbuf=NULL; } if (signal_pending (current)) { tapestate_set (ti, TS_IDLE); return -ERESTARTSYS; } s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); 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_FAILED) { tapestate_set (ti, TS_IDLE); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); hisize=(hisize+losize)/2; cqr = ti->discipline->mtrew (ti, 1); if (cqr == NULL) {#ifdef TAPE_DEBUG debug_text_event (tape_debug_area,6,"b: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; tape_free_request (cqr); if (signal_pending (current)) { tapestate_set (ti, TS_IDLE); return -ERESTARTSYS; } s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags); if (tapestate_get (ti) == TS_FAILED) { tapestate_set (ti, TS_IDLE); s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags); return -EIO; } 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); continue; } 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); losize=(hisize+losize)/2+1; } blk_size[tapeblock_major][ti->blk_minor]=(losize)*(blksize_size[tapeblock_major][ti->blk_minor]/1024); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -