+- add patches.fixes/linux-post-2.6.3-20040220
[linux-flexiantxendom0-3.2.10.git] / drivers / s390 / char / tape_core.c
1 /*
2  *  drivers/s390/char/tape_core.c
3  *    basic function of the tape device driver
4  *
5  *  S390 and zSeries version
6  *    Copyright (C) 2001,2002 IBM Deutschland Entwicklung GmbH, IBM Corporation
7  *    Author(s): Carsten Otte <cotte@de.ibm.com>
8  *               Michael Holzheu <holzheu@de.ibm.com>
9  *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
10  *               Martin Schwidefsky <schwidefsky@de.ibm.com>
11  */
12
13 #include <linux/config.h>
14 #include <linux/module.h>
15 #include <linux/init.h>      // for kernel parameters
16 #include <linux/kmod.h>      // for requesting modules
17 #include <linux/spinlock.h>  // for locks
18 #include <linux/vmalloc.h>
19 #include <linux/list.h>
20
21 #include <asm/types.h>       // for variable types
22
23 #include "tape.h"
24 #include "tape_std.h"
25
26 #define PRINTK_HEADER "TAPE_CORE: "
27
28 static void __tape_do_irq (struct ccw_device *, unsigned long, struct irb *);
29 static void __tape_remove_request(struct tape_device *, struct tape_request *);
30
31 /*
32  * One list to contain all tape devices of all disciplines, so
33  * we can assign the devices to minor numbers of the same major
34  * The list is protected by the rwlock
35  */
36 static struct list_head tape_device_list = LIST_HEAD_INIT(tape_device_list);
37 static rwlock_t tape_device_lock = RW_LOCK_UNLOCKED;
38
39 /*
40  * Pointer to debug area.
41  */
42 debug_info_t *tape_dbf_area = NULL;
43
44 /*
45  * Printable strings for tape enumerations.
46  */
47 const char *tape_state_verbose[TS_SIZE] =
48 {
49         [TS_UNUSED]   = "UNUSED",
50         [TS_IN_USE]   = "IN_USE",
51         [TS_BLKUSE]   = "BLKUSE",
52         [TS_INIT]     = "INIT  ",
53         [TS_NOT_OPER] = "NOT_OP"
54 };
55
56 const char *tape_op_verbose[TO_SIZE] =
57 {
58         [TO_BLOCK] = "BLK",     [TO_BSB] = "BSB",
59         [TO_BSF] = "BSF",       [TO_DSE] = "DSE",
60         [TO_FSB] = "FSB",       [TO_FSF] = "FSF",
61         [TO_LBL] = "LBL",       [TO_NOP] = "NOP",
62         [TO_RBA] = "RBA",       [TO_RBI] = "RBI",
63         [TO_RFO] = "RFO",       [TO_REW] = "REW",
64         [TO_RUN] = "RUN",       [TO_WRI] = "WRI",
65         [TO_WTM] = "WTM",       [TO_MSEN] = "MSN",
66         [TO_LOAD] = "LOA",      [TO_READ_CONFIG] = "RCF",
67         [TO_READ_ATTMSG] = "RAT",
68         [TO_DIS] = "DIS",       [TO_ASSIGN] = "ASS",
69         [TO_UNASSIGN] = "UAS"
70 };
71
72 /*
73  * Some channel attached tape specific attributes.
74  *
75  * FIXME: In the future the first_minor and blocksize attribute should be
76  *        replaced by a link to the cdev tree.
77  */
78 static ssize_t
79 tape_medium_state_show(struct device *dev, char *buf)
80 {
81         struct tape_device *tdev;
82
83         tdev = (struct tape_device *) dev->driver_data;
84         return scnprintf(buf, PAGE_SIZE, "%i\n", tdev->medium_state);
85 }
86
87 static
88 DEVICE_ATTR(medium_state, 0444, tape_medium_state_show, NULL);
89
90 static ssize_t
91 tape_first_minor_show(struct device *dev, char *buf)
92 {
93         struct tape_device *tdev;
94
95         tdev = (struct tape_device *) dev->driver_data;
96         return scnprintf(buf, PAGE_SIZE, "%i\n", tdev->first_minor);
97 }
98
99 static
100 DEVICE_ATTR(first_minor, 0444, tape_first_minor_show, NULL);
101
102 static ssize_t
103 tape_state_show(struct device *dev, char *buf)
104 {
105         struct tape_device *tdev;
106
107         tdev = (struct tape_device *) dev->driver_data;
108         return scnprintf(buf, PAGE_SIZE, "%s\n", (tdev->first_minor < 0) ?
109                 "OFFLINE" : tape_state_verbose[tdev->tape_state]);
110 }
111
112 static
113 DEVICE_ATTR(state, 0444, tape_state_show, NULL);
114
115 static ssize_t
116 tape_operation_show(struct device *dev, char *buf)
117 {
118         struct tape_device *tdev;
119         ssize_t rc;
120
121         tdev = (struct tape_device *) dev->driver_data;
122         if (tdev->first_minor < 0)
123                 return scnprintf(buf, PAGE_SIZE, "N/A\n");
124
125         spin_lock_irq(get_ccwdev_lock(tdev->cdev));
126         if (list_empty(&tdev->req_queue))
127                 rc = scnprintf(buf, PAGE_SIZE, "---\n");
128         else {
129                 struct tape_request *req;
130
131                 req = list_entry(tdev->req_queue.next, struct tape_request,
132                         list);
133                 rc = scnprintf(buf,PAGE_SIZE, "%s\n", tape_op_verbose[req->op]);
134         }
135         spin_unlock_irq(get_ccwdev_lock(tdev->cdev));
136         return rc;
137 }
138
139 static
140 DEVICE_ATTR(operation, 0444, tape_operation_show, NULL);
141
142 static ssize_t
143 tape_blocksize_show(struct device *dev, char *buf)
144 {
145         struct tape_device *tdev;
146
147         tdev = (struct tape_device *) dev->driver_data;
148
149         return scnprintf(buf, PAGE_SIZE, "%i\n", tdev->char_data.block_size);
150 }
151
152 static
153 DEVICE_ATTR(blocksize, 0444, tape_blocksize_show, NULL);
154
155 static struct attribute *tape_attrs[] = {
156         &dev_attr_medium_state.attr,
157         &dev_attr_first_minor.attr,
158         &dev_attr_state.attr,
159         &dev_attr_operation.attr,
160         &dev_attr_blocksize.attr,
161         NULL
162 };
163
164 static struct attribute_group tape_attr_group = {
165         .attrs = tape_attrs,
166 };
167
168 /*
169  * Tape state functions
170  */
171 void
172 tape_state_set(struct tape_device *device, enum tape_state newstate)
173 {
174         const char *str;
175
176         if (device->tape_state == TS_NOT_OPER) {
177                 DBF_EVENT(3, "ts_set err: not oper\n");
178                 return;
179         }
180         DBF_EVENT(4, "ts. dev:  %x\n", device->first_minor);
181         if (device->tape_state < TO_SIZE && device->tape_state >= 0)
182                 str = tape_state_verbose[device->tape_state];
183         else
184                 str = "UNKNOWN TS";
185         DBF_EVENT(4, "old ts:   %s\n", str);
186         if (device->tape_state < TO_SIZE && device->tape_state >=0 )
187                 str = tape_state_verbose[device->tape_state];
188         else
189                 str = "UNKNOWN TS";
190         DBF_EVENT(4, "%s\n", str);
191         DBF_EVENT(4, "new ts:\t\n");
192         if (newstate < TO_SIZE && newstate >= 0)
193                 str = tape_state_verbose[newstate];
194         else
195                 str = "UNKNOWN TS";
196         DBF_EVENT(4, "%s\n", str);
197         device->tape_state = newstate;
198         wake_up(&device->state_change_wq);
199 }
200
201 void
202 tape_med_state_set(struct tape_device *device, enum tape_medium_state newstate)
203 {
204         if (device->medium_state == newstate)
205                 return;
206         switch(newstate){
207         case MS_UNLOADED:
208                 device->tape_generic_status |= GMT_DR_OPEN(~0);
209                 PRINT_INFO("(%s): Tape is unloaded\n",
210                            device->cdev->dev.bus_id);
211                 break;
212         case MS_LOADED:
213                 device->tape_generic_status &= ~GMT_DR_OPEN(~0);
214                 PRINT_INFO("(%s): Tape has been mounted\n",
215                            device->cdev->dev.bus_id);
216                 break;
217         default:
218                 // print nothing
219                 break;
220         }
221         device->medium_state = newstate;
222         wake_up(&device->state_change_wq);
223 }
224
225 /*
226  * Stop running ccw. Has to be called with the device lock held.
227  */
228 static inline int
229 __tape_halt_io(struct tape_device *device, struct tape_request *request)
230 {
231         int retries;
232         int rc;
233
234         /* Check if interrupt has already been processed */
235         if (request->callback == NULL)
236                 return 0;
237
238         rc = 0;
239         for (retries = 0; retries < 5; retries++) {
240                 if (retries < 2)
241                         rc = ccw_device_halt(device->cdev, (long) request);
242                 else
243                         rc = ccw_device_clear(device->cdev, (long) request);
244
245                 if (rc == 0) {                     /* Termination successful */
246                         request->rc     = -EIO;
247                         request->status = TAPE_REQUEST_DONE;
248                         return 0;
249                 }
250
251                 if (rc == -ENODEV)
252                         DBF_EXCEPTION(2, "device gone, retry\n");
253                 else if (rc == -EIO)
254                         DBF_EXCEPTION(2, "I/O error, retry\n");
255                 else if (rc == -EBUSY)
256                         DBF_EXCEPTION(2, "device busy, retry late\n");
257                 else
258                         BUG();
259         }
260
261         return rc;
262 }
263
264 /*
265  * Add device into the sorted list, giving it the first
266  * available minor number.
267  */
268 static int
269 tape_assign_minor(struct tape_device *device)
270 {
271         struct tape_device *tmp;
272         int minor;
273
274         minor = 0;
275         write_lock(&tape_device_lock);
276         list_for_each_entry(tmp, &tape_device_list, node) {
277                 if (minor < tmp->first_minor)
278                         break;
279                 minor += TAPE_MINORS_PER_DEV;
280         }
281         if (minor >= 256) {
282                 write_unlock(&tape_device_lock);
283                 return -ENODEV;
284         }
285         device->first_minor = minor;
286         list_add_tail(&device->node, &tmp->node);
287         write_unlock(&tape_device_lock);
288         return 0;
289 }
290
291 /* remove device from the list */
292 static void
293 tape_remove_minor(struct tape_device *device)
294 {
295         write_lock(&tape_device_lock);
296         list_del_init(&device->node);
297         device->first_minor = -1;
298         write_unlock(&tape_device_lock);
299 }
300
301 /*
302  * Enable tape device
303  */
304 int
305 tape_enable_device(struct tape_device *device,
306                    struct tape_discipline *discipline)
307 {
308         int rc;
309
310         DBF_LH(6, "tape_enable_device(%p, %p)\n", device, discipline);
311
312         if (device->tape_state != TS_INIT) {
313                 DBF_LH(3, "Tapestate not INIT (%d)\n", device->tape_state);
314                 return -EINVAL;
315         }
316
317         /* Let the discipline have a go at the device. */
318         device->discipline = discipline;
319         rc = discipline->setup_device(device);
320         if (rc)
321                 goto out;
322         rc = tape_assign_minor(device);
323         if (rc)
324                 goto out_discipline;
325
326         rc = tapechar_setup_device(device);
327         if (rc)
328                 goto out_minor;
329         rc = tapeblock_setup_device(device);
330         if (rc)
331                 goto out_char;
332
333         tape_state_set(device, TS_UNUSED);
334         return 0;
335
336 out_char:
337         tapechar_cleanup_device(device);
338 out_discipline:
339         device->discipline->cleanup_device(device);
340         device->discipline = NULL;
341 out_minor:
342         tape_remove_minor(device);
343 out:
344         return rc;
345 }
346
347 /*
348  * Disable tape device. Check if there is a running request and
349  * terminate it. Post all queued requests with -EIO.
350  */
351 void
352 tape_disable_device(struct tape_device *device)
353 {
354         struct list_head *l, *n;
355         struct tape_request *request;
356
357         spin_lock_irq(get_ccwdev_lock(device->cdev));
358         /* Post remaining requests with -EIO */
359         list_for_each_safe(l, n, &device->req_queue) {
360                 request = list_entry(l, struct tape_request, list);
361                 if (request->status == TAPE_REQUEST_IN_IO)
362                         __tape_halt_io(device, request);
363                 list_del(&request->list);
364                 /* Decrease ref_count for removed request. */
365                 request->device = tape_put_device(device);
366                 request->rc = -EIO;
367                 if (request->callback != NULL)
368                         request->callback(request, request->callback_data);
369         }
370         spin_unlock_irq(get_ccwdev_lock(device->cdev));
371
372         tapeblock_cleanup_device(device);
373         tapechar_cleanup_device(device);
374         device->discipline->cleanup_device(device);
375         tape_remove_minor(device);
376
377         tape_med_state_set(device, MS_UNKNOWN);
378         device->tape_state = TS_INIT;
379 }
380
381 /*
382  * Allocate memory for a new device structure.
383  */
384 static struct tape_device *
385 tape_alloc_device(void)
386 {
387         struct tape_device *device;
388
389         device = (struct tape_device *)
390                 kmalloc(sizeof(struct tape_device), GFP_KERNEL);
391         if (device == NULL) {
392                 DBF_EXCEPTION(2, "ti:no mem\n");
393                 PRINT_INFO ("can't allocate memory for "
394                             "tape info structure\n");
395                 return ERR_PTR(-ENOMEM);
396         }
397         memset(device, 0, sizeof(struct tape_device));
398         device->modeset_byte = (char *) kmalloc(1, GFP_KERNEL | GFP_DMA);
399         if (device->modeset_byte == NULL) {
400                 DBF_EXCEPTION(2, "ti:no mem\n");
401                 PRINT_INFO("can't allocate memory for modeset byte\n");
402                 kfree(device);
403                 return ERR_PTR(-ENOMEM);
404         }
405         INIT_LIST_HEAD(&device->req_queue);
406         INIT_LIST_HEAD(&device->node);
407         init_waitqueue_head(&device->state_change_wq);
408         device->tape_state = TS_INIT;
409         device->medium_state = MS_UNKNOWN;
410         *device->modeset_byte = 0;
411         device->first_minor = -1;
412         atomic_set(&device->ref_count, 1);
413
414         return device;
415 }
416
417 /*
418  * Get a reference to an existing device structure. This will automatically
419  * increment the reference count.
420  */
421 struct tape_device *
422 tape_get_device_reference(struct tape_device *device)
423 {
424         DBF_EVENT(4, "tape_get_device_reference(%p) = %i\n", device,
425                 atomic_inc_return(&device->ref_count));
426
427         return device;
428 }
429
430 /*
431  * Decrease the reference counter of a devices structure. If the
432  * reference counter reaches zero free the device structure.
433  * The function returns a NULL pointer to be used by the caller
434  * for clearing reference pointers.
435  */
436 struct tape_device *
437 tape_put_device(struct tape_device *device)
438 {
439         int remain;
440
441         remain = atomic_dec_return(&device->ref_count);
442         if (remain > 0) {
443                 DBF_EVENT(4, "tape_put_device(%p) -> %i\n", device, remain);
444         } else {
445                 if (remain < 0) {
446                         DBF_EVENT(4, "put device without reference\n");
447                         PRINT_ERR("put device without reference\n");
448                 } else {
449                         DBF_EVENT(4, "tape_free_device(%p)\n", device);
450                         kfree(device->modeset_byte);
451                         kfree(device);
452                 }
453         }
454
455         return NULL;                    
456 }
457
458 /*
459  * Find tape device by a device index.
460  */
461 struct tape_device *
462 tape_get_device(int devindex)
463 {
464         struct tape_device *device, *tmp;
465
466         device = ERR_PTR(-ENODEV);
467         read_lock(&tape_device_lock);
468         list_for_each_entry(tmp, &tape_device_list, node) {
469                 if (tmp->first_minor / TAPE_MINORS_PER_DEV == devindex) {
470                         device = tape_get_device_reference(tmp);
471                         break;
472                 }
473         }
474         read_unlock(&tape_device_lock);
475         return device;
476 }
477
478 /*
479  * Driverfs tape probe function.
480  */
481 int
482 tape_generic_probe(struct ccw_device *cdev)
483 {
484         struct tape_device *device;
485         char *bus_id = cdev->dev.bus_id;
486
487         device = tape_alloc_device();
488         if (IS_ERR(device))
489                 return -ENODEV;
490         PRINT_INFO("tape device %s found\n", bus_id);
491         cdev->dev.driver_data = device;
492         device->cdev = cdev;
493         cdev->handler = __tape_do_irq;
494
495         ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP);
496         sysfs_create_group(&cdev->dev.kobj, &tape_attr_group);
497
498         return 0;
499 }
500
501 /*
502  * Driverfs tape remove function.
503  */
504 void
505 tape_generic_remove(struct ccw_device *cdev)
506 {
507         ccw_device_set_offline(cdev);
508         if (cdev->dev.driver_data != NULL) {
509                 sysfs_remove_group(&cdev->dev.kobj, &tape_attr_group);
510                 cdev->dev.driver_data = tape_put_device(cdev->dev.driver_data);
511         }
512 }
513
514 /*
515  * Allocate a new tape ccw request
516  */
517 struct tape_request *
518 tape_alloc_request(int cplength, int datasize)
519 {
520         struct tape_request *request;
521
522         if (datasize > PAGE_SIZE || (cplength*sizeof(struct ccw1)) > PAGE_SIZE)
523                 BUG();
524
525         DBF_LH(6, "tape_alloc_request(%d, %d)\n", cplength, datasize);
526
527         request = (struct tape_request *) kmalloc(sizeof(struct tape_request),
528                                                   GFP_KERNEL);
529         if (request == NULL) {
530                 DBF_EXCEPTION(1, "cqra nomem\n");
531                 return ERR_PTR(-ENOMEM);
532         }
533         memset(request, 0, sizeof(struct tape_request));
534         /* allocate channel program */
535         if (cplength > 0) {
536                 request->cpaddr = kmalloc(cplength*sizeof(struct ccw1),
537                                           GFP_ATOMIC | GFP_DMA);
538                 if (request->cpaddr == NULL) {
539                         DBF_EXCEPTION(1, "cqra nomem\n");
540                         kfree(request);
541                         return ERR_PTR(-ENOMEM);
542                 }
543                 memset(request->cpaddr, 0, cplength*sizeof(struct ccw1));
544         }
545         /* alloc small kernel buffer */
546         if (datasize > 0) {
547                 request->cpdata = kmalloc(datasize, GFP_KERNEL | GFP_DMA);
548                 if (request->cpdata == NULL) {
549                         DBF_EXCEPTION(1, "cqra nomem\n");
550                         if (request->cpaddr != NULL)
551                                 kfree(request->cpaddr);
552                         kfree(request);
553                         return ERR_PTR(-ENOMEM);
554                 }
555                 memset(request->cpdata, 0, datasize);
556         }
557         DBF_LH(6, "New request %p(%p/%p)\n", request, request->cpaddr,
558                 request->cpdata);
559
560         return request;
561 }
562
563 /*
564  * Free tape ccw request
565  */
566 void
567 tape_free_request (struct tape_request * request)
568 {
569         DBF_LH(6, "Free request %p\n", request);
570
571         if (request->device != NULL) {
572                 request->device = tape_put_device(request->device);
573         }
574         if (request->cpdata != NULL)
575                 kfree(request->cpdata);
576         if (request->cpaddr != NULL)
577                 kfree(request->cpaddr);
578         kfree(request);
579 }
580
581 static inline void
582 __tape_do_io_list(struct tape_device *device)
583 {
584         struct list_head *l, *n;
585         struct tape_request *request;
586         int rc;
587
588         DBF_LH(6, "__tape_do_io_list(%p)\n", device);
589         /*
590          * Try to start each request on request queue until one is
591          * started successful.
592          */
593         list_for_each_safe(l, n, &device->req_queue) {
594                 request = list_entry(l, struct tape_request, list);
595 #ifdef CONFIG_S390_TAPE_BLOCK
596                 if (request->op == TO_BLOCK)
597                         device->discipline->check_locate(device, request);
598 #endif
599                 rc = ccw_device_start(device->cdev, request->cpaddr,
600                                       (unsigned long) request, 0x00,
601                                       request->options);
602                 if (rc == 0) {
603                         request->status = TAPE_REQUEST_IN_IO;
604                         break;
605                 }
606                 /* Start failed. Remove request and indicate failure. */
607                 DBF_EVENT(1, "tape: DOIO failed with er = %i\n", rc);
608
609                 /* Set ending status and do callback. */
610                 request->rc = rc;
611                 request->status = TAPE_REQUEST_DONE;
612                 __tape_remove_request(device, request);
613         }
614 }
615
616 static void
617 __tape_remove_request(struct tape_device *device, struct tape_request *request)
618 {
619         /* Remove from request queue. */
620         list_del(&request->list);
621
622         /* Do callback. */
623         if (request->callback != NULL)
624                 request->callback(request, request->callback_data);
625
626         /* Start next request. */
627         if (!list_empty(&device->req_queue))
628                 __tape_do_io_list(device);
629 }
630
631 /*
632  * Write sense data to console/dbf
633  */
634 void
635 tape_dump_sense(struct tape_device* device, struct tape_request *request,
636                 struct irb *irb)
637 {
638         unsigned int *sptr;
639
640         PRINT_INFO("-------------------------------------------------\n");
641         PRINT_INFO("DSTAT : %02x  CSTAT: %02x   CPA: %04x\n",
642                    irb->scsw.dstat, irb->scsw.cstat, irb->scsw.cpa);
643         PRINT_INFO("DEVICE: %s\n", device->cdev->dev.bus_id);
644         if (request != NULL)
645                 PRINT_INFO("OP    : %s\n", tape_op_verbose[request->op]);
646
647         sptr = (unsigned int *) irb->ecw;
648         PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
649                    sptr[0], sptr[1], sptr[2], sptr[3]);
650         PRINT_INFO("Sense data: %08X %08X %08X %08X \n",
651                    sptr[4], sptr[5], sptr[6], sptr[7]);
652         PRINT_INFO("--------------------------------------------------\n");
653 }
654
655 /*
656  * Write sense data to dbf
657  */
658 void
659 tape_dump_sense_dbf(struct tape_device *device, struct tape_request *request,
660                     struct irb *irb)
661 {
662         unsigned int *sptr;
663         const char* op;
664
665         if (request != NULL)
666                 op = tape_op_verbose[request->op];
667         else
668                 op = "---";
669         DBF_EVENT(3, "DSTAT : %02x   CSTAT: %02x\n",
670                   irb->scsw.dstat,irb->scsw.cstat);
671         DBF_EVENT(3, "DEVICE: %s OP\t: %s\n", device->cdev->dev.bus_id,op);
672         sptr = (unsigned int *) irb->ecw;
673         DBF_EVENT(3, "%08x %08x\n", sptr[0], sptr[1]);
674         DBF_EVENT(3, "%08x %08x\n", sptr[2], sptr[3]);
675         DBF_EVENT(3, "%08x %08x\n", sptr[4], sptr[5]);
676         DBF_EVENT(3, "%08x %08x\n", sptr[6], sptr[7]);
677 }
678
679 /*
680  * I/O helper function. Adds the request to the request queue
681  * and starts it if the tape is idle. Has to be called with
682  * the device lock held.
683  */
684 static inline int
685 __tape_do_io(struct tape_device *device, struct tape_request *request)
686 {
687         int rc;
688
689         switch (request->op) {
690                 case TO_MSEN:
691                 case TO_ASSIGN:
692                 case TO_UNASSIGN:
693                 case TO_READ_ATTMSG:
694                         if (device->tape_state == TS_INIT)
695                                 break;
696                         if (device->tape_state == TS_UNUSED)
697                                 break;
698                 default:
699                         if (device->tape_state == TS_BLKUSE)
700                                 break;
701                         if (device->tape_state != TS_IN_USE)
702                                 return -ENODEV;
703         }
704
705         /* Increase use count of device for the added request. */
706         request->device = tape_get_device_reference(device);
707
708         if (list_empty(&device->req_queue)) {
709                 /* No other requests are on the queue. Start this one. */
710 #ifdef CONFIG_S390_TAPE_BLOCK
711                 if (request->op == TO_BLOCK)
712                         device->discipline->check_locate(device, request);
713 #endif
714                 rc = ccw_device_start(device->cdev, request->cpaddr,
715                                       (unsigned long) request, 0x00,
716                                       request->options);
717                 if (rc) {
718                         DBF_EVENT(1, "tape: DOIO failed with rc = %i\n", rc);
719                         return rc;
720                 }
721                 DBF_LH(5, "Request %p added for execution.\n", request);
722                 list_add(&request->list, &device->req_queue);
723                 request->status = TAPE_REQUEST_IN_IO;
724         } else {
725                 DBF_LH(5, "Request %p add to queue.\n", request);
726                 list_add_tail(&request->list, &device->req_queue);
727                 request->status = TAPE_REQUEST_QUEUED;
728         }
729         return 0;
730 }
731
732 /*
733  * Add the request to the request queue, try to start it if the
734  * tape is idle. Return without waiting for end of i/o.
735  */
736 int
737 tape_do_io_async(struct tape_device *device, struct tape_request *request)
738 {
739         int rc;
740
741         DBF_LH(6, "tape_do_io_async(%p, %p)\n", device, request);
742
743         spin_lock_irq(get_ccwdev_lock(device->cdev));
744         /* Add request to request queue and try to start it. */
745         rc = __tape_do_io(device, request);
746         spin_unlock_irq(get_ccwdev_lock(device->cdev));
747         return rc;
748 }
749
750 /*
751  * tape_do_io/__tape_wake_up
752  * Add the request to the request queue, try to start it if the
753  * tape is idle and wait uninterruptible for its completion.
754  */
755 static void
756 __tape_wake_up(struct tape_request *request, void *data)
757 {
758         request->callback = NULL;
759         wake_up((wait_queue_head_t *) data);
760 }
761
762 int
763 tape_do_io(struct tape_device *device, struct tape_request *request)
764 {
765         wait_queue_head_t wq;
766         int rc;
767
768         init_waitqueue_head(&wq);
769         spin_lock_irq(get_ccwdev_lock(device->cdev));
770         /* Setup callback */
771         request->callback = __tape_wake_up;
772         request->callback_data = &wq;
773         /* Add request to request queue and try to start it. */
774         rc = __tape_do_io(device, request);
775         spin_unlock_irq(get_ccwdev_lock(device->cdev));
776         if (rc)
777                 return rc;
778         /* Request added to the queue. Wait for its completion. */
779         wait_event(wq, (request->callback == NULL));
780         /* Get rc from request */
781         return request->rc;
782 }
783
784 /*
785  * tape_do_io_interruptible/__tape_wake_up_interruptible
786  * Add the request to the request queue, try to start it if the
787  * tape is idle and wait uninterruptible for its completion.
788  */
789 static void
790 __tape_wake_up_interruptible(struct tape_request *request, void *data)
791 {
792         request->callback = NULL;
793         wake_up_interruptible((wait_queue_head_t *) data);
794 }
795
796 int
797 tape_do_io_interruptible(struct tape_device *device,
798                          struct tape_request *request)
799 {
800         wait_queue_head_t wq;
801         int rc;
802
803         init_waitqueue_head(&wq);
804         spin_lock_irq(get_ccwdev_lock(device->cdev));
805         /* Setup callback */
806         request->callback = __tape_wake_up_interruptible;
807         request->callback_data = &wq;
808         rc = __tape_do_io(device, request);
809         spin_unlock_irq(get_ccwdev_lock(device->cdev));
810         if (rc)
811                 return rc;
812         /* Request added to the queue. Wait for its completion. */
813         rc = wait_event_interruptible(wq, (request->callback == NULL));
814         if (rc != -ERESTARTSYS)
815                 /* Request finished normally. */
816                 return request->rc;
817         /* Interrupted by a signal. We have to stop the current request. */
818         spin_lock_irq(get_ccwdev_lock(device->cdev));
819         rc = __tape_halt_io(device, request);
820         if (rc == 0) {
821                 DBF_EVENT(3, "IO stopped on %s\n", device->cdev->dev.bus_id);
822                 rc = -ERESTARTSYS;
823         }
824         spin_unlock_irq(get_ccwdev_lock(device->cdev));
825         return rc;
826 }
827
828 /*
829  * Tape interrupt routine, called from the ccw_device layer
830  */
831 static void
832 __tape_do_irq (struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
833 {
834         struct tape_device *device;
835         struct tape_request *request;
836         int final;
837         int rc;
838
839         device = (struct tape_device *) cdev->dev.driver_data;
840         if (device == NULL) {
841                 PRINT_ERR("could not get device structure for bus_id %s "
842                           "in interrupt\n", cdev->dev.bus_id);
843                 return;
844         }
845         request = (struct tape_request *) intparm;
846
847         DBF_LH(6, "__tape_do_irq(device=%p, request=%p)\n", device, request);
848
849         /* May be an unsolicited irq */
850         if(request != NULL)
851                 request->rescnt = irb->scsw.count;
852
853         if (irb->scsw.dstat != 0x0c) {
854                 /* Set the 'ONLINE' flag depending on sense byte 1 */
855                 if(*(((__u8 *) irb->ecw) + 1) & SENSE_DRIVE_ONLINE)
856                         device->tape_generic_status |= GMT_ONLINE(~0);
857                 else
858                         device->tape_generic_status &= ~GMT_ONLINE(~0);
859
860                 /*
861                  * Any request that does not come back with channel end
862                  * and device end is unusual. Log the sense data.
863                  */
864                 DBF_EVENT(3,"-- Tape Interrupthandler --\n");
865                 tape_dump_sense_dbf(device, request, irb);
866         } else {
867                 /* Upon normal completion the device _is_ online */
868                 device->tape_generic_status |= GMT_ONLINE(~0);
869         }
870         if (device->tape_state == TS_NOT_OPER) {
871                 DBF_EVENT(6, "tape:device is not operational\n");
872                 return;
873         }
874
875         /*
876          * Request that were canceled still come back with an interrupt.
877          * To detect these request the state will be set to TAPE_REQUEST_DONE.
878          */
879         if(request != NULL && request->status == TAPE_REQUEST_DONE) {
880                 __tape_remove_request(device, request);
881                 return;
882         }
883
884         rc = device->discipline->irq(device, request, irb);
885         /*
886          * rc < 0 : request finished unsuccessfully.
887          * rc == TAPE_IO_SUCCESS: request finished successfully.
888          * rc == TAPE_IO_PENDING: request is still running. Ignore rc.
889          * rc == TAPE_IO_RETRY: request finished but needs another go.
890          * rc == TAPE_IO_STOP: request needs to get terminated.
891          */
892         final = 0;
893         switch (rc) {
894         case TAPE_IO_SUCCESS:
895                 /* Upon normal completion the device _is_ online */
896                 device->tape_generic_status |= GMT_ONLINE(~0);
897                 final = 1;
898                 break;
899         case TAPE_IO_PENDING:
900                 break;
901         case TAPE_IO_RETRY:
902 #ifdef CONFIG_S390_TAPE_BLOCK
903                 if (request->op == TO_BLOCK)
904                         device->discipline->check_locate(device, request);
905 #endif
906                 rc = ccw_device_start(cdev, request->cpaddr,
907                                       (unsigned long) request, 0x00,
908                                       request->options);
909                 if (rc) {
910                         DBF_EVENT(1, "tape: DOIO failed with er = %i\n", rc);
911                         final = 1;
912                 }
913                 break;
914         case TAPE_IO_STOP:
915                 __tape_halt_io(device, request);
916                 break;
917         default:
918                 if (rc > 0) {
919                         DBF_EVENT(6, "xunknownrc\n");
920                         PRINT_ERR("Invalid return code from discipline "
921                                   "interrupt function.\n");
922                         rc = -EIO;
923                 }
924                 final = 1;
925                 break;
926         }
927         if (final) {
928                 /* May be an unsolicited irq */
929                 if(request != NULL) {
930                         /* Set ending status. */
931                         request->rc = rc;
932                         request->status = TAPE_REQUEST_DONE;
933                         __tape_remove_request(device, request);
934                 } else {
935                         __tape_do_io_list(device);
936                 }
937         }
938 }
939
940 /*
941  * Tape device open function used by tape_char & tape_block frontends.
942  */
943 int
944 tape_open(struct tape_device *device)
945 {
946         int rc;
947
948         spin_lock(get_ccwdev_lock(device->cdev));
949         if (device->tape_state == TS_NOT_OPER) {
950                 DBF_EVENT(6, "TAPE:nodev\n");
951                 rc = -ENODEV;
952         } else if (device->tape_state == TS_IN_USE) {
953                 DBF_EVENT(6, "TAPE:dbusy\n");
954                 rc = -EBUSY;
955         } else if (device->tape_state == TS_BLKUSE) {
956                 DBF_EVENT(6, "TAPE:dbusy\n");
957                 rc = -EBUSY;
958         } else if (device->discipline != NULL &&
959                    !try_module_get(device->discipline->owner)) {
960                 DBF_EVENT(6, "TAPE:nodisc\n");
961                 rc = -ENODEV;
962         } else {
963                 tape_state_set(device, TS_IN_USE);
964                 rc = 0;
965         }
966         spin_unlock(get_ccwdev_lock(device->cdev));
967         return rc;
968 }
969
970 /*
971  * Tape device release function used by tape_char & tape_block frontends.
972  */
973 int
974 tape_release(struct tape_device *device)
975 {
976         spin_lock(get_ccwdev_lock(device->cdev));
977         if (device->tape_state == TS_IN_USE)
978                 tape_state_set(device, TS_UNUSED);
979         module_put(device->discipline->owner);
980         spin_unlock(get_ccwdev_lock(device->cdev));
981         return 0;
982 }
983
984 /*
985  * Execute a magnetic tape command a number of times.
986  */
987 int
988 tape_mtop(struct tape_device *device, int mt_op, int mt_count)
989 {
990         tape_mtop_fn fn;
991         int rc;
992
993         DBF_EVENT(6, "TAPE:mtio\n");
994         DBF_EVENT(6, "TAPE:ioop: %x\n", mt_op);
995         DBF_EVENT(6, "TAPE:arg:  %x\n", mt_count);
996
997         if (mt_op < 0 || mt_op >= TAPE_NR_MTOPS)
998                 return -EINVAL;
999         fn = device->discipline->mtop_array[mt_op];
1000         if (fn == NULL)
1001                 return -EINVAL;
1002
1003         /* We assume that the backends can handle count up to 500. */
1004         if (mt_op == MTBSR  || mt_op == MTFSR  || mt_op == MTFSF  ||
1005             mt_op == MTBSF  || mt_op == MTFSFM || mt_op == MTBSFM) {
1006                 rc = 0;
1007                 for (; mt_count > 500; mt_count -= 500)
1008                         if ((rc = fn(device, 500)) != 0)
1009                                 break;
1010                 if (rc == 0)
1011                         rc = fn(device, mt_count);
1012         } else
1013                 rc = fn(device, mt_count);
1014         return rc;
1015
1016 }
1017
1018 /*
1019  * Hutplug event support.
1020  */
1021 void
1022 tape_hotplug_event(struct tape_device *device, int devmaj, int action) {
1023 #ifdef CONFIG_HOTPLUG
1024         char *argv[3];
1025         char *envp[8];
1026         char  busid[20];
1027         char  major[20];
1028         char  minor[20];
1029
1030         /* Call the busid DEVNO to be compatible with old tape.agent. */
1031         sprintf(busid, "DEVNO=%s",   device->cdev->dev.bus_id);
1032         sprintf(major, "MAJOR=%d",   devmaj);
1033         sprintf(minor, "MINOR=%d",   device->first_minor);
1034
1035         argv[0] = hotplug_path;
1036         argv[1] = "tape";
1037         argv[2] = NULL;
1038
1039         envp[0] = "HOME=/";
1040         envp[1] = "PATH=/sbin:/bin:/usr/sbin:/usr/bin";
1041
1042         switch (action) {
1043                 case TAPE_HOTPLUG_CHAR_ADD:
1044                 case TAPE_HOTPLUG_BLOCK_ADD:
1045                         envp[2] = "ACTION=add";
1046                         break;
1047                 case TAPE_HOTPLUG_CHAR_REMOVE:
1048                 case TAPE_HOTPLUG_BLOCK_REMOVE:
1049                         envp[2] = "ACTION=remove";
1050                         break;
1051                 default:
1052                         BUG();
1053         }
1054         switch (action) {
1055                 case TAPE_HOTPLUG_CHAR_ADD:
1056                 case TAPE_HOTPLUG_CHAR_REMOVE:
1057                         envp[3] = "INTERFACE=char";
1058                         break;
1059                 case TAPE_HOTPLUG_BLOCK_ADD:
1060                 case TAPE_HOTPLUG_BLOCK_REMOVE:
1061                         envp[3] = "INTERFACE=block";
1062                         break;
1063                 default:
1064                         BUG();
1065         }
1066         envp[4] = busid;
1067         envp[5] = major;
1068         envp[6] = minor;
1069         envp[7] = NULL;
1070
1071         call_usermodehelper(argv[0], argv, envp, 0);
1072 #endif
1073 }
1074
1075 /*
1076  * Tape init function.
1077  */
1078 static int
1079 tape_init (void)
1080 {
1081         tape_dbf_area = debug_register ( "tape", 1, 2, 4*sizeof(long));
1082         debug_register_view(tape_dbf_area, &debug_sprintf_view);
1083 #ifdef DBF_LIKE_HELL
1084         debug_set_level(tape_dbf_area, 6);
1085 #endif
1086         DBF_EVENT(3, "tape init: ($Revision: 1.41 $)\n");
1087         tape_proc_init();
1088         tapechar_init ();
1089         tapeblock_init ();
1090         return 0;
1091 }
1092
1093 /*
1094  * Tape exit function.
1095  */
1096 static void
1097 tape_exit(void)
1098 {
1099         DBF_EVENT(6, "tape exit\n");
1100
1101         /* Get rid of the frontends */
1102         tapechar_exit();
1103         tapeblock_exit();
1104         tape_proc_cleanup();
1105         debug_unregister (tape_dbf_area);
1106 }
1107
1108 MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and "
1109               "Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)");
1110 MODULE_DESCRIPTION("Linux on zSeries channel attached "
1111                    "tape device driver ($Revision: 1.41 $)");
1112 MODULE_LICENSE("GPL");
1113
1114 module_init(tape_init);
1115 module_exit(tape_exit);
1116
1117 EXPORT_SYMBOL(tape_dbf_area);
1118 EXPORT_SYMBOL(tape_generic_remove);
1119 EXPORT_SYMBOL(tape_disable_device);
1120 EXPORT_SYMBOL(tape_generic_probe);
1121 EXPORT_SYMBOL(tape_enable_device);
1122 EXPORT_SYMBOL(tape_put_device);
1123 EXPORT_SYMBOL(tape_get_device_reference);
1124 EXPORT_SYMBOL(tape_state_verbose);
1125 EXPORT_SYMBOL(tape_op_verbose);
1126 EXPORT_SYMBOL(tape_state_set);
1127 EXPORT_SYMBOL(tape_med_state_set);
1128 EXPORT_SYMBOL(tape_alloc_request);
1129 EXPORT_SYMBOL(tape_free_request);
1130 EXPORT_SYMBOL(tape_dump_sense);
1131 EXPORT_SYMBOL(tape_dump_sense_dbf);
1132 EXPORT_SYMBOL(tape_do_io);
1133 EXPORT_SYMBOL(tape_do_io_async);
1134 EXPORT_SYMBOL(tape_do_io_interruptible);
1135 EXPORT_SYMBOL(tape_mtop);