File: /usr/src/linux/drivers/s390/char/tapeblock.c

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