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