1
2/***************************************************************************
3 *
4 *  drivers/s390/char/tapeblock.c
5 *    block device frontend for tape device driver
6 *
7 *  S390 and zSeries version
8 *    Copyright (C) 2001 IBM Corporation
9 *    Author(s): Carsten Otte <cotte@de.ibm.com>
10 *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
11 *
12 *
13 ****************************************************************************
14 */
15
16#include "tapedefs.h"
17#include <linux/config.h>
18#include <linux/blkdev.h>
19#include <linux/blk.h>
20#include <linux/version.h>
21#include <linux/interrupt.h>
22#include <asm/ccwcache.h>	/* CCW allocations      */
23#include <asm/debug.h>
24#include <asm/s390dyn.h>
25#include <linux/compatmac.h>
26#ifdef MODULE
27#define __NO_VERSION__
28#include <linux/module.h>
29#endif
30#include "tape.h"
31#include "tapeblock.h"
32
33#define PRINTK_HEADER "TBLOCK:"
34
35/*
36 * file operation structure for tape devices
37 */
38#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
39static struct block_device_operations tapeblock_fops = {
40#else
41static struct file_operations tapeblock_fops = {
42#endif
43    owner   : THIS_MODULE,
44    open    : tapeblock_open,      /* open */
45    release : tapeblock_release,   /* release */
46        };
47
48int    tapeblock_major = 0;
49
50#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
51static void tape_request_fn (request_queue_t * queue);
52#else
53static void tape_request_fn (void);
54#endif
55
56static request_queue_t* tapeblock_getqueue (kdev_t kdev);
57
58#ifdef CONFIG_DEVFS_FS
59void
60tapeblock_mkdevfstree (tape_info_t* ti) {
61    ti->devfs_block_dir=devfs_mk_dir (ti->devfs_dir, "block", ti);
62    ti->devfs_disc=devfs_register(ti->devfs_block_dir, "disc",DEVFS_FL_DEFAULT,
63				    tapeblock_major, ti->blk_minor,
64				    TAPEBLOCK_DEFAULTMODE, &tapeblock_fops, ti);
65}
66
67void
68tapeblock_rmdevfstree (tape_info_t* ti) {
69    devfs_unregister(ti->devfs_disc);
70    devfs_unregister(ti->devfs_block_dir);
71}
72#endif
73
74void
75tapeblock_setup(tape_info_t* ti) {
76    blk_size[tapeblock_major][ti->blk_minor]=0; // this will be detected
77    blksize_size[tapeblock_major][ti->blk_minor]=2048; // blocks are 2k by default.
78    hardsect_size[tapeblock_major][ti->blk_minor]=512;
79    blk_init_queue (&ti->request_queue, tape_request_fn);
80    blk_queue_headactive (&ti->request_queue, 0);
81#ifdef CONFIG_DEVFS_FS
82    tapeblock_mkdevfstree(ti);
83#endif
84}
85
86int
87tapeblock_init(void) {
88    int result;
89    tape_frontend_t* blkfront,*temp;
90    tape_info_t* ti;
91
92    tape_init();
93    /* Register the tape major number to the kernel */
94#ifdef CONFIG_DEVFS_FS
95    result = devfs_register_blkdev(tapeblock_major, "tBLK", &tapeblock_fops);
96#else
97    result = register_blkdev(tapeblock_major, "tBLK", &tapeblock_fops);
98#endif
99    if (result < 0) {
100        PRINT_WARN(KERN_ERR "tape: can't get major %d for block device\n", tapeblock_major);
101        panic ("cannot get major number for tape block device");
102    }
103    if (tapeblock_major == 0) tapeblock_major = result;   /* accept dynamic major number*/
104    INIT_BLK_DEV(tapeblock_major,tape_request_fn,tapeblock_getqueue,NULL);
105    read_ahead[tapeblock_major]=TAPEBLOCK_READAHEAD;
106    PRINT_WARN(KERN_ERR " tape gets major %d for block device\n", result);
107    blk_size[tapeblock_major] = (int*) kmalloc (256*sizeof(int),GFP_ATOMIC);
108    memset(blk_size[tapeblock_major],0,256*sizeof(int));
109    blksize_size[tapeblock_major] = (int*) kmalloc (256*sizeof(int),GFP_ATOMIC);
110    memset(blksize_size[tapeblock_major],0,256*sizeof(int));
111    hardsect_size[tapeblock_major] = (int*) kmalloc (256*sizeof(int),GFP_ATOMIC);
112    memset(hardsect_size[tapeblock_major],0,256*sizeof(int));
113    max_sectors[tapeblock_major] = (int*) kmalloc (256*sizeof(int),GFP_ATOMIC);
114    memset(max_sectors[tapeblock_major],0,256*sizeof(int));
115    blkfront = kmalloc(sizeof(tape_frontend_t),GFP_KERNEL);
116    if (blkfront==NULL) panic ("no mem for tape block device structure");
117    blkfront->device_setup=tapeblock_setup;
118#ifdef CONFIG_DEVFS_FS
119    blkfront->mkdevfstree = tapeblock_mkdevfstree;
120    blkfront->rmdevfstree = tapeblock_rmdevfstree;
121#endif
122    blkfront->next=NULL;
123    if (first_frontend==NULL) {
124	first_frontend=blkfront;
125    } else {
126	temp=first_frontend;
127	while (temp->next!=NULL)
128	temp=temp->next;
129	temp->next=blkfront;
130    }
131    ti=first_tape_info;
132    while (ti!=NULL) {
133	tapeblock_setup(ti);
134	ti=ti->next;
135    }
136    return 0;
137}
138
139
140void
141tapeblock_uninit(void) {
142    unregister_blkdev(tapeblock_major, "tBLK");
143}
144
145int
146tapeblock_open(struct inode *inode, struct file *filp) {
147    tape_info_t *ti;
148    kdev_t dev;
149    int rc;
150    long lockflags;
151
152    inode = filp->f_dentry->d_inode;
153    ti = first_tape_info;
154    while ((ti != NULL) && (ti->blk_minor != MINOR (inode->i_rdev)))
155		ti = (tape_info_t *) ti->next;
156	if (ti == NULL)
157		return -ENODEV;
158#ifdef TAPE_DEBUG
159	debug_text_event (tape_debug_area,6,"b:open:");
160	debug_int_event (tape_debug_area,6,ti->blk_minor);
161#endif
162	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
163	if (tapestate_get (ti) != TS_UNUSED) {
164		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
165#ifdef TAPE_DEBUG
166		debug_text_event (tape_debug_area,6,"b:dbusy");
167#endif
168		return -EBUSY;
169	}
170	tapestate_set (ti, TS_IDLE);
171        ti->position=-1;
172
173	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
174        rc=tapeblock_mediumdetect(ti);
175        if (rc) {
176	    s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
177	    tapestate_set (ti, TS_UNUSED);
178	    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
179	    return rc; // in case of errors, we don't have a size of the medium
180	}
181	dev = MKDEV (tapeblock_major, MINOR (inode->i_rdev));	/* Get the device */
182	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
183	ti->blk_filp = filp;
184	filp->private_data = ti;	/* save the dev.info for later reference */
185        ti->cqr=NULL;
186	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
187
188	return 0;
189}
190
191int
192tapeblock_release(struct inode *inode, struct file *filp) {
193	long lockflags;
194	tape_info_t *ti,*lastti;
195	ti = first_tape_info;
196	while ((ti != NULL) && (ti->blk_minor != MINOR (inode->i_rdev)))
197		ti = (tape_info_t *) ti->next;
198	if ((ti != NULL) && (tapestate_get (ti) == TS_NOT_OPER)) {
199	    if (ti==first_tape_info) {
200		first_tape_info=ti->next;
201	    } else {
202		lastti=first_tape_info;
203		while (lastti->next!=ti) lastti=lastti->next;
204		lastti->next=ti->next;
205	    }
206	    kfree(ti);
207	    return 0;
208	}
209	if ((ti == NULL) || (tapestate_get (ti) != TS_IDLE)) {
210#ifdef TAPE_DEBUG
211	debug_text_event (tape_debug_area,3,"b:notidle!");
212#endif
213		return -ENXIO;	/* error in tape_release */
214	}
215#ifdef TAPE_DEBUG
216	debug_text_event (tape_debug_area,6,"b:release:");
217	debug_int_event (tape_debug_area,6,ti->blk_minor);
218#endif
219	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
220	tapestate_set (ti, TS_UNUSED);
221	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
222	invalidate_buffers(inode->i_rdev);
223	return 0;
224}
225
226static void
227tapeblock_end_request(tape_info_t* ti) {
228    struct buffer_head *bh;
229    int uptodate;
230    if ((tapestate_get(ti)!=TS_FAILED) &&
231	(tapestate_get(ti)!=TS_DONE))
232       BUG(); // A request has to be completed to end it
233    uptodate=(tapestate_get(ti)==TS_DONE); // is the buffer up to date?
234#ifdef TAPE_DEBUG
235    if (uptodate) {
236	debug_text_event (tape_debug_area,6,"b:done:");
237	debug_int_event (tape_debug_area,6,(long)ti->cqr);
238    } else {
239	debug_text_event (tape_debug_area,3,"b:failed:");
240	debug_int_event (tape_debug_area,3,(long)ti->cqr);
241    }
242#endif
243    // now inform ll_rw_block about a request status
244    while ((bh = ti->current_request->bh) != NULL) {
245	ti->current_request->bh = bh->b_reqnext;
246	bh->b_reqnext = NULL;
247	bh->b_end_io (bh, uptodate);
248    }
249    if (!end_that_request_first (ti->current_request, uptodate, "tBLK")) {
250#ifndef DEVICE_NO_RANDOM
251	add_blkdev_randomness (MAJOR (ti->current_request->rq_dev));
252#endif
253	end_that_request_last (ti->current_request);
254    }
255    ti->discipline->free_bread(ti->cqr,ti);
256    ti->cqr=NULL;
257    ti->current_request=NULL;
258    if (tapestate_get(ti)!=TS_NOT_OPER) tapestate_set(ti,TS_IDLE);
259    return;
260}
261
262static void
263tapeblock_exec_IO (tape_info_t* ti) {
264    int rc;
265    struct request* req;
266    if (ti->cqr) { // process done/failed request
267	while ((tapestate_get(ti)==TS_FAILED) &&
268	    ti->blk_retries>0) {
269	    ti->blk_retries--;
270	    ti->position=-1;
271	    tapestate_set(ti,TS_BLOCK_INIT);
272#ifdef TAPE_DEBUG
273	    debug_text_event (tape_debug_area,3,"b:retryreq:");
274	    debug_int_event (tape_debug_area,3,(long)ti->cqr);
275#endif
276	    rc = do_IO (ti->devinfo.irq, ti->cqr->cpaddr, (unsigned long) ti->cqr,
277			0x00, ti->cqr->options);
278	    if (rc) {
279#ifdef TAPE_DEBUG
280		debug_text_event (tape_debug_area,3,"b:doIOfail:");
281		debug_int_event (tape_debug_area,3,(long)ti->cqr);
282#endif
283		continue; // one retry lost 'cause doIO failed
284	    }
285	    return;
286	}
287	tapeblock_end_request (ti); // check state, inform user, free mem, dev=idl
288    }
289    if (ti->cqr!=NULL) BUG(); // tape should be idle now, request should be freed!
290    if (tapestate_get (ti) == TS_NOT_OPER) {
291	ti->blk_minor=ti->rew_minor=ti->nor_minor=-1;
292	ti->devinfo.irq=-1;
293	return;
294    }
295#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
296	if (list_empty (&ti->request_queue.queue_head)) {
297#else
298	if (ti->request_queue==NULL) {
299#endif
300	// nothing more to do or device has dissapeared;)
301#ifdef TAPE_DEBUG
302	debug_text_event (tape_debug_area,6,"b:Qempty");
303#endif
304	tapestate_set(ti,TS_IDLE);
305	return;
306    }
307    // queue is not empty, fetch a request and start IO!
308    req=ti->current_request=tape_next_request(&ti->request_queue);
309    if (req==NULL) {
310	BUG(); // Yo. The queue was not reported empy, but no request found. This is _bad_.
311    }
312    if (req->cmd!=READ) { // we only support reading
313	tapestate_set(ti,TS_FAILED);
314	tapeblock_end_request (ti); // check state, inform user, free mem, dev=idl
315	tapestate_set(ti,TS_BLOCK_INIT);
316	schedule_tapeblock_exec_IO(ti);
317	return;
318    }
319    ti->cqr=ti->discipline->bread(req,ti,tapeblock_major); //build channel program from request
320    if (!ti->cqr) {
321	// ccw generation failed. we try again later.
322#ifdef TAPE_DEBUG
323	debug_text_event (tape_debug_area,3,"b:cqrNULL");
324#endif
325	schedule_tapeblock_exec_IO(ti);
326	ti->current_request=NULL;
327	return;
328    }
329    ti->blk_retries = TAPEBLOCK_RETRIES;
330    rc= do_IO (ti->devinfo.irq, ti->cqr->cpaddr,
331	       (unsigned long) ti->cqr, 0x00, ti->cqr->options);
332    if (rc) {
333	// okay. ssch failed. we try later.
334#ifdef TAPE_DEBUG
335	debug_text_event (tape_debug_area,3,"b:doIOfail");
336#endif
337	ti->discipline->free_bread(ti->cqr,ti);
338	ti->cqr=NULL;
339	ti->current_request=NULL;
340	schedule_tapeblock_exec_IO(ti);
341	return;
342    }
343    // our request is in IO. we remove it from the queue and exit
344    tape_dequeue_request (&ti->request_queue,req);
345}
346
347static void
348do_tape_request (request_queue_t * queue) {
349    tape_info_t* ti;
350    long lockflags;
351    for (ti=first_tape_info;
352	 ((ti!=NULL) && ((&ti->request_queue)!=queue));
353	 ti=ti->next);
354    if (ti==NULL) BUG();
355    s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
356    if (tapestate_get(ti)!=TS_IDLE) {
357	s390irq_spin_unlock_irqrestore(ti->devinfo.irq,lockflags);
358	return;
359    }
360    if (tapestate_get(ti)!=TS_IDLE) BUG();
361    tapestate_set(ti,TS_BLOCK_INIT);
362    tapeblock_exec_IO(ti);
363    s390irq_spin_unlock_irqrestore(ti->devinfo.irq,lockflags);
364}
365
366static void
367run_tapeblock_exec_IO (tape_info_t* ti) {
368    long flags_390irq,flags_ior;
369    spin_lock_irqsave (&io_request_lock, flags_ior);
370    s390irq_spin_lock_irqsave(ti->devinfo.irq,flags_390irq);
371    atomic_set(&ti->bh_scheduled,0);
372    tapeblock_exec_IO(ti);
373    s390irq_spin_unlock_irqrestore(ti->devinfo.irq,flags_390irq);
374    spin_unlock_irqrestore (&io_request_lock, flags_ior);
375}
376
377void
378schedule_tapeblock_exec_IO (tape_info_t *ti)
379{
380	/* Protect against rescheduling, when already running */
381        if (atomic_compare_and_swap(0,1,&ti->bh_scheduled)) {
382                return;
383        }
384#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
385	INIT_LIST_HEAD(&ti->bh_tq.list);
386#endif
387	ti->bh_tq.sync = 0;
388	ti->bh_tq.routine = (void *) (void *) run_tapeblock_exec_IO;
389	ti->bh_tq.data = ti;
390
391	queue_task (&ti->bh_tq, &tq_immediate);
392	mark_bh (IMMEDIATE_BH);
393	return;
394}
395
396/* wrappers around do_tape_request for different kernel versions */
397#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98))
398static void tape_request_fn (void) {
399    tape_info_t* ti=first_tape_info;
400    while (ti!=NULL) {
401	do_tape_request(&ti->request_queue);
402	ti=ti->next;
403    }
404}
405#else
406static void  tape_request_fn (request_queue_t* queue) {
407    do_tape_request(queue);
408}
409#endif
410
411static request_queue_t* tapeblock_getqueue (kdev_t kdev) {
412    tape_info_t* ti=first_tape_info;
413    while ((ti!=NULL) && (MINOR(kdev)!=ti->blk_minor))
414        ti=ti->next;
415    if (ti!=NULL) return &ti->request_queue;
416    return NULL;
417}
418
419int tapeblock_mediumdetect(tape_info_t* ti) {
420        ccw_req_t* cqr;
421    int losize=1,hisize=1,rc;
422    long lockflags;
423#ifdef TAPE_DEBUG
424    debug_text_event (tape_debug_area,3,"b:medDet");
425#endif
426    PRINT_WARN("Detecting media size. This will take _long_, so get yourself a coffee...\n");
427    while (1) { //is interruped by break
428	hisize=hisize << 1; // try twice the size tested before
429	cqr=ti->discipline->mtseek (ti, hisize);
430	if (cqr == NULL) {
431#ifdef TAPE_DEBUG
432	    debug_text_event (tape_debug_area,6,"b:ccwg fail");
433#endif
434	    return -ENOSPC;
435	}
436	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
437	ti->cqr = cqr;
438	ti->wanna_wakeup=0;
439	rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
440	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
441	if (rc) return -EIO;
442	wait_event_interruptible (ti->wq,ti->wanna_wakeup);
443	ti->cqr = NULL;
444	tape_free_request (cqr);
445	if (ti->kernbuf) {
446	    kfree (ti->kernbuf);
447	    ti->kernbuf=NULL;
448	}
449	if (signal_pending (current)) {
450		tapestate_set (ti, TS_IDLE);
451		return -ERESTARTSYS;
452	}
453	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
454	if (tapestate_get (ti) == TS_FAILED) {
455		tapestate_set (ti, TS_IDLE);
456		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
457		break;
458	}
459	if (tapestate_get (ti) == TS_NOT_OPER) {
460	    ti->blk_minor=ti->rew_minor=ti->nor_minor=-1;
461	    ti->devinfo.irq=-1;
462	    s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags);
463	    return -ENODEV;
464	}
465	if (tapestate_get (ti) != TS_DONE) {
466		tapestate_set (ti, TS_IDLE);
467		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
468		return -EIO;
469	}
470	tapestate_set (ti, TS_IDLE);
471	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
472	losize=hisize;
473    }
474    cqr = ti->discipline->mtrew (ti, 1);
475    if (cqr == NULL) {
476#ifdef TAPE_DEBUG
477	debug_text_event (tape_debug_area,6,"b:ccwg fail");
478#endif
479	return -ENOSPC;
480    }
481    s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
482    ti->cqr = cqr;
483    ti->wanna_wakeup=0;
484    rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
485    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
486    wait_event_interruptible (ti->wq,ti->wanna_wakeup);
487    ti->cqr = NULL;
488    tape_free_request (cqr);
489    if (signal_pending (current)) {
490	tapestate_set (ti, TS_IDLE);
491	return -ERESTARTSYS;
492    }
493    s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
494    if (tapestate_get (ti) == TS_FAILED) {
495	tapestate_set (ti, TS_IDLE);
496	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
497	return -EIO;
498    }
499    if (tapestate_get (ti) == TS_NOT_OPER) {
500	ti->blk_minor=ti->rew_minor=ti->nor_minor=-1;
501	ti->devinfo.irq=-1;
502	s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags);
503	return -ENODEV;
504    }
505    if (tapestate_get (ti) != TS_DONE) {
506	tapestate_set (ti, TS_IDLE);
507	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
508	return -EIO;
509    }
510    tapestate_set (ti, TS_IDLE);
511    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
512    while (losize!=hisize) {
513	cqr=ti->discipline->mtseek (ti, (hisize+losize)/2+1);
514	if (cqr == NULL) {
515#ifdef TAPE_DEBUG
516	    debug_text_event (tape_debug_area,6,"b:ccwg fail");
517#endif
518	    return -ENOSPC;
519	}
520	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
521	ti->cqr = cqr;
522	ti->wanna_wakeup=0;
523	rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
524	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
525	if (rc) return -EIO;
526	wait_event_interruptible (ti->wq,ti->wanna_wakeup);
527	ti->cqr = NULL;
528	tape_free_request (cqr);
529	if (ti->kernbuf) {
530	    kfree (ti->kernbuf);
531	    ti->kernbuf=NULL;
532	}
533	if (signal_pending (current)) {
534		tapestate_set (ti, TS_IDLE);
535		return -ERESTARTSYS;
536	}
537	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
538	if (tapestate_get (ti) == TS_NOT_OPER) {
539	    ti->blk_minor=ti->rew_minor=ti->nor_minor=-1;
540	    ti->devinfo.irq=-1;
541	    s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags);
542	    return -ENODEV;
543	}
544	if (tapestate_get (ti) == TS_FAILED) {
545		tapestate_set (ti, TS_IDLE);
546		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
547		hisize=(hisize+losize)/2;
548		cqr = ti->discipline->mtrew (ti, 1);
549		if (cqr == NULL) {
550#ifdef TAPE_DEBUG
551		    debug_text_event (tape_debug_area,6,"b:ccwg fail");
552#endif
553		    return -ENOSPC;
554		}
555		s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
556		ti->cqr = cqr;
557		ti->wanna_wakeup=0;
558		rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
559		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
560		wait_event_interruptible (ti->wq,ti->wanna_wakeup);
561		ti->cqr = NULL;
562		tape_free_request (cqr);
563		if (signal_pending (current)) {
564		    tapestate_set (ti, TS_IDLE);
565		    return -ERESTARTSYS;
566		}
567		s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
568		if (tapestate_get (ti) == TS_FAILED) {
569		    tapestate_set (ti, TS_IDLE);
570		    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
571		    return -EIO;
572		}
573		if (tapestate_get (ti) != TS_DONE) {
574		    tapestate_set (ti, TS_IDLE);
575		    s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
576		    return -EIO;
577		}
578		tapestate_set (ti, TS_IDLE);
579		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
580		continue;
581	}
582	if (tapestate_get (ti) != TS_DONE) {
583		tapestate_set (ti, TS_IDLE);
584		s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
585		return -EIO;
586	}
587	tapestate_set (ti, TS_IDLE);
588	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
589	losize=(hisize+losize)/2+1;
590    }
591    blk_size[tapeblock_major][ti->blk_minor]=(losize)*(blksize_size[tapeblock_major][ti->blk_minor]/1024);
592    return 0;
593}
594