2 /***************************************************************************
4 * drivers/s390/char/tapeblock.c
5 * block device frontend for tape device driver
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>
13 ****************************************************************************
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>
27 #define __NO_VERSION__
28 #include <linux/module.h>
31 #include "tapeblock.h"
33 #define PRINTK_HEADER "TBLOCK:"
36 * file operation structure for tape devices
38 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
39 static struct block_device_operations tapeblock_fops = {
41 static struct file_operations tapeblock_fops = {
44 open : tapeblock_open, /* open */
45 release : tapeblock_release, /* release */
48 int tapeblock_major = 0;
50 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
51 static void tape_request_fn (request_queue_t * queue);
53 static void tape_request_fn (void);
56 static request_queue_t* tapeblock_getqueue (kdev_t kdev);
58 #ifdef CONFIG_DEVFS_FS
60 tapeblock_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);
68 tapeblock_rmdevfstree (tape_info_t* ti) {
69 devfs_unregister(ti->devfs_disc);
70 devfs_unregister(ti->devfs_block_dir);
75 tapeblock_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);
87 tapeblock_init(void) {
89 tape_frontend_t* blkfront,*temp;
93 /* Register the tape major number to the kernel */
94 #ifdef CONFIG_DEVFS_FS
95 result = devfs_register_blkdev(tapeblock_major, "tBLK", &tapeblock_fops);
97 result = register_blkdev(tapeblock_major, "tBLK", &tapeblock_fops);
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");
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;
123 if (first_frontend==NULL) {
124 first_frontend=blkfront;
127 while (temp->next!=NULL)
141 tapeblock_uninit(void) {
142 unregister_blkdev(tapeblock_major, "tBLK");
146 tapeblock_open(struct inode *inode, struct file *filp) {
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;
159 debug_text_event (tape_debug_area,6,"b:open:");
160 debug_int_event (tape_debug_area,6,ti->blk_minor);
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);
166 debug_text_event (tape_debug_area,6,"b:dbusy");
170 tapestate_set (ti, TS_IDLE);
173 s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
174 rc=tapeblock_mediumdetect(ti);
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
181 dev = MKDEV (tapeblock_major, MINOR (inode->i_rdev)); /* Get the device */
182 s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
184 filp->private_data = ti; /* save the dev.info for later reference */
186 s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
192 tapeblock_release(struct inode *inode, struct file *filp) {
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;
202 lastti=first_tape_info;
203 while (lastti->next!=ti) lastti=lastti->next;
204 lastti->next=ti->next;
209 if ((ti == NULL) || (tapestate_get (ti) != TS_IDLE)) {
211 debug_text_event (tape_debug_area,3,"b:notidle!");
213 return -ENXIO; /* error in tape_release */
216 debug_text_event (tape_debug_area,6,"b:release:");
217 debug_int_event (tape_debug_area,6,ti->blk_minor);
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);
227 tapeblock_end_request(tape_info_t* ti) {
228 struct buffer_head *bh;
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?
236 debug_text_event (tape_debug_area,6,"b:done:");
237 debug_int_event (tape_debug_area,6,(long)ti->cqr);
239 debug_text_event (tape_debug_area,3,"b:failed:");
240 debug_int_event (tape_debug_area,3,(long)ti->cqr);
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);
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));
253 end_that_request_last (ti->current_request);
255 ti->discipline->free_bread(ti->cqr,ti);
257 ti->current_request=NULL;
258 if (tapestate_get(ti)!=TS_NOT_OPER) tapestate_set(ti,TS_IDLE);
263 tapeblock_exec_IO (tape_info_t* ti) {
266 if (ti->cqr) { // process done/failed request
267 while ((tapestate_get(ti)==TS_FAILED) &&
271 tapestate_set(ti,TS_BLOCK_INIT);
273 debug_text_event (tape_debug_area,3,"b:retryreq:");
274 debug_int_event (tape_debug_area,3,(long)ti->cqr);
276 rc = do_IO (ti->devinfo.irq, ti->cqr->cpaddr, (unsigned long) ti->cqr,
277 0x00, ti->cqr->options);
280 debug_text_event (tape_debug_area,3,"b:doIOfail:");
281 debug_int_event (tape_debug_area,3,(long)ti->cqr);
283 continue; // one retry lost 'cause doIO failed
287 tapeblock_end_request (ti); // check state, inform user, free mem, dev=idl
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;
295 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
296 if (list_empty (&ti->request_queue.queue_head)) {
298 if (ti->request_queue==NULL) {
300 // nothing more to do or device has dissapeared;)
302 debug_text_event (tape_debug_area,6,"b:Qempty");
304 tapestate_set(ti,TS_IDLE);
307 // queue is not empty, fetch a request and start IO!
308 req=ti->current_request=tape_next_request(&ti->request_queue);
310 BUG(); // Yo. The queue was not reported empy, but no request found. This is _bad_.
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);
319 ti->cqr=ti->discipline->bread(req,ti,tapeblock_major); //build channel program from request
321 // ccw generation failed. we try again later.
323 debug_text_event (tape_debug_area,3,"b:cqrNULL");
325 schedule_tapeblock_exec_IO(ti);
326 ti->current_request=NULL;
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);
333 // okay. ssch failed. we try later.
335 debug_text_event (tape_debug_area,3,"b:doIOfail");
337 ti->discipline->free_bread(ti->cqr,ti);
339 ti->current_request=NULL;
340 schedule_tapeblock_exec_IO(ti);
343 // our request is in IO. we remove it from the queue and exit
344 tape_dequeue_request (&ti->request_queue,req);
348 do_tape_request (request_queue_t * queue) {
351 for (ti=first_tape_info;
352 ((ti!=NULL) && ((&ti->request_queue)!=queue));
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);
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);
367 run_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);
378 schedule_tapeblock_exec_IO (tape_info_t *ti)
380 /* Protect against rescheduling, when already running */
381 if (atomic_compare_and_swap(0,1,&ti->bh_scheduled)) {
384 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
385 INIT_LIST_HEAD(&ti->bh_tq.list);
388 ti->bh_tq.routine = (void *) (void *) run_tapeblock_exec_IO;
391 queue_task (&ti->bh_tq, &tq_immediate);
392 mark_bh (IMMEDIATE_BH);
396 /* wrappers around do_tape_request for different kernel versions */
397 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,98))
398 static void tape_request_fn (void) {
399 tape_info_t* ti=first_tape_info;
401 do_tape_request(&ti->request_queue);
406 static void tape_request_fn (request_queue_t* queue) {
407 do_tape_request(queue);
411 static 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))
415 if (ti!=NULL) return &ti->request_queue;
419 int tapeblock_mediumdetect(tape_info_t* ti) {
421 int losize=1,hisize=1,rc;
424 debug_text_event (tape_debug_area,3,"b:medDet");
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);
432 debug_text_event (tape_debug_area,6,"b:ccwg fail");
436 s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
439 rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
440 s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
442 wait_event_interruptible (ti->wq,ti->wanna_wakeup);
444 tape_free_request (cqr);
449 if (signal_pending (current)) {
450 tapestate_set (ti, TS_IDLE);
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);
459 if (tapestate_get (ti) == TS_NOT_OPER) {
460 ti->blk_minor=ti->rew_minor=ti->nor_minor=-1;
462 s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags);
465 if (tapestate_get (ti) != TS_DONE) {
466 tapestate_set (ti, TS_IDLE);
467 s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
470 tapestate_set (ti, TS_IDLE);
471 s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
474 cqr = ti->discipline->mtrew (ti, 1);
477 debug_text_event (tape_debug_area,6,"b:ccwg fail");
481 s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
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);
488 tape_free_request (cqr);
489 if (signal_pending (current)) {
490 tapestate_set (ti, TS_IDLE);
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);
499 if (tapestate_get (ti) == TS_NOT_OPER) {
500 ti->blk_minor=ti->rew_minor=ti->nor_minor=-1;
502 s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags);
505 if (tapestate_get (ti) != TS_DONE) {
506 tapestate_set (ti, TS_IDLE);
507 s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
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);
516 debug_text_event (tape_debug_area,6,"b:ccwg fail");
520 s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
523 rc = do_IO (ti->devinfo.irq, cqr->cpaddr, (unsigned long) cqr, 0x00, cqr->options);
524 s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
526 wait_event_interruptible (ti->wq,ti->wanna_wakeup);
528 tape_free_request (cqr);
533 if (signal_pending (current)) {
534 tapestate_set (ti, TS_IDLE);
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;
541 s390irq_spin_unlock_irqrestore (ti->devinfo.irq,lockflags);
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);
551 debug_text_event (tape_debug_area,6,"b:ccwg fail");
555 s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
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);
562 tape_free_request (cqr);
563 if (signal_pending (current)) {
564 tapestate_set (ti, TS_IDLE);
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);
573 if (tapestate_get (ti) != TS_DONE) {
574 tapestate_set (ti, TS_IDLE);
575 s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
578 tapestate_set (ti, TS_IDLE);
579 s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
582 if (tapestate_get (ti) != TS_DONE) {
583 tapestate_set (ti, TS_IDLE);
584 s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
587 tapestate_set (ti, TS_IDLE);
588 s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
589 losize=(hisize+losize)/2+1;
591 blk_size[tapeblock_major][ti->blk_minor]=(losize)*(blksize_size[tapeblock_major][ti->blk_minor]/1024);