1/***************************************************************************
2 *
3 *  drivers/s390/char/tape34xx.c
4 *    common tape device discipline for 34xx tapes.
5 *
6 *  S390 and zSeries version
7 *    Copyright (C) 2001 IBM Corporation
8 *    Author(s): Carsten Otte <cotte@de.ibm.com>
9 *               Tuan Ngo-Anh <ngoanh@de.ibm.com>
10 *
11 ****************************************************************************
12 */
13
14#include "tapedefs.h"
15#include <linux/config.h>
16#include <linux/version.h>
17#include <linux/stddef.h>
18#include <linux/kernel.h>
19#include <asm/types.h>
20#include <asm/uaccess.h>
21#include <linux/stat.h>
22#include <linux/proc_fs.h>
23#include <asm/ccwcache.h>
24#include <asm/idals.h>
25#ifdef CONFIG_S390_TAPE_DYNAMIC
26#include <asm/s390dyn.h>
27#endif
28#include <asm/debug.h>
29#include <linux/compatmac.h>
30#include "tape.h"
31#include "tape34xx.h"
32
33#define PRINTK_HEADER "T34xx:"
34
35tape_event_handler_t tape34xx_event_handler_table[TS_SIZE][TE_SIZE] =
36{
37    /* {START , DONE, FAILED, ERROR, OTHER } */
38	{NULL, tape34xx_unused_done, NULL, NULL, NULL},	/* TS_UNUSED */
39	{NULL, tape34xx_idle_done, NULL, NULL, NULL},	/* TS_IDLE */
40	{NULL, NULL, NULL, NULL, NULL},		/* TS_DONE */
41	{NULL, NULL, NULL, NULL, NULL},		/* TS_FAILED */
42	{NULL, tape34xx_block_done, NULL, NULL, NULL},		/* TS_BLOCK_INIT */
43	{NULL, tape34xx_bsb_init_done, NULL, NULL, NULL},	/* TS_BSB_INIT */
44	{NULL, tape34xx_bsf_init_done, NULL, NULL, NULL},	/* TS_BSF_INIT */
45	{NULL, tape34xx_dse_init_done, NULL, NULL, NULL},	/* TS_DSE_INIT */
46	{NULL, NULL, NULL, NULL, NULL},		/* TS_EGA_INIT */
47	{NULL, tape34xx_fsb_init_done, NULL, NULL, NULL},	/* TS_FSB_INIT */
48	{NULL, tape34xx_fsf_init_done, NULL, NULL, NULL},	/* TS_FSF_INIT */
49	{NULL, NULL, NULL, NULL, NULL},		/* TS_LDI_INIT */
50	{NULL, tape34xx_lbl_init_done, NULL, NULL, NULL},	/* TS_LBL_INIT */
51	{NULL, NULL, NULL, NULL, NULL},		/* TS_MSE_INIT */
52	{NULL, tape34xx_nop_init_done, NULL, NULL, NULL},	/* TS_NOP_INIT */
53	{NULL, NULL, NULL, NULL, NULL},		/* TS_RBA_INIT */
54	{NULL, tape34xx_rbi_init_done, NULL, NULL, NULL},	/* TS_RBI_INIT */
55	{NULL, NULL, NULL, NULL, NULL},		/* TS_RBU_INIT */
56	{NULL, NULL, NULL, NULL, NULL},		/* TS_RBL_INIT */
57	{NULL, NULL, NULL, NULL, NULL},		/* TS_RDC_INIT */
58	{NULL, tape34xx_rfo_init_done, NULL, NULL, NULL},	/* TS_RFO_INIT */
59	{NULL, NULL, NULL, NULL, NULL},		/* TS_RSD_INIT */
60	{NULL, tape34xx_rew_init_done, NULL, NULL, NULL},	/* TS_REW_INIT */
61	{NULL, tape34xx_rew_release_init_done, NULL, NULL, NULL},	/* TS_REW_RELEASE_IMIT */
62	{NULL, tape34xx_run_init_done, NULL, NULL, NULL},	/* TS_RUN_INIT */
63	{NULL, NULL, NULL, NULL, NULL},		/* TS_SEN_INIT */
64	{NULL, NULL, NULL, NULL, NULL},		/* TS_SID_INIT */
65	{NULL, NULL, NULL, NULL, NULL},		/* TS_SNP_INIT */
66	{NULL, NULL, NULL, NULL, NULL},		/* TS_SPG_INIT */
67	{NULL, NULL, NULL, NULL, NULL},		/* TS_SWI_INIT */
68	{NULL, NULL, NULL, NULL, NULL},		/* TS_SMR_INIT */
69	{NULL, NULL, NULL, NULL, NULL},		/* TS_SYN_INIT */
70	{NULL, NULL, NULL, NULL, NULL},		/* TS_TIO_INIT */
71	{NULL, NULL, NULL, NULL, NULL},		/* TS_UNA_INIT */
72	{NULL, tape34xx_wri_init_done, NULL, NULL, NULL},	/* TS_WRI_INIT */
73	{NULL, tape34xx_wtm_init_done, NULL, NULL, NULL},	/* TS_WTM_INIT */
74	{NULL, NULL, NULL, NULL, NULL}};        /* TS_NOT_OPER */
75
76
77int
78tape34xx_ioctl_overload (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg)
79{
80	return -EINVAL;		// no additional ioctls
81
82}
83
84ccw_req_t *
85tape34xx_write_block (const char *data, size_t count, tape_info_t * ti)
86{
87	long lockflags;
88	ccw_req_t *cqr;
89	ccw1_t *ccw;
90	void *mem;
91	cqr = tape_alloc_ccw_req (ti, 2, 0);
92	if (!cqr) {
93#ifdef TAPE_DEBUG
94	        debug_text_exception (tape_debug_area,6,"xwbl nomem");
95#endif /* TAPE_DEBUG */
96		return NULL;
97	}
98	mem = kmalloc (count, GFP_KERNEL);
99	if (!mem) {
100		tape_free_request (cqr);
101#ifdef TAPE_DEBUG
102	        debug_text_exception (tape_debug_area,6,"xwbl nomem");
103#endif /* TAPE_DEBUG */
104		return NULL;
105	}
106	if (copy_from_user (mem, data, count)) {
107		kfree (mem);
108		tape_free_request (cqr);
109#ifdef TAPE_DEBUG
110	        debug_text_exception (tape_debug_area,6,"xwbl segf.");
111#endif /* TAPE_DEBUG */
112		return NULL;
113	}
114	ccw = cqr->cpaddr;
115	ccw->cmd_code = MODE_SET_DB;
116	ccw->flags = CCW_FLAG_CC;
117	ccw->count = 1;
118	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
119	ccw++;
120
121	ccw->cmd_code = WRITE_CMD;
122	ccw->flags = 0;
123	ccw->count = count;
124	set_normalized_cda (ccw, (unsigned long) mem);
125	if ((ccw->cda) == 0) {
126		kfree (mem);
127		tape_free_request (cqr);
128		return NULL;
129	}
130	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
131	ti->kernbuf = mem;
132	ti->userbuf = (void *) data;
133	tapestate_set (ti, TS_WRI_INIT);
134	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
135#ifdef TAPE_DEBUG
136	debug_text_event (tape_debug_area,6,"xwbl ccwg");
137#endif /* TAPE_DEBUG */
138	return cqr;
139}
140
141void
142tape34xx_free_write_block (ccw_req_t * cqr, tape_info_t * ti)
143{
144	unsigned long lockflags;
145	ccw1_t *ccw;
146	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
147	ccw = cqr->cpaddr;
148	ccw++;
149	clear_normalized_cda (ccw);
150	kfree (ti->kernbuf);
151	tape_free_request (cqr);
152	ti->kernbuf = ti->userbuf = NULL;
153	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
154#ifdef TAPE_DEBUG
155	debug_text_event (tape_debug_area,6,"xfwb free");
156#endif /* TAPE_DEBUG */
157}
158
159ccw_req_t *
160tape34xx_read_block (const char *data, size_t count, tape_info_t * ti)
161{
162	long lockflags;
163	ccw_req_t *cqr;
164	ccw1_t *ccw;
165	void *mem;
166	cqr = tape_alloc_ccw_req (ti, 2, 0);
167	if (!cqr) {
168#ifdef TAPE_DEBUG
169	        debug_text_exception (tape_debug_area,6,"xrbl nomem");
170#endif /* TAPE_DEBUG */
171		return NULL;
172	}
173	mem = kmalloc (count, GFP_KERNEL);
174	if (!mem) {
175		tape_free_request (cqr);
176#ifdef TAPE_DEBUG
177	        debug_text_exception (tape_debug_area,6,"xrbl nomem");
178#endif /* TAPE_DEBUG */
179		return NULL;
180	}
181	ccw = cqr->cpaddr;
182	ccw->cmd_code = MODE_SET_DB;
183	ccw->flags = CCW_FLAG_CC;
184	ccw->count = 1;
185	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
186	ccw++;
187
188	ccw->cmd_code = READ_FORWARD;
189	ccw->flags = 0;
190	ccw->count = count;
191	set_normalized_cda (ccw, (unsigned long) mem);
192	if ((ccw->cda) == 0) {
193		kfree (mem);
194		tape_free_request (cqr);
195		return NULL;
196	}
197	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
198	ti->kernbuf = mem;
199	ti->userbuf = (void *) data;
200	tapestate_set (ti, TS_RFO_INIT);
201	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
202#ifdef TAPE_DEBUG
203	debug_text_event (tape_debug_area,6,"xrbl ccwg");
204#endif /* TAPE_DEBUG */
205	return cqr;
206}
207
208ccw_req_t *
209tape34xx_read_opposite (tape_info_t * ti,int novalue)
210{
211	ccw_req_t *cqr;
212	ccw1_t *ccw;
213	size_t count;
214	// first, retrieve the count from the old cqr.
215	cqr = ti->cqr;
216	ccw = cqr->cpaddr;
217	ccw++;
218	count=ccw->count;
219	// free old cqr.
220	clear_normalized_cda (ccw);
221	tape_free_request (cqr);
222	// build new cqr
223	cqr = tape_alloc_ccw_req (ti, 3, 0);
224	if (!cqr) {
225#ifdef TAPE_DEBUG
226	        debug_text_exception (tape_debug_area,6,"xrop nomem");
227#endif /* TAPE_DEBUG */
228		return NULL;
229	}
230	ccw = cqr->cpaddr;
231	ccw->cmd_code = MODE_SET_DB;
232	ccw->flags = CCW_FLAG_CC;
233	ccw->count = 1;
234	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
235	ccw++;
236
237	ccw->cmd_code = READ_BACKWARD;
238	ccw->flags = CCW_FLAG_CC;
239	ccw->count = count;
240	set_normalized_cda (ccw, (unsigned long) ti->kernbuf);
241	if ((ccw->cda) == 0) {
242		tape_free_request (cqr);
243		return NULL;
244	}
245	ccw++;
246	ccw->cmd_code = FORSPACEBLOCK;
247	ccw->flags = CCW_FLAG_CC;
248	ccw->count = 1;
249	ccw->cda = (unsigned long)ccw;
250	ccw++;
251	ccw->cmd_code = NOP;
252	ccw->flags = 0;
253	ccw->count = 1;
254	ccw->cda = (unsigned long)ccw;
255	tapestate_set (ti, TS_RBA_INIT);
256#ifdef TAPE_DEBUG
257	debug_text_event (tape_debug_area,6,"xrop ccwg");
258#endif /* TAPE_DEBUG */
259	return cqr;
260}
261
262void
263tape34xx_free_read_block (ccw_req_t * cqr, tape_info_t * ti)
264{
265	unsigned long lockflags;
266	size_t cpysize;
267	ccw1_t *ccw;
268	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
269	ccw = cqr->cpaddr;
270	ccw++;
271	cpysize = ccw->count - ti->devstat.rescnt;
272	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
273	if (copy_to_user (ti->userbuf, ti->kernbuf, cpysize)) {
274#ifdef TAPE_DEBUG
275	    debug_text_exception (tape_debug_area,6,"xfrb segf.");
276#endif /* TAPE_DEBUG */
277	}
278	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
279	clear_normalized_cda (ccw);
280	kfree (ti->kernbuf);
281	tape_free_request (cqr);
282	ti->kernbuf = ti->userbuf = NULL;
283	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
284#ifdef TAPE_DEBUG
285	debug_text_event (tape_debug_area,6,"xfrb free");
286#endif /* TAPE_DEBUG */
287}
288
289/*
290 * The IOCTL interface is implemented in the following section,
291 * excepted the MTRESET, MTSETBLK which are handled by tapechar.c
292 */
293/*
294 * MTFSF: Forward space over 'count' file marks. The tape is positioned
295 * at the EOT (End of Tape) side of the file mark.
296 */
297ccw_req_t *
298tape34xx_mtfsf (tape_info_t * ti, int count)
299{
300	long lockflags;
301	int i;
302	ccw_req_t *cqr;
303	ccw1_t *ccw;
304	if ((count == 0) || (count > 510)) {
305#ifdef TAPE_DEBUG
306	        debug_text_exception (tape_debug_area,6,"xfsf parm");
307#endif /* TAPE_DEBUG */
308		return NULL;
309	}
310	cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
311	if (!cqr) {
312#ifdef TAPE_DEBUG
313	        debug_text_exception (tape_debug_area,6,"xfsf nomem");
314#endif /* TAPE_DEBUG */
315		return NULL;
316	}
317	ccw = cqr->cpaddr;
318	ccw->cmd_code = MODE_SET_DB;
319	ccw->flags = CCW_FLAG_CC;
320	ccw->count = 1;
321	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
322	ccw++;
323	for (i = 0; i < count; i++) {
324		ccw->cmd_code = FORSPACEFILE;
325		ccw->flags = CCW_FLAG_CC;
326		ccw->count = 0;
327		ccw->cda = (unsigned long) (&(ccw->cmd_code));
328		ccw++;
329	}
330	ccw->cmd_code = NOP;
331	ccw->flags = 0;
332	ccw->count = 0;
333	ccw->cda = (unsigned long) (&(ccw->cmd_code));
334	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
335	ti->kernbuf = NULL;
336	ti->userbuf = NULL;
337	tapestate_set (ti, TS_FSF_INIT);
338	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
339#ifdef TAPE_DEBUG
340	debug_text_event (tape_debug_area,6,"xfsf ccwg");
341#endif /* TAPE_DEBUG */
342	return cqr;
343}
344
345/*
346 * MTBSF: Backward space over 'count' file marks. The tape is positioned at
347 * the EOT (End of Tape) side of the last skipped file mark.
348 */
349ccw_req_t *
350tape34xx_mtbsf (tape_info_t * ti, int count)
351{
352	long lockflags;
353	int i;
354	ccw_req_t *cqr;
355	ccw1_t *ccw;
356	if ((count == 0) || (count > 510)) {
357#ifdef TAPE_DEBUG
358	        debug_text_exception (tape_debug_area,6,"xbsf parm");
359#endif /* TAPE_DEBUG */
360	        return NULL;
361	}
362	cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
363	if (!cqr) {
364#ifdef TAPE_DEBUG
365	        debug_text_exception (tape_debug_area,6,"xbsf nomem");
366#endif /* TAPE_DEBUG */
367		return NULL;
368	}
369	ccw = cqr->cpaddr;
370	ccw->cmd_code = MODE_SET_DB;
371	ccw->flags = CCW_FLAG_CC;
372	ccw->count = 1;
373	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
374	ccw++;
375	for (i = 0; i < count; i++) {
376		ccw->cmd_code = BACKSPACEFILE;
377		ccw->flags = CCW_FLAG_CC;
378		ccw->count = 0;
379		ccw->cda = (unsigned long) (&(ccw->cmd_code));
380		ccw++;
381	}
382	ccw->cmd_code = NOP;
383	ccw->flags = 0;
384	ccw->count = 0;
385	ccw->cda = (unsigned long) (&(ccw->cmd_code));
386	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
387	ti->kernbuf = NULL;
388	ti->userbuf = NULL;
389	tapestate_set (ti, TS_BSF_INIT);
390	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
391#ifdef TAPE_DEBUG
392	debug_text_event (tape_debug_area,6,"xbsf ccwg");
393#endif /* TAPE_DEBUG */
394	return cqr;
395}
396
397/*
398 * MTFSR: Forward space over 'count' tape blocks (blocksize is set
399 * via MTSETBLK.
400 */
401ccw_req_t *
402tape34xx_mtfsr (tape_info_t * ti, int count)
403{
404	long lockflags;
405	int i;
406	ccw_req_t *cqr;
407	ccw1_t *ccw;
408	if ((count == 0) || (count > 510)) {
409#ifdef TAPE_DEBUG
410	        debug_text_exception (tape_debug_area,6,"xfsr parm");
411#endif /* TAPE_DEBUG */
412		return NULL;
413	}
414	cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
415	if (!cqr) {
416#ifdef TAPE_DEBUG
417	        debug_text_exception (tape_debug_area,6,"xfsr nomem");
418#endif /* TAPE_DEBUG */
419		return NULL;
420	}
421	ccw = cqr->cpaddr;
422	ccw->cmd_code = MODE_SET_DB;
423	ccw->flags = CCW_FLAG_CC;
424	ccw->count = 1;
425	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
426	ccw++;
427	for (i = 0; i < count; i++) {
428		ccw->cmd_code = FORSPACEBLOCK;
429		ccw->flags = CCW_FLAG_CC;
430		ccw->count = 0;
431		ccw->cda = (unsigned long) (&(ccw->cmd_code));
432		ccw++;
433	}
434	ccw->cmd_code = NOP;
435	ccw->flags = 0;
436	ccw->count = 0;
437	ccw->cda = (unsigned long) (&(ccw->cmd_code));
438	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
439	ti->kernbuf = NULL;
440	ti->userbuf = NULL;
441	tapestate_set (ti, TS_FSB_INIT);
442	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
443#ifdef TAPE_DEBUG
444	debug_text_event (tape_debug_area,6,"xfsr ccwgen");
445#endif /* TAPE_DEBUG */
446	return cqr;
447}
448
449/*
450 * MTBSR: Backward space over 'count' tape blocks.
451 * (blocksize is set via MTSETBLK.
452 */
453ccw_req_t *
454tape34xx_mtbsr (tape_info_t * ti, int count)
455{
456	long lockflags;
457	int i;
458	ccw_req_t *cqr;
459	ccw1_t *ccw;
460	if ((count == 0) || (count > 510)) {
461#ifdef TAPE_DEBUG
462	        debug_text_exception (tape_debug_area,6,"xbsr parm");
463#endif /* TAPE_DEBUG */
464	        return NULL;
465	}
466	cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
467	if (!cqr) {
468#ifdef TAPE_DEBUG
469	        debug_text_exception (tape_debug_area,6,"xbsr nomem");
470#endif /* TAPE_DEBUG */
471		return NULL;
472	}
473	ccw = cqr->cpaddr;
474	ccw->cmd_code = MODE_SET_DB;
475	ccw->flags = CCW_FLAG_CC;
476	ccw->count = 1;
477	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
478	ccw++;
479	for (i = 0; i < count; i++) {
480		ccw->cmd_code = BACKSPACEBLOCK;
481		ccw->flags = CCW_FLAG_CC;
482		ccw->count = 0;
483		ccw->cda = (unsigned long) (&(ccw->cmd_code));
484		ccw++;
485	}
486	ccw->cmd_code = NOP;
487	ccw->flags = 0;
488	ccw->count = 0;
489	ccw->cda = (unsigned long) (&(ccw->cmd_code));
490	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
491	ti->kernbuf = NULL;
492	ti->userbuf = NULL;
493	tapestate_set (ti, TS_BSB_INIT);
494	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
495#ifdef TAPE_DEBUG
496	debug_text_event (tape_debug_area,6,"xbsr ccwg");
497#endif /* TAPE_DEBUG */
498	return cqr;
499}
500
501/*
502 * MTWEOF: Write 'count' file marks at the current position.
503 */
504ccw_req_t *
505tape34xx_mtweof (tape_info_t * ti, int count)
506{
507	long lockflags;
508	int i;
509	ccw_req_t *cqr;
510	ccw1_t *ccw;
511	if ((count == 0) || (count > 510)) {
512#ifdef TAPE_DEBUG
513	        debug_text_exception (tape_debug_area,6,"xweo parm");
514#endif /* TAPE_DEBUG */
515		return NULL;
516	}
517	cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
518	if (!cqr) {
519#ifdef TAPE_DEBUG
520	        debug_text_exception (tape_debug_area,6,"xweo nomem");
521#endif /* TAPE_DEBUG */
522		return NULL;
523	}
524	ccw = cqr->cpaddr;
525	ccw->cmd_code = MODE_SET_DB;
526	ccw->flags = CCW_FLAG_CC;
527	ccw->count = 1;
528	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
529	ccw++;
530	for (i = 0; i < count; i++) {
531		ccw->cmd_code = WRITETAPEMARK;
532		ccw->flags = CCW_FLAG_CC;
533		ccw->count = 1;
534		ccw->cda = (unsigned long) (&(ccw->cmd_code));
535		ccw++;
536	}
537	ccw->cmd_code = NOP;
538	ccw->flags = 0;
539	ccw->count = 0;
540	ccw->cda = (unsigned long) (&(ccw->cmd_code));
541	ccw++;
542	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
543	ti->kernbuf = NULL;
544	ti->userbuf = NULL;
545	tapestate_set (ti, TS_WTM_INIT);
546	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
547#ifdef TAPE_DEBUG
548	debug_text_event (tape_debug_area,6,"xweo ccwg");
549#endif /* TAPE_DEBUG */
550	return cqr;
551}
552
553/*
554 * MTREW: Rewind the tape.
555 */
556ccw_req_t *
557tape34xx_mtrew (tape_info_t * ti, int count)
558{
559	long lockflags;
560	ccw_req_t *cqr;
561	ccw1_t *ccw;
562	cqr = tape_alloc_ccw_req (ti, 3, 0);
563	if (!cqr) {
564#ifdef TAPE_DEBUG
565	        debug_text_exception (tape_debug_area,6,"xrew nomem");
566#endif /* TAPE_DEBUG */
567		return NULL;
568	}
569	ccw = cqr->cpaddr;
570	ccw->cmd_code = MODE_SET_DB;
571	ccw->flags = CCW_FLAG_CC;
572	ccw->count = 1;
573	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
574	ccw++;
575	ccw->cmd_code = REWIND;
576	ccw->flags = CCW_FLAG_CC;
577	ccw->count = 0;
578	ccw->cda = (unsigned long) (&(ccw->cmd_code));
579	ccw++;
580	ccw->cmd_code = NOP;
581	ccw->flags = 0;
582	ccw->count = 0;
583	ccw->cda = (unsigned long) (&(ccw->cmd_code));
584	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
585	ti->kernbuf = NULL;
586	ti->userbuf = NULL;
587	tapestate_set (ti, TS_REW_INIT);
588	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
589#ifdef TAPE_DEBUG
590	debug_text_event (tape_debug_area,6,"xrew ccwg");
591#endif /* TAPE_DEBUG */
592	return cqr;
593}
594
595/*
596 * MTOFFL: Rewind the tape and put the drive off-line.
597 * Implement 'rewind unload'
598 */
599ccw_req_t *
600tape34xx_mtoffl (tape_info_t * ti, int count)
601{
602	long lockflags;
603	ccw_req_t *cqr;
604	ccw1_t *ccw;
605	cqr = tape_alloc_ccw_req (ti, 3, 32);
606	if (!cqr) {
607#ifdef TAPE_DEBUG
608	        debug_text_exception (tape_debug_area,6,"xoff nomem");
609#endif /* TAPE_DEBUG */
610		return NULL;
611	}
612	ccw = cqr->cpaddr;
613	ccw->cmd_code = MODE_SET_DB;
614	ccw->flags = CCW_FLAG_CC;
615	ccw->count = 1;
616	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
617	ccw++;
618	ccw->cmd_code = REWIND_UNLOAD;
619	ccw->flags = CCW_FLAG_CC;
620	ccw->count = 1;
621	ccw->cda = (unsigned long) (&(ccw->cmd_code));
622	ccw++;
623	ccw->cmd_code = SENSE;
624	ccw->flags = 0;
625	ccw->count = 32;
626	ccw->cda = (unsigned long) cqr->cpaddr;
627	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
628	ti->kernbuf = NULL;
629	ti->userbuf = NULL;
630	tapestate_set (ti, TS_RUN_INIT);
631	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
632#ifdef TAPE_DEBUG
633	debug_text_event (tape_debug_area,6,"xoff ccwg");
634#endif /* TAPE_DEBUG */
635	return cqr;
636}
637
638/*
639 * MTNOP: 'No operation'.
640 */
641ccw_req_t *
642tape34xx_mtnop (tape_info_t * ti, int count)
643{
644	long lockflags;
645	ccw_req_t *cqr;
646	ccw1_t *ccw;
647	cqr = tape_alloc_ccw_req (ti, 1, 0);
648	if (!cqr) {
649#ifdef TAPE_DEBUG
650	        debug_text_exception (tape_debug_area,6,"xnop nomem");
651#endif /* TAPE_DEBUG */
652		return NULL;
653	}
654	ccw = cqr->cpaddr;
655	ccw->cmd_code = NOP;
656	ccw->flags = 0;
657	ccw->count = 0;
658	ccw->cda = (unsigned long) ccw->cmd_code;
659	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
660	ti->kernbuf = NULL;
661	ti->userbuf = NULL;
662	tapestate_set (ti, TS_NOP_INIT);
663	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
664#ifdef TAPE_DEBUG
665	debug_text_event (tape_debug_area,6,"xnop ccwg");
666#endif /* TAPE_DEBUG */
667	return cqr;
668}
669
670/*
671 * MTBSFM: Backward space over 'count' file marks.
672 * The tape is positioned at the BOT (Begin Of Tape) side of the
673 * last skipped file mark.
674 */
675ccw_req_t *
676tape34xx_mtbsfm (tape_info_t * ti, int count)
677{
678	long lockflags;
679	int i;
680	ccw_req_t *cqr;
681	ccw1_t *ccw;
682	if ((count == 0) || (count > 510)) {
683#ifdef TAPE_DEBUG
684	        debug_text_exception (tape_debug_area,6,"xbsm parm");
685#endif /* TAPE_DEBUG */
686		return NULL;
687	}
688	cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
689	if (!cqr) {
690#ifdef TAPE_DEBUG
691	        debug_text_exception (tape_debug_area,6,"xbsm nomem");
692#endif /* TAPE_DEBUG */
693		return NULL;
694	}
695	ccw = cqr->cpaddr;
696	ccw->cmd_code = MODE_SET_DB;
697	ccw->flags = CCW_FLAG_CC;
698	ccw->count = 1;
699	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
700	ccw++;
701	for (i = 0; i < count; i++) {
702		ccw->cmd_code = BACKSPACEFILE;
703		ccw->flags = CCW_FLAG_CC;
704		ccw->count = 0;
705		ccw->cda = (unsigned long) (&(ccw->cmd_code));
706		ccw++;
707	}
708	ccw->cmd_code = NOP;
709	ccw->flags = 0;
710	ccw->count = 0;
711	ccw->cda = (unsigned long) (&(ccw->cmd_code));
712	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
713	ti->kernbuf = NULL;
714	ti->userbuf = NULL;
715	tapestate_set (ti, TS_BSF_INIT);
716	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
717#ifdef TAPE_DEBUG
718	debug_text_event (tape_debug_area,6,"xbsm ccwg");
719#endif /* TAPE_DEBUG */
720	return cqr;
721}
722
723/*
724 * MTFSFM: Forward space over 'count' file marks.
725 * The tape is positioned at the BOT (Begin Of Tape) side
726 * of the last skipped file mark.
727 */
728ccw_req_t *
729tape34xx_mtfsfm (tape_info_t * ti, int count)
730{
731	long lockflags;
732	int i;
733	ccw_req_t *cqr;
734	ccw1_t *ccw;
735	if ((count == 0) || (count > 510)) {
736#ifdef TAPE_DEBUG
737	        debug_text_exception (tape_debug_area,6,"xfsm parm");
738#endif /* TAPE_DEBUG */
739		return NULL;
740	}
741	cqr = tape_alloc_ccw_req (ti, 2 + count, 0);
742	if (!cqr) {
743#ifdef TAPE_DEBUG
744	        debug_text_exception (tape_debug_area,6,"xfsm nomem");
745#endif /* TAPE_DEBUG */
746		return NULL;
747	}
748	ccw = cqr->cpaddr;
749	ccw->cmd_code = MODE_SET_DB;
750	ccw->flags = CCW_FLAG_CC;
751	ccw->count = 1;
752	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
753	ccw++;
754	for (i = 0; i < count; i++) {
755		ccw->cmd_code = FORSPACEFILE;
756		ccw->flags = CCW_FLAG_CC;
757		ccw->count = 0;
758		ccw->cda = (unsigned long) (&(ccw->cmd_code));
759		ccw++;
760	}
761	ccw->cmd_code = NOP;
762	ccw->flags = 0;
763	ccw->count = 0;
764	ccw->cda = (unsigned long) (&(ccw->cmd_code));
765	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
766	ti->kernbuf = NULL;
767	ti->userbuf = NULL;
768	tapestate_set (ti, TS_FSF_INIT);
769	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
770#ifdef TAPE_DEBUG
771	debug_text_event (tape_debug_area,6,"xfsm ccwg");
772#endif /* TAPE_DEBUG */
773	return cqr;
774}
775
776/*
777 * MTEOM: positions at the end of the portion of the tape already used
778 * for recordind data. MTEOM positions after the last file mark, ready for
779 * appending another file.
780 * MTRETEN: Retension the tape, i.e. forward space to end of tape and rewind.
781 */
782ccw_req_t *
783tape34xx_mteom (tape_info_t * ti, int count)
784{
785	long lockflags;
786	ccw_req_t *cqr;
787	ccw1_t *ccw;
788	cqr = tape_alloc_ccw_req (ti, 4, 0);
789	if (!cqr) {
790#ifdef TAPE_DEBUG
791	        debug_text_exception (tape_debug_area,6,"xeom nomem");
792#endif /* TAPE_DEBUG */
793		return NULL;
794	}
795	ccw = cqr->cpaddr;
796	ccw->cmd_code = MODE_SET_DB;
797	ccw->flags = CCW_FLAG_CC;
798	ccw->count = 1;
799	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
800	ccw++;
801	ccw->cmd_code = FORSPACEFILE;
802	ccw->flags = CCW_FLAG_CC;
803	ccw->count = 0;
804	ccw->cda = (unsigned long) (&(ccw->cmd_code));
805	ccw++;
806	ccw->cmd_code = NOP;
807	ccw->flags = CCW_FLAG_CC;
808	ccw->count = 0;
809	ccw->cda = (unsigned long) (&(ccw->cmd_code));
810	ccw++;
811	ccw->cmd_code = CCW_CMD_TIC;
812	ccw->flags = 0;
813	ccw->count = 0;
814	ccw->cda = (unsigned long) (cqr->cpaddr);
815	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
816	ti->kernbuf = NULL;
817	ti->userbuf = NULL;
818	tapestate_set (ti, TS_FSF_INIT);
819	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
820#ifdef TAPE_DEBUG
821	debug_text_event (tape_debug_area,6,"xeom ccwg");
822#endif /* TAPE_DEBUG */
823	return cqr;
824}
825
826/*
827 * MTERASE: erases the tape.
828 */
829ccw_req_t *
830tape34xx_mterase (tape_info_t * ti, int count)
831{
832	long lockflags;
833	ccw_req_t *cqr;
834	ccw1_t *ccw;
835	cqr = tape_alloc_ccw_req (ti, 5, 0);
836	if (!cqr) {
837#ifdef TAPE_DEBUG
838	        debug_text_exception (tape_debug_area,6,"xera nomem");
839#endif /* TAPE_DEBUG */
840		return NULL;
841	}
842	ccw = cqr->cpaddr;
843	ccw->cmd_code = MODE_SET_DB;
844	ccw->flags = CCW_FLAG_CC;
845	ccw->count = 1;
846	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
847	ccw++;
848	ccw->cmd_code = REWIND;
849	ccw->flags = CCW_FLAG_CC;
850	ccw->count = 0;
851	ccw->cda = (unsigned long) (&(ccw->cmd_code));
852	ccw++;
853	ccw->cmd_code = ERASE_GAP;
854	ccw->flags = CCW_FLAG_CC;
855	ccw->count = 0;
856	ccw->cda = (unsigned long) (&(ccw->cmd_code));
857	ccw++;
858	ccw->cmd_code = DATA_SEC_ERASE;
859	ccw->flags = CCW_FLAG_CC;
860	ccw->count = 0;
861	ccw->cda = (unsigned long) (&(ccw->cmd_code));
862	ccw++;
863	ccw->cmd_code = NOP;
864	ccw->flags = 0;
865	ccw->count = 0;
866	ccw->cda = (unsigned long) (&(ccw->cmd_code));
867	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
868	ti->kernbuf = NULL;
869	ti->userbuf = NULL;
870	tapestate_set (ti, TS_DSE_INIT);
871	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
872#ifdef TAPE_DEBUG
873	debug_text_event (tape_debug_area,6,"xera ccwg");
874#endif /* TAPE_DEBUG */
875	return cqr;
876}
877
878/*
879 * MTSETDENSITY: set tape density.
880 */
881ccw_req_t *
882tape34xx_mtsetdensity (tape_info_t * ti, int count)
883{
884	long lockflags;
885	ccw_req_t *cqr;
886	ccw1_t *ccw;
887	cqr = tape_alloc_ccw_req (ti, 2, 0);
888	if (!cqr) {
889#ifdef TAPE_DEBUG
890	        debug_text_exception (tape_debug_area,6,"xden nomem");
891#endif /* TAPE_DEBUG */
892		return NULL;
893	}
894	ccw = cqr->cpaddr;
895	ccw->cmd_code = MODE_SET_DB;
896	ccw->flags = CCW_FLAG_CC;
897	ccw->count = 1;
898	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
899	ccw++;
900	ccw->cmd_code = NOP;
901	ccw->flags = 0;
902	ccw->count = 0;
903	ccw->cda = (unsigned long) (&(ccw->cmd_code));
904	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
905	ti->kernbuf = NULL;
906	ti->userbuf = NULL;
907	tapestate_set (ti, TS_NOP_INIT);
908	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
909#ifdef TAPE_DEBUG
910	debug_text_event (tape_debug_area,6,"xden ccwg");
911#endif /* TAPE_DEBUG */
912	return cqr;
913}
914
915/*
916 * MTSEEK: seek to the specified block.
917 */
918ccw_req_t *
919tape34xx_mtseek (tape_info_t * ti, int count)
920{
921	long lockflags;
922	__u8 *data;
923	ccw_req_t *cqr;
924	ccw1_t *ccw;
925	if ((data = kmalloc (4 * sizeof (__u8), GFP_KERNEL)) == NULL) {
926#ifdef TAPE_DEBUG
927	        debug_text_exception (tape_debug_area,6,"xsee nomem");
928#endif /* TAPE_DEBUG */
929		return NULL;
930	}
931	data[0] = 0x01;
932	data[1] = data[2] = data[3] = 0x00;
933	if (count >= 4194304) {
934#ifdef TAPE_DEBUG
935	        debug_text_exception (tape_debug_area,6,"xsee parm");
936#endif /* TAPE_DEBUG */
937		kfree(data);
938		return NULL;
939	}
940	if (((tape34xx_disc_data_t *) ti->discdata)->modeset_byte & 0x08)	// IDRC on
941
942		data[1] = data[1] | 0x80;
943	data[3] += count % 256;
944	data[2] += (count / 256) % 256;
945	data[1] += (count / 65536);
946#ifdef TAPE_DEBUG
947	debug_text_event (tape_debug_area,6,"xsee id:");
948	debug_int_event (tape_debug_area,6,count);
949#endif /* TAPE_DEBUG */
950	cqr = tape_alloc_ccw_req (ti, 3, 0);
951	if (!cqr) {
952#ifdef TAPE_DEBUG
953	        debug_text_exception (tape_debug_area,6,"xsee nomem");
954#endif /* TAPE_DEBUG */
955		kfree (data);
956		return NULL;
957	}
958	ccw = cqr->cpaddr;
959	ccw->cmd_code = MODE_SET_DB;
960	ccw->flags = CCW_FLAG_CC;
961	ccw->count = 1;
962	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
963	ccw++;
964	ccw->cmd_code = LOCATE;
965	ccw->flags = CCW_FLAG_CC;
966	ccw->count = 4;
967	set_normalized_cda (ccw, (unsigned long) data);
968	ccw++;
969	ccw->cmd_code = NOP;
970	ccw->flags = 0;
971	ccw->count = 0;
972	ccw->cda = (unsigned long) (&(ccw->cmd_code));
973	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
974	ti->kernbuf = data;
975	ti->userbuf = NULL;
976	tapestate_set (ti, TS_LBL_INIT);
977	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
978#ifdef TAPE_DEBUG
979	debug_text_event (tape_debug_area,6,"xsee ccwg");
980#endif /* TAPE_DEBUG */
981	return cqr;
982}
983
984/*
985 * MTTELL: Tell block. Return the number of block relative to current file.
986 */
987ccw_req_t *
988tape34xx_mttell (tape_info_t * ti, int count)
989{
990	long lockflags;
991	ccw_req_t *cqr;
992	ccw1_t *ccw;
993	void *mem;
994	cqr = tape_alloc_ccw_req (ti, 2, 0);
995	if (!cqr) {
996#ifdef TAPE_DEBUG
997	        debug_text_exception (tape_debug_area,6,"xtel nomem");
998#endif /* TAPE_DEBUG */
999		return NULL;
1000	}
1001	mem = kmalloc (8, GFP_KERNEL);
1002	if (!mem) {
1003		tape_free_request (cqr);
1004#ifdef TAPE_DEBUG
1005	        debug_text_exception (tape_debug_area,6,"xtel nomem");
1006#endif /* TAPE_DEBUG */
1007		return NULL;
1008	}
1009	ccw = cqr->cpaddr;
1010	ccw->cmd_code = MODE_SET_DB;
1011	ccw->flags = CCW_FLAG_CC;
1012	ccw->count = 1;
1013	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
1014	ccw++;
1015
1016	ccw->cmd_code = READ_BLOCK_ID;
1017	ccw->flags = 0;
1018	ccw->count = 8;
1019	set_normalized_cda (ccw, (unsigned long) mem);
1020	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
1021	ti->kernbuf = mem;
1022	ti->userbuf = NULL;
1023	tapestate_set (ti, TS_RBI_INIT);
1024	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
1025#ifdef TAPE_DEBUG
1026	debug_text_event (tape_debug_area,6,"xtel ccwg");
1027#endif /* TAPE_DEBUG */
1028	return cqr;
1029}
1030
1031/*
1032 * MTSETDRVBUFFER: Set the tape drive buffer code to number.
1033 * Implement NOP.
1034 */
1035ccw_req_t *
1036tape34xx_mtsetdrvbuffer (tape_info_t * ti, int count)
1037{
1038	long lockflags;
1039	ccw_req_t *cqr;
1040	ccw1_t *ccw;
1041	cqr = tape_alloc_ccw_req (ti, 2, 0);
1042	if (!cqr) {
1043#ifdef TAPE_DEBUG
1044	        debug_text_exception (tape_debug_area,6,"xbuf nomem");
1045#endif /* TAPE_DEBUG */
1046		return NULL;
1047	}
1048	ccw = cqr->cpaddr;
1049	ccw->cmd_code = MODE_SET_DB;
1050	ccw->flags = CCW_FLAG_CC;
1051	ccw->count = 1;
1052	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
1053	ccw++;
1054	ccw->cmd_code = NOP;
1055	ccw->flags = 0;
1056	ccw->count = 0;
1057	ccw->cda = (unsigned long) (&(ccw->cmd_code));
1058	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
1059	ti->kernbuf = NULL;
1060	ti->userbuf = NULL;
1061	tapestate_set (ti, TS_NOP_INIT);
1062	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
1063#ifdef TAPE_DEBUG
1064	debug_text_event (tape_debug_area,6,"xbuf ccwg");
1065#endif /* TAPE_DEBUG */
1066	return cqr;
1067}
1068
1069/*
1070 * MTLOCK: Locks the tape drive door.
1071 * Implement NOP CCW command.
1072 */
1073ccw_req_t *
1074tape34xx_mtlock (tape_info_t * ti, int count)
1075{
1076	long lockflags;
1077	ccw_req_t *cqr;
1078	ccw1_t *ccw;
1079	cqr = tape_alloc_ccw_req (ti, 2, 0);
1080	if (!cqr) {
1081#ifdef TAPE_DEBUG
1082	        debug_text_exception (tape_debug_area,6,"xloc nomem");
1083#endif /* TAPE_DEBUG */
1084		return NULL;
1085	}
1086	ccw = cqr->cpaddr;
1087	ccw->cmd_code = MODE_SET_DB;
1088	ccw->flags = CCW_FLAG_CC;
1089	ccw->count = 1;
1090	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
1091	ccw++;
1092	ccw->cmd_code = NOP;
1093	ccw->flags = 0;
1094	ccw->count = 0;
1095	ccw->cda = (unsigned long) (&(ccw->cmd_code));
1096	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
1097	ti->kernbuf = NULL;
1098	ti->userbuf = NULL;
1099	tapestate_set (ti, TS_NOP_INIT);
1100	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
1101#ifdef TAPE_DEBUG
1102	debug_text_event (tape_debug_area,6,"xloc ccwg");
1103#endif /* TAPE_DEBUG */
1104	return cqr;
1105}
1106
1107/*
1108 * MTUNLOCK: Unlocks the tape drive door.
1109 * Implement the NOP CCW command.
1110 */
1111ccw_req_t *
1112tape34xx_mtunlock (tape_info_t * ti, int count)
1113{
1114	long lockflags;
1115	ccw_req_t *cqr;
1116	ccw1_t *ccw;
1117	cqr = tape_alloc_ccw_req (ti, 2, 0);
1118	if (!cqr) {
1119#ifdef TAPE_DEBUG
1120	        debug_text_exception (tape_debug_area,6,"xulk nomem");
1121#endif /* TAPE_DEBUG */
1122		return NULL;
1123	}
1124	ccw = cqr->cpaddr;
1125	ccw->cmd_code = MODE_SET_DB;
1126	ccw->flags = CCW_FLAG_CC;
1127	ccw->count = 1;
1128	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
1129	ccw++;
1130	ccw->cmd_code = NOP;
1131	ccw->flags = 0;
1132	ccw->count = 0;
1133	ccw->cda = (unsigned long) (&(ccw->cmd_code));
1134	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
1135	ti->kernbuf = NULL;
1136	ti->userbuf = NULL;
1137	tapestate_set (ti, TS_NOP_INIT);
1138	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
1139#ifdef TAPE_DEBUG
1140	debug_text_event (tape_debug_area,6,"xulk ccwg");
1141#endif /* TAPE_DEBUG */
1142	return cqr;
1143}
1144
1145/*
1146 * MTLOAD: Loads the tape.
1147 * This function is not implemented and returns NULL, which causes the Frontend to wait for a medium being loaded.
1148 *  The 3480/3490 type Tapes do not support a load command
1149 */
1150ccw_req_t *
1151tape34xx_mtload (tape_info_t * ti, int count)
1152{
1153         return NULL;
1154}
1155
1156/*
1157 * MTUNLOAD: Rewind the tape and unload it.
1158 */
1159ccw_req_t *
1160tape34xx_mtunload (tape_info_t * ti, int count)
1161{
1162	long lockflags;
1163	ccw_req_t *cqr;
1164	ccw1_t *ccw;
1165	cqr = tape_alloc_ccw_req (ti, 3, 32);
1166	if (!cqr) {
1167#ifdef TAPE_DEBUG
1168	        debug_text_exception (tape_debug_area,6,"xunl nomem");
1169#endif /* TAPE_DEBUG */
1170		return NULL;
1171	}
1172	ccw = cqr->cpaddr;
1173	ccw->cmd_code = MODE_SET_DB;
1174	ccw->flags = CCW_FLAG_CC;
1175	ccw->count = 1;
1176	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
1177	ccw++;
1178	ccw->cmd_code = REWIND_UNLOAD;
1179	ccw->flags = CCW_FLAG_CC;
1180	ccw->count = 1;
1181	ccw->cda = (unsigned long) (&(ccw->cmd_code));
1182	ccw++;
1183	ccw->cmd_code = SENSE;
1184	ccw->flags = 0;
1185	ccw->count = 32;
1186	ccw->cda = (unsigned long) cqr->cpaddr;
1187	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
1188	ti->kernbuf = NULL;
1189	ti->userbuf = NULL;
1190	tapestate_set (ti, TS_RUN_INIT);
1191	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
1192#ifdef TAPE_DEBUG
1193	debug_text_event (tape_debug_area,6,"xunl ccwg");
1194#endif /* TAPE_DEBUG */
1195	return cqr;
1196}
1197
1198/*
1199 * MTCOMPRESSION: used to enable compression.
1200 * Sets the IDRC on/off.
1201 */
1202ccw_req_t *
1203tape34xx_mtcompression (tape_info_t * ti, int count)
1204{
1205	long lockflags;
1206	ccw_req_t *cqr;
1207	ccw1_t *ccw;
1208	if ((count < 0) || (count > 1)) {
1209#ifdef TAPE_DEBUG
1210	        debug_text_exception (tape_debug_area,6,"xcom parm");
1211#endif /* TAPE_DEBUG */
1212		return NULL;
1213	}
1214	if (count == 0)
1215		((tape34xx_disc_data_t *) ti->discdata)->modeset_byte = 0x00;		// IDRC off
1216
1217	else
1218		((tape34xx_disc_data_t *) ti->discdata)->modeset_byte = 0x08;		// IDRC on
1219
1220	cqr = tape_alloc_ccw_req (ti, 2, 0);
1221	if (!cqr) {
1222#ifdef TAPE_DEBUG
1223	        debug_text_exception (tape_debug_area,6,"xcom nomem");
1224#endif /* TAPE_DEBUG */
1225		return NULL;
1226	}
1227	ccw = cqr->cpaddr;
1228	ccw->cmd_code = MODE_SET_DB;
1229	ccw->flags = CCW_FLAG_CC;
1230	ccw->count = 1;
1231	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
1232	ccw++;
1233	ccw->cmd_code = NOP;
1234	ccw->flags = 0;
1235	ccw->count = 0;
1236	ccw->cda = (unsigned long) (&(ccw->cmd_code));
1237	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
1238	ti->kernbuf = NULL;
1239	ti->userbuf = NULL;
1240	tapestate_set (ti, TS_NOP_INIT);
1241	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
1242#ifdef TAPE_DEBUG
1243	debug_text_event (tape_debug_area,6,"xcom ccwg");
1244#endif /* TAPE_DEBUG */
1245	return cqr;
1246}
1247
1248/*
1249 * MTSTPART: Move the tape head at the partition with the number 'count'.
1250 * Implement the NOP CCW command.
1251 */
1252ccw_req_t *
1253tape34xx_mtsetpart (tape_info_t * ti, int count)
1254{
1255	long lockflags;
1256	ccw_req_t *cqr;
1257	ccw1_t *ccw;
1258	cqr = tape_alloc_ccw_req (ti, 2, 0);
1259	if (!cqr) {
1260#ifdef TAPE_DEBUG
1261	        debug_text_exception (tape_debug_area,6,"xspa nomem");
1262#endif /* TAPE_DEBUG */
1263		return NULL;
1264	}
1265	ccw = cqr->cpaddr;
1266	ccw->cmd_code = MODE_SET_DB;
1267	ccw->flags = CCW_FLAG_CC;
1268	ccw->count = 1;
1269	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
1270	ccw++;
1271	ccw->cmd_code = NOP;
1272	ccw->flags = 0;
1273	ccw->count = 0;
1274	ccw->cda = (unsigned long) (&(ccw->cmd_code));
1275	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
1276	ti->kernbuf = NULL;
1277	ti->userbuf = NULL;
1278	tapestate_set (ti, TS_NOP_INIT);
1279	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
1280#ifdef TAPE_DEBUG
1281	debug_text_event (tape_debug_area,6,"xspa ccwg");
1282#endif /* TAPE_DEBUG */
1283	return cqr;
1284}
1285
1286/*
1287 * MTMKPART: .... dummy .
1288 * Implement the NOP CCW command.
1289 */
1290ccw_req_t *
1291tape34xx_mtmkpart (tape_info_t * ti, int count)
1292{
1293	long lockflags;
1294	ccw_req_t *cqr;
1295	ccw1_t *ccw;
1296	cqr = tape_alloc_ccw_req (ti, 2, 0);
1297	if (!cqr) {
1298#ifdef TAPE_DEBUG
1299	        debug_text_exception (tape_debug_area,6,"xnpa nomem");
1300#endif /* TAPE_DEBUG */
1301		return NULL;
1302	}
1303	ccw = cqr->cpaddr;
1304	ccw->cmd_code = MODE_SET_DB;
1305	ccw->flags = CCW_FLAG_CC;
1306	ccw->count = 1;
1307	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
1308	ccw++;
1309	ccw->cmd_code = NOP;
1310	ccw->flags = 0;
1311	ccw->count = 0;
1312	ccw->cda = (unsigned long) (&(ccw->cmd_code));
1313	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);
1314	ti->kernbuf = NULL;
1315	ti->userbuf = NULL;
1316	tapestate_set (ti, TS_NOP_INIT);
1317	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);
1318#ifdef TAPE_DEBUG
1319	debug_text_event (tape_debug_area,6,"xnpa ccwg");
1320#endif /* TAPE_DEBUG */
1321	return cqr;
1322}
1323
1324/*
1325 * MTIOCGET: query the tape drive status.
1326 */
1327ccw_req_t *
1328tape34xx_mtiocget (tape_info_t * ti, int count)
1329{
1330	return NULL;
1331}
1332
1333/*
1334 * MTIOCPOS: query the tape position.
1335 */
1336ccw_req_t *
1337tape34xx_mtiocpos (tape_info_t * ti, int count)
1338{
1339	return NULL;
1340}
1341
1342ccw_req_t * tape34xx_bread (struct request *req,tape_info_t* ti,int tapeblock_major) {
1343	ccw_req_t *cqr;
1344	ccw1_t *ccw;
1345	__u8 *data;
1346	int s2b = blksize_size[tapeblock_major][ti->blk_minor]/hardsect_size[tapeblock_major][ti->blk_minor];
1347	int realcount;
1348	int size,bhct = 0;
1349	struct buffer_head* bh;
1350	for (bh = req->bh; bh; bh = bh->b_reqnext) {
1351		if (bh->b_size > blksize_size[tapeblock_major][ti->blk_minor])
1352			for (size = 0; size < bh->b_size; size += blksize_size[tapeblock_major][ti->blk_minor])
1353				bhct++;
1354		else
1355			bhct++;
1356	}
1357	if ((data = kmalloc (4 * sizeof (__u8), GFP_ATOMIC)) == NULL) {
1358#ifdef TAPE_DEBUG
1359	        debug_text_exception (tape_debug_area,3,"xBREDnomem");
1360#endif /* TAPE_DEBUG */
1361		return NULL;
1362	}
1363	data[0] = 0x01;
1364	data[1] = data[2] = data[3] = 0x00;
1365	realcount=req->sector/s2b;
1366	if (((tape34xx_disc_data_t *) ti->discdata)->modeset_byte & 0x08)	// IDRC on
1367
1368		data[1] = data[1] | 0x80;
1369	data[3] += realcount % 256;
1370	data[2] += (realcount / 256) % 256;
1371	data[1] += (realcount / 65536);
1372#ifdef TAPE_DEBUG
1373	debug_text_event (tape_debug_area,6,"xBREDid:");
1374	debug_int_event (tape_debug_area,6,realcount);
1375#endif /* TAPE_DEBUG */
1376	cqr = tape_alloc_ccw_req (ti, 2+bhct+1, 0);
1377	if (!cqr) {
1378#ifdef TAPE_DEBUG
1379	        debug_text_exception (tape_debug_area,6,"xBREDnomem");
1380#endif /* TAPE_DEBUG */
1381		kfree(data);
1382		return NULL;
1383	}
1384	ccw = cqr->cpaddr;
1385	ccw->cmd_code = MODE_SET_DB;
1386	ccw->flags = CCW_FLAG_CC;
1387	ccw->count = 1;
1388	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));
1389	if (realcount!=ti->position) {
1390	    ccw++;
1391	    ccw->cmd_code = LOCATE;
1392	    ccw->flags = CCW_FLAG_CC;
1393	    ccw->count = 4;
1394	    set_normalized_cda (ccw, (unsigned long) data);
1395	}
1396	ti->position=realcount+req->nr_sectors/s2b;
1397	for (bh=req->bh;bh!=NULL;) {
1398	        ccw->flags = CCW_FLAG_CC;
1399		if (bh->b_size >= blksize_size[tapeblock_major][ti->blk_minor]) {
1400			for (size = 0; size < bh->b_size; size += blksize_size[tapeblock_major][ti->blk_minor]) {
1401			        ccw++;
1402				ccw->flags = CCW_FLAG_CC;
1403				ccw->cmd_code = READ_FORWARD;
1404				ccw->count = blksize_size[tapeblock_major][ti->blk_minor];
1405				set_normalized_cda (ccw, __pa (bh->b_data + size));
1406			}
1407			bh = bh->b_reqnext;
1408		} else {	/* group N bhs to fit into byt_per_blk */
1409			for (size = 0; bh != NULL && size < blksize_size[tapeblock_major][ti->blk_minor];) {
1410				ccw++;
1411				ccw->flags = CCW_FLAG_DC;
1412				ccw->cmd_code = READ_FORWARD;
1413				ccw->count = bh->b_size;
1414				set_normalized_cda (ccw, __pa (bh->b_data));
1415				size += bh->b_size;
1416				bh = bh->b_reqnext;
1417			}
1418			if (size != blksize_size[tapeblock_major][ti->blk_minor]) {
1419				PRINT_WARN ("Cannot fulfill small request %d vs. %d (%ld sects)\n",
1420					    size,
1421					    blksize_size[tapeblock_major][ti->blk_minor],
1422					    req->nr_sectors);
1423				kfree(data);
1424				tape_free_request (cqr);
1425				return NULL;
1426			}
1427		}
1428	}
1429	ccw -> flags &= ~(CCW_FLAG_DC);
1430	ccw -> flags |= (CCW_FLAG_CC);
1431	ccw++;
1432	ccw->cmd_code = NOP;
1433	ccw->flags = 0;
1434	ccw->count = 0;
1435	ccw->cda = (unsigned long) (&(ccw->cmd_code));
1436	ti->kernbuf = data;
1437	ti->userbuf = NULL;
1438	tapestate_set (ti, TS_BLOCK_INIT);
1439#ifdef TAPE_DEBUG
1440	debug_text_event (tape_debug_area,6,"xBREDccwg");
1441#endif /* TAPE_DEBUG */
1442	return cqr;
1443}
1444void tape34xx_free_bread (ccw_req_t* cqr,struct _tape_info_t* ti) {
1445    ccw1_t* ccw;
1446    for (ccw=(ccw1_t*)cqr->cpaddr;(ccw->flags & CCW_FLAG_CC)||(ccw->flags & CCW_FLAG_DC);ccw++)
1447	if ((ccw->cmd_code == MODE_SET_DB) ||
1448	    (ccw->cmd_code == LOCATE) ||
1449	    (ccw->cmd_code == READ_FORWARD))
1450	    clear_normalized_cda(ccw);
1451    tape_free_request(cqr);
1452    kfree(ti->kernbuf);
1453    ti->kernbuf=NULL;
1454}
1455
1456/* event handlers */
1457void
1458tape34xx_default_handler (tape_info_t * ti)
1459{
1460#ifdef TAPE_DEBUG
1461    debug_text_event (tape_debug_area,6,"xdefhandle");
1462#endif /* TAPE_DEBUG */
1463	PRINT_ERR ("TAPE34XX: An unexpected Unit Check occurred.\n");
1464	PRINT_ERR ("TAPE34XX: Please read Documentation/s390/TAPE and report it!\n");
1465	PRINT_ERR ("TAPE34XX: Current state is: %s",
1466		   (((tapestate_get (ti) < TS_SIZE) && (tapestate_get (ti) >= 0)) ?
1467		    state_verbose[tapestate_get (ti)] : "->UNKNOWN STATE<-"));
1468	tape_dump_sense (&ti->devstat);
1469	ti->rc = -EIO;
1470	ti->wanna_wakeup=1;
1471        switch (tapestate_get(ti)) {
1472        case TS_REW_RELEASE_INIT:
1473            tapestate_set(ti,TS_FAILED);
1474            wake_up (&ti->wq);
1475            break;
1476        case TS_BLOCK_INIT:
1477            tapestate_set(ti,TS_FAILED);
1478            schedule_tapeblock_exec_IO(ti);
1479            break;
1480        default:
1481            tapestate_set(ti,TS_FAILED);
1482            wake_up_interruptible (&ti->wq);
1483        }
1484}
1485
1486void
1487tape34xx_unexpect_uchk_handler (tape_info_t * ti)
1488{
1489	if ((ti->devstat.ii.sense.data[0] == 0x40) &&
1490	    (ti->devstat.ii.sense.data[1] == 0x40) &&
1491	    (ti->devstat.ii.sense.data[3] == 0x43)) {
1492		// no tape in the drive
1493	        PRINT_INFO ("Drive %d not ready. No volume loaded.\n", ti->rew_minor / 2);
1494#ifdef TAPE_DEBUG
1495	        debug_text_event (tape_debug_area,3,"xuuh nomed");
1496#endif /* TAPE_DEBUG */
1497		tapestate_set (ti, TS_FAILED);
1498		ti->rc = -ENOMEDIUM;
1499		ti->wanna_wakeup=1;
1500		wake_up_interruptible (&ti->wq);
1501	} else if ((ti->devstat.ii.sense.data[0] == 0x42) &&
1502		   (ti->devstat.ii.sense.data[1] == 0x44) &&
1503		   (ti->devstat.ii.sense.data[3] == 0x3b)) {
1504       	        PRINT_INFO ("Media in drive %d was changed!\n",
1505			    ti->rew_minor / 2);
1506#ifdef TAPE_DEBUG
1507		debug_text_event (tape_debug_area,3,"xuuh medchg");
1508#endif
1509		/* nothing to do. chan end & dev end will be reported when io is finished */
1510	} else {
1511#ifdef TAPE_DEBUG
1512	        debug_text_event (tape_debug_area,3,"xuuh unexp");
1513	        debug_text_event (tape_debug_area,3,"state:");
1514	        debug_text_event (tape_debug_area,3,((tapestate_get (ti) < TS_SIZE) &&
1515						     (tapestate_get (ti) >= 0)) ?
1516				  state_verbose[tapestate_get (ti)] :
1517				  "TS UNKNOWN");
1518#endif /* TAPE_DEBUG */
1519		tape34xx_default_handler (ti);
1520	}
1521}
1522
1523void
1524tape34xx_unused_done (tape_info_t * ti)
1525{
1526    if (ti->medium_is_unloaded) {
1527	// A medium was inserted in the drive!
1528#ifdef TAPE_DEBUG
1529	debug_text_event (tape_debug_area,6,"xuui med");
1530#endif /* TAPE_DEBUG */
1531	PRINT_WARN ("A medium was inserted into the tape.\n");
1532	ti->medium_is_unloaded=0;
1533    } else {
1534#ifdef TAPE_DEBUG
1535        debug_text_event (tape_debug_area,3,"unsol.irq!");
1536        debug_text_event (tape_debug_area,3,"dev end");
1537        debug_int_exception (tape_debug_area,3,ti->devinfo.irq);
1538#endif /* TAPE_DEBUG */
1539	PRINT_WARN ("Unsolicited IRQ (Device End) caught in unused state.\n");
1540	tape_dump_sense (&ti->devstat);
1541    }
1542}
1543
1544
1545void
1546tape34xx_idle_done (tape_info_t * ti)
1547{
1548    if (ti->medium_is_unloaded) {
1549	// A medium was inserted in the drive!
1550#ifdef TAPE_DEBUG
1551	debug_text_event (tape_debug_area,6,"xuud med");
1552#endif /* TAPE_DEBUG */
1553	PRINT_WARN ("A medium was inserted into the tape.\n");
1554	ti->medium_is_unloaded=0;
1555	wake_up_interruptible (&ti->wq);
1556    } else {
1557#ifdef TAPE_DEBUG
1558        debug_text_event (tape_debug_area,3,"unsol.irq!");
1559        debug_text_event (tape_debug_area,3,"dev end");
1560        debug_int_exception (tape_debug_area,3,ti->devinfo.irq);
1561#endif /* TAPE_DEBUG */
1562	PRINT_WARN ("Unsolicited IRQ (Device End) caught in idle state.\n");
1563	tape_dump_sense (&ti->devstat);
1564    }
1565}
1566
1567void
1568tape34xx_block_done (tape_info_t * ti)
1569{
1570#ifdef TAPE_DEBUG
1571        debug_text_event (tape_debug_area,6,"x:bREQdone");
1572#endif /* TAPE_DEBUG */
1573	tapestate_set(ti,TS_DONE);
1574	schedule_tapeblock_exec_IO(ti);
1575}
1576
1577void
1578tape34xx_bsf_init_done (tape_info_t * ti)
1579{
1580#ifdef TAPE_DEBUG
1581        debug_text_event (tape_debug_area,6,"bsf done");
1582#endif
1583	tapestate_set (ti, TS_DONE);
1584	ti->rc = 0;
1585	ti->wanna_wakeup=1;
1586	wake_up_interruptible (&ti->wq);
1587}
1588
1589void
1590tape34xx_dse_init_done (tape_info_t * ti)
1591{
1592#ifdef TAPE_DEBUG
1593        debug_text_event (tape_debug_area,6,"dse done");
1594#endif
1595	tapestate_set (ti, TS_DONE);
1596	ti->rc = 0;
1597	ti->wanna_wakeup=1;
1598	wake_up_interruptible (&ti->wq);
1599}
1600
1601void
1602tape34xx_fsf_init_done (tape_info_t * ti)
1603{
1604#ifdef TAPE_DEBUG
1605        debug_text_event (tape_debug_area,6,"fsf done");
1606#endif
1607	tapestate_set (ti, TS_DONE);
1608	ti->rc = 0;
1609	ti->wanna_wakeup=1;
1610	wake_up_interruptible (&ti->wq);
1611}
1612
1613void
1614tape34xx_fsb_init_done (tape_info_t * ti)
1615{
1616#ifdef TAPE_DEBUG
1617        debug_text_event (tape_debug_area,6,"fsb done");
1618#endif
1619	tapestate_set (ti, TS_DONE);
1620	ti->rc = 0;
1621	ti->wanna_wakeup=1;
1622	wake_up_interruptible (&ti->wq);
1623}
1624
1625void
1626tape34xx_bsb_init_done (tape_info_t * ti)
1627{
1628#ifdef TAPE_DEBUG
1629        debug_text_event (tape_debug_area,6,"bsb done");
1630#endif
1631	tapestate_set (ti, TS_DONE);
1632	ti->rc = 0;
1633	ti->wanna_wakeup=1;
1634	wake_up (&ti->wq);
1635}
1636
1637void
1638tape34xx_lbl_init_done (tape_info_t * ti)
1639{
1640#ifdef TAPE_DEBUG
1641        debug_text_event (tape_debug_area,6,"lbl done");
1642#endif
1643	tapestate_set (ti, TS_DONE);
1644	ti->rc = 0;
1645	//s390irq_spin_unlock(tape->devinfo.irq);
1646	ti->wanna_wakeup=1;
1647	wake_up (&ti->wq);
1648}
1649
1650void
1651tape34xx_nop_init_done (tape_info_t * ti)
1652{
1653#ifdef TAPE_DEBUG
1654        debug_text_event (tape_debug_area,6,"nop done..");
1655        debug_text_exception (tape_debug_area,6,"or rew/rel");
1656#endif
1657	tapestate_set (ti, TS_DONE);
1658	ti->rc = 0;
1659	//s390irq_spin_unlock(tape->devinfo.irq);
1660	ti->wanna_wakeup=1;
1661	wake_up (&ti->wq);
1662}
1663
1664void
1665tape34xx_rfo_init_done (tape_info_t * ti)
1666{
1667#ifdef TAPE_DEBUG
1668        debug_text_event (tape_debug_area,6,"rfo done");
1669#endif
1670	tapestate_set (ti, TS_DONE);
1671	ti->rc = 0;
1672	ti->wanna_wakeup=1;
1673	wake_up (&ti->wq);
1674}
1675
1676void
1677tape34xx_rbi_init_done (tape_info_t * ti)
1678{
1679	__u8 *data;
1680#ifdef TAPE_DEBUG
1681	int i;
1682#endif
1683	tapestate_set (ti, TS_FAILED);
1684	data = ti->kernbuf;
1685	ti->rc = data[3];
1686	ti->rc += 256 * data[2];
1687	ti->rc += 65536 * (data[1] & 0x3F);
1688#ifdef TAPE_DEBUG
1689        debug_text_event (tape_debug_area,6,"rbi done");
1690        debug_text_event (tape_debug_area,6,"data:");
1691	for (i=0;i<8;i++)
1692	    debug_int_event (tape_debug_area,6,data[i]);
1693#endif
1694	ti->wanna_wakeup=1;
1695	wake_up_interruptible (&ti->wq);
1696}
1697
1698void
1699tape34xx_rew_init_done (tape_info_t * ti)
1700{
1701#ifdef TAPE_DEBUG
1702        debug_text_event (tape_debug_area,6,"rew done");
1703#endif
1704	//BH: use irqsave
1705	//s390irq_spin_lock(tape->devinfo.irq);
1706	tapestate_set (ti, TS_DONE);
1707	ti->rc = 0;
1708	//s390irq_spin_unlock(tape->devinfo.irq);
1709	ti->wanna_wakeup=1;
1710	wake_up_interruptible (&ti->wq);
1711}
1712
1713void
1714tape34xx_rew_release_init_done (tape_info_t * ti)
1715{
1716#ifdef TAPE_DEBUG
1717        debug_text_event (tape_debug_area,6,"rewR done");
1718#endif
1719	tapestate_set (ti, TS_DONE);
1720	ti->rc = 0;
1721	//s390irq_spin_unlock(tape->devinfo.irq);
1722	ti->wanna_wakeup=1;
1723	wake_up (&ti->wq);
1724}
1725
1726void
1727tape34xx_run_init_done (tape_info_t * ti)
1728{
1729#ifdef TAPE_DEBUG
1730        debug_text_event (tape_debug_area,6,"rew done");
1731#endif
1732	tapestate_set (ti, TS_DONE);
1733	ti->rc = 0;
1734	ti->wanna_wakeup=1;
1735	wake_up_interruptible (&ti->wq);
1736}
1737
1738void
1739tape34xx_wri_init_done (tape_info_t * ti)
1740{
1741#ifdef TAPE_DEBUG
1742        debug_text_event (tape_debug_area,6,"wri done");
1743#endif
1744	//BH: use irqsave
1745	//s390irq_spin_lock(ti->devinfo.irq);
1746	tapestate_set (ti, TS_DONE);
1747	ti->rc = 0;
1748	//s390irq_spin_unlock(ti->devinfo.irq);
1749	ti->wanna_wakeup=1;
1750	wake_up_interruptible (&ti->wq);
1751}
1752
1753void
1754tape34xx_wtm_init_done (tape_info_t * ti)
1755{
1756#ifdef TAPE_DEBUG
1757        debug_text_event (tape_debug_area,3,"wtm done");
1758#endif
1759	tapestate_set (ti, TS_DONE);
1760	ti->rc = 0;
1761	ti->wanna_wakeup=1;
1762	wake_up_interruptible (&ti->wq);
1763}
1764
1765/* This function analyses the tape's sense-data in case of a unit-check. If possible,
1766   it tries to recover from the error. Else the user is informed about the problem. */
1767void
1768tape34xx_error_recovery (tape_info_t* ti)
1769{
1770    __u8* sense=ti->devstat.ii.sense.data;
1771    int inhibit_cu_recovery=0;
1772    int cu_type=ti->discipline->cu_type;
1773    if ((((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)&0x80) inhibit_cu_recovery=1;
1774    if (tapestate_get(ti)==TS_BLOCK_INIT) {
1775	// no recovery for block device, bottom half will retry...
1776	tape34xx_error_recovery_has_failed(ti,EIO);
1777	return;
1778    }
1779    if (sense[0]&SENSE_COMMAND_REJECT)
1780	switch (tapestate_get(ti)) {
1781	case TS_BLOCK_INIT:
1782	case TS_DSE_INIT:
1783	case TS_EGA_INIT:
1784	case TS_WRI_INIT:
1785	case TS_WTM_INIT:
1786	    if (sense[1]&SENSE_WRITE_PROTECT) {
1787		// trying to write, but medium is write protected
1788		tape34xx_error_recovery_has_failed(ti,EACCES);
1789		return;
1790	    }
1791	default:
1792	    tape34xx_error_recovery_HWBUG(ti,1);
1793	    return;
1794	}
1795    // special cases for various tape-states when reaching end of recorded area
1796    if (((sense[0]==0x08) || (sense[0]==0x10) || (sense[0]==0x12)) &&
1797	((sense[1]==0x40) || (sense[1]==0x0c)))
1798	switch (tapestate_get(ti)) {
1799	case TS_FSF_INIT:
1800	    // Trying to seek beyond end of recorded area
1801	    tape34xx_error_recovery_has_failed(ti,EIO);
1802	    return;
1803	case TS_LBL_INIT:
1804	    // Block could not be located.
1805	    tape34xx_error_recovery_has_failed(ti,EIO);
1806	    return;
1807	case TS_RFO_INIT:
1808	    // Try to read beyond end of recorded area -> 0 bytes read
1809	    tape34xx_error_recovery_has_failed(ti,0);
1810	    return;
1811	}
1812    // Sensing special bits
1813    if (sense[0]&SENSE_BUS_OUT_CHECK) {
1814	tape34xx_error_recovery_do_retry(ti);
1815	return;
1816    }
1817    if (sense[0]&SENSE_DATA_CHECK) {
1818	// hardware failure, damaged tape or improper operating conditions
1819	switch (sense[3]) {
1820	case 0x23:
1821	    // a read data check occurred
1822	    if ((sense[2]&SENSE_TAPE_SYNC_MODE) ||
1823		(inhibit_cu_recovery)) {
1824		// data check is not permanent, may be recovered.
1825		// We always use async-mode with cu-recovery, so this should *never* happen.
1826		tape34xx_error_recovery_HWBUG(ti,2);
1827		return;
1828	    } else {
1829		// data check is permanent, CU recovery has failed
1830		PRINT_WARN("Permanent read error, recovery failed!\n");
1831		tape34xx_error_recovery_has_failed(ti,EIO);
1832		return;
1833	    }
1834	case 0x25:
1835	    // a write data check occurred
1836	    if ((sense[2]&SENSE_TAPE_SYNC_MODE) ||
1837		(inhibit_cu_recovery)) {
1838		// data check is not permanent, may be recovered.
1839		// We always use async-mode with cu-recovery, so this should *never* happen.
1840		tape34xx_error_recovery_HWBUG(ti,3);
1841		return;
1842	    } else {
1843		// data check is permanent, cu-recovery has failed
1844		PRINT_WARN("Permanent write error, recovery failed!\n");
1845		tape34xx_error_recovery_has_failed(ti,EIO);
1846		return;
1847	    }
1848	case 0x26:
1849	    // Data Check (read opposite) occurred. We'll recover this.
1850	    tape34xx_error_recovery_read_opposite(ti);
1851	    return;
1852	case 0x28:
1853	    // The ID-Mark at the beginning of the tape could not be written. This is fatal, we'll report and exit.
1854	    PRINT_WARN("ID-Mark could not be written. Check your hardware!\n");
1855	    tape34xx_error_recovery_has_failed(ti,EIO);
1856	    return;
1857	case 0x31:
1858	    // Tape void. Tried to read beyond end of device. We'll report and exit.
1859	    PRINT_WARN("Try to read beyond end of recorded area!\n");
1860	    tape34xx_error_recovery_has_failed(ti,ENOSPC);
1861	    return;
1862	case 0x41:
1863	    // Record sequence error. cu detected incorrect block-id sequence on tape. We'll report and exit.
1864	    PRINT_WARN("Illegal block-id sequence found!\n");
1865	    tape34xx_error_recovery_has_failed(ti,EIO);
1866	    return;
1867	    default:
1868	    // well, all data checks for 3480 should result in one of the above erpa-codes. if not -> bug
1869	    // On 3490, other data-check conditions do exist.
1870		if (cu_type==0x3480) {
1871		    tape34xx_error_recovery_HWBUG(ti,4);
1872		    return;
1873		}
1874	}
1875    }
1876    if (sense[0]&SENSE_OVERRUN) {
1877	// A data overrun between cu and drive occurred. The channel speed is to slow! We'll report this and exit!
1878	switch (sense[3]) {
1879	case 0x40: // overrun error
1880	    PRINT_WARN ("Data overrun error between control-unit and drive. Use a faster channel connection, if possible! \n");
1881	    tape34xx_error_recovery_has_failed(ti,EIO);
1882	    return;
1883	default:
1884	    // Overrun bit is set, but erpa does not show overrun error. This is a bug.
1885	    tape34xx_error_recovery_HWBUG(ti,5);
1886	    return;
1887	}
1888    }
1889    if (sense[1]&SENSE_RECORD_SEQUENCE_ERR) {
1890	switch (sense[3]) {
1891	case 0x41:
1892	    // Record sequence error. cu detected incorrect block-id sequence on tape. We'll report and exit.
1893	    PRINT_WARN("Illegal block-id sequence found!\n");
1894	    tape34xx_error_recovery_has_failed(ti,EIO);
1895	    return;
1896	default:
1897	    // Record sequence error bit is set, but erpa does not show record sequence error. This is a bug.
1898	    tape34xx_error_recovery_HWBUG(ti,6);
1899	    return;
1900	}
1901    }
1902    // Sensing erpa codes
1903    switch (sense[3]) {
1904    case 0x00:
1905	// Everything is fine, but we got a unit check. Report and ignore!
1906	PRINT_WARN ("Non-error sense was found. Unit-check will be ignored, expect errors...\n");
1907	return;
1908    case 0x21:
1909	// Data streaming not operational. Cu switches to interlock mode, we reissue the command.
1910	PRINT_WARN ("Data streaming not operational. Switching to interlock-mode! \n");
1911	tape34xx_error_recovery_do_retry(ti);
1912	return;
1913    case 0x22:
1914	// Path equipment check. Might be drive adapter error, buffer error on the lower interface, internal path not useable, or error during cartridge load.
1915	// All of the above are not recoverable
1916	PRINT_WARN ("A path equipment check occurred. One of the following conditions occurred:\n");
1917	PRINT_WARN ("drive adapter error,buffer error on the lower interface, internal path not useable, error during cartridge load.\n");
1918	tape34xx_error_recovery_has_failed(ti,EIO);
1919	return;
1920    case 0x23:
1921	// Read data check. Should have been be covered earlier -> Bug!
1922	tape34xx_error_recovery_HWBUG(ti,7);
1923	return;
1924    case 0x24:
1925	// Load display check. Load display was command was issued, but the drive is displaying a drive check message. Can be threated as "device end".
1926	tape34xx_error_recovery_succeded(ti);
1927	return;
1928    case 0x25:
1929	// Write data check. Should have been covered earlier -> Bug!
1930	tape34xx_error_recovery_HWBUG(ti,8);
1931	return;
1932    case 0x26:
1933	// Data check (read opposite). Should have been covered earlier -> Bug!
1934	tape34xx_error_recovery_HWBUG(ti,9);
1935	return;
1936    case 0x27:
1937	// Command reject. May indicate illegal channel program or buffer over/underrun.
1938	// Since all channel programms are issued by this driver and ought be correct,
1939	// we assume a over/underrun situaltion and retry the channel program.
1940	tape34xx_error_recovery_do_retry(ti);
1941	return;
1942    case 0x28:
1943	// Write id mark check. Should have beed covered earlier -> bug!
1944	tape34xx_error_recovery_HWBUG(ti,10);
1945	return;
1946    case 0x29:
1947	// Function incompatible. Either idrc is on but hardware not capable doing idrc
1948	// or a perform subsystem func is issued and the cu is not online. Anyway, this
1949	// cannot be recovered and is an I/O error.
1950	PRINT_WARN ("Function incompatible. Try to switch off idrc! \n");
1951	tape34xx_error_recovery_has_failed(ti,EIO);
1952	return;
1953    case 0x2a:
1954	// Unsolicited environmental data. An internal counter overflows, we can ignore
1955	// this and reissue the cmd.
1956	tape34xx_error_recovery_do_retry(ti);
1957	return;
1958    case 0x2b:
1959	// Environmental data present. Indicates either unload completed ok or read buffered
1960	// log command completed ok.
1961	if (tapestate_get(ti)==TS_RUN_INIT) {
1962	    // Rewind unload completed ok.
1963	    tape34xx_error_recovery_succeded(ti);
1964	    return;
1965	}
1966	// Since we do not issue read buffered log commands, this should never occur -> bug.
1967	tape34xx_error_recovery_HWBUG(ti,11);
1968	return;
1969    case 0x2c:
1970	// Permanent equipment check. cu has tried recovery, but did not succeed. This is an
1971	// I/O error.
1972	tape34xx_error_recovery_has_failed(ti,EIO);
1973	return;
1974    case 0x2d:
1975	// Data security erase failure.
1976	if (tapestate_get(ti)==TS_DSE_INIT) {
1977	    // report an I/O error
1978	    tape34xx_error_recovery_has_failed(ti,EIO);
1979	    return;
1980	}
1981	// Data security erase failure, but no such command issued. This is a bug.
1982	tape34xx_error_recovery_HWBUG(ti,12);
1983	return;
1984    case 0x2e:
1985	// Not capable. This indicates either that the drive fails reading the format id mark
1986	// or that that format specified is not supported by the drive. We write a message and
1987	// return an I/O error.
1988	PRINT_WARN("Drive not capable processing the tape format!");
1989	tape34xx_error_recovery_has_failed(ti,EMEDIUMTYPE);
1990	return;
1991    case 0x2f:
1992	// This erpa is reserved. This is a bug.
1993	tape34xx_error_recovery_HWBUG(ti,13);
1994	return;
1995    case 0x30:
1996	// The medium is write protected, while trying to write on it. We'll report this.
1997	PRINT_WARN("Medium is write protected!\n");
1998	tape34xx_error_recovery_has_failed(ti,EACCES);
1999	return;
2000    case 0x31:
2001	// Tape void. Should have beed covered ealier -> bug
2002	tape34xx_error_recovery_HWBUG(ti,14);
2003	return;
2004    case 0x32:
2005	// Tension loss. We cannot recover this, it's an I/O error.
2006	PRINT_WARN("The drive lost tape tension.\n");
2007	tape34xx_error_recovery_has_failed(ti,EIO);
2008	return;
2009    case 0x33:
2010	// Load Failure. The catridge was not inserted correctly or the tape is not threaded
2011	// correctly. We cannot recover this, the user has to reload the catridge.
2012	PRINT_WARN("Cartridge load failure. Reload the cartridge and try again.\n");
2013	tape34xx_error_recovery_has_failed(ti,EIO);
2014	return;
2015    case 0x34:
2016	// Unload failure. The drive cannot maintain tape tension and control tape movement
2017	// during an unload operation.
2018	PRINT_WARN("Failure during cartridge unload. Please try manually.\n");
2019	if (tapestate_get(ti)!=TS_RUN_INIT) {
2020	    tape34xx_error_recovery_HWBUG(ti,15);
2021	    return;
2022	}
2023	tape34xx_error_recovery_has_failed(ti,EIO);
2024	return;
2025    case 0x35:
2026	// Drive equipment check. One of the following:
2027	// - cu cannot recover from a drive detected error
2028	// - a check code message is displayed on drive message/load displays
2029	// - the cartridge loader does not respond correctly
2030	// - a failure occurs during an index, load, or unload cycle
2031	PRINT_WARN("Equipment check! Please check the drive and the cartridge loader.\n");
2032	tape34xx_error_recovery_has_failed(ti,EIO);
2033	return;
2034    case 0x36:
2035	switch (cu_type) {
2036	case 0x3480:
2037	    // This erpa is reserved for 3480 -> BUG
2038	    tape34xx_error_recovery_HWBUG(ti,16);
2039	    return;
2040	case 0x3490:
2041	    // End of data. This is a permanent I/O error, which cannot be recovered.
2042	    // A read-type command has reached the end-of-data mark.
2043	    tape34xx_error_recovery_has_failed(ti,EIO);
2044	    return;
2045	}
2046    case 0x37:
2047	// Tape length error. The tape is shorter than reported in the beginning-of-tape data.
2048	PRINT_WARN("Tape length error.\n");
2049	tape34xx_error_recovery_has_failed(ti,EIO);
2050	return;
2051    case 0x38:
2052	// Physical end of tape. A read/write operation reached the physical end of tape.
2053	if (tapestate_get(ti)==TS_WRI_INIT ||
2054	    tapestate_get(ti)==TS_DSE_INIT ||
2055	    tapestate_get(ti)==TS_EGA_INIT ||
2056	    tapestate_get(ti)==TS_WTM_INIT){
2057 	    tape34xx_error_recovery_has_failed(ti,ENOSPC);
2058	} else {
2059	    tape34xx_error_recovery_has_failed(ti,EIO);
2060	}
2061	return;
2062    case 0x39:
2063	// Backward at BOT. The drive is at BOT and is requestet to move backward.
2064	tape34xx_error_recovery_has_failed(ti,EIO);
2065	return;
2066    case 0x3a:
2067	// Drive switched not ready, but the command needs the drive to be ready.
2068	PRINT_WARN("Drive not ready. Turn the ready/not ready switch to ready position and try again.\n");
2069	tape34xx_error_recovery_has_failed(ti,EIO);
2070	return;
2071    case 0x3b:
2072	// Manual rewind or unload. This causes an I/O error.
2073	PRINT_WARN("Medium was rewound or unloaded manually. Expect errors! Please do only use the mtoffl and mtrew ioctl to unload tapes or rewind tapes.\n");
2074	tape34xx_error_recovery_has_failed(ti,EIO);
2075	return;
2076    case 0x3c:
2077    case 0x3d:
2078    case 0x3e:
2079    case 0x3f:
2080	// These erpas are reserved -> BUG
2081	tape34xx_error_recovery_HWBUG(ti,17);
2082	return;
2083    case 0x40:
2084	// Overrun error. This should have been covered earlier -> bug.
2085	tape34xx_error_recovery_HWBUG(ti,18);
2086	return;
2087    case 0x41:
2088	// Record sequence error. This should have been covered earlier -> bug.
2089	tape34xx_error_recovery_HWBUG(ti,19);
2090	return;
2091    case 0x42:
2092	// Degraded mode. A condition that can cause degraded performace is detected.
2093	PRINT_WARN("Subsystem is running in degraded mode. This may compromise your performace.\n");
2094	tape34xx_error_recovery_do_retry(ti);
2095	return;
2096    case 0x43:
2097	// Drive not ready. Probably swith the ready/not ready switch to ready?
2098	PRINT_WARN("The drive is not ready. Maybe no medium in?\n");
2099	tape34xx_error_recovery_has_failed(ti,ENOMEDIUM);
2100	return;
2101    case 0x44:
2102	// Locate Block unsuccessfull. We'll report this.
2103	if ((tapestate_get(ti)!=TS_BLOCK_INIT) &&
2104	    (tapestate_get(ti)!=TS_LBL_INIT)) {
2105	    tape34xx_error_recovery_HWBUG(ti,20); // No locate block was issued...
2106	    return;
2107	}
2108	tape34xx_error_recovery_has_failed(ti,EIO);
2109	return;
2110    case 0x45:
2111	// The drive is assigned elsewhere [to a different channel path/computer].
2112	PRINT_WARN("The drive is assigned elsewhere.\n");
2113	tape34xx_error_recovery_has_failed(ti,EIO);
2114	return;
2115    case 0x46:
2116	// Drive not online. Drive may be switched offline, the power supply may be switched off
2117	// or the drive address may not be set correctly.
2118	PRINT_WARN("The drive is not online.");
2119	tape34xx_error_recovery_has_failed(ti,EIO);
2120	return;
2121    case 0x47:
2122	// Volume fenced. cu reports volume integrity is lost!
2123	PRINT_WARN("Volume fenced. The volume integrity is lost! \n");
2124	tape34xx_error_recovery_has_failed(ti,EIO);
2125	return;
2126    case 0x48:
2127	// Log sense data and retry request. We'll do so...
2128	tape34xx_error_recovery_do_retry(ti);
2129	return;
2130    case 0x49:
2131	// Bus out check. A parity check error on the bus was found.	PRINT_WARN("Bus out check. A data transfer over the bus was corrupted.\n");
2132	tape34xx_error_recovery_has_failed(ti,EIO);
2133	return;
2134    case 0x4a:
2135	// Control unit erp failed. We'll report this.
2136	PRINT_WARN("The control unit failed recovering an I/O error.\n");
2137	tape34xx_error_recovery_has_failed(ti,EIO);
2138	return;
2139    case 0x4b:
2140	// Cu and drive incompatible. The drive requests micro-program patches, which are not available on the cu.
2141	PRINT_WARN("The drive needs microprogram patches from the control unit, which are not available.\n");
2142	tape34xx_error_recovery_has_failed(ti,EIO);
2143	return;
2144    case 0x4c:
2145	// Recovered Check-One failure. Cu develops a hardware error, but is able to recover. We'll reissue the command.
2146	tape34xx_error_recovery_do_retry(ti);
2147	return;
2148    case 0x4d:
2149	switch (cu_type) {
2150	case 0x3480:
2151	    // This erpa is reserved for 3480 -> bug
2152      	    tape34xx_error_recovery_HWBUG(ti,21);
2153	    return;
2154	case 0x3490:
2155	    // Resetting event received. Since the driver does not support resetting event recovery
2156	    // (which has to be handled by the I/O Layer), we'll report and retry our command.
2157	    tape34xx_error_recovery_do_retry(ti);
2158	    return;
2159	}
2160    case 0x4e:
2161	switch (cu_type) {
2162	case 0x3480:
2163	    // This erpa is reserved for 3480 -> bug.
2164	    tape34xx_error_recovery_HWBUG(ti,22);
2165	    return;
2166	case 0x3490:
2167	    // Maximum block size exeeded. This indicates, that the block to be written is larger
2168	    // than allowed for buffered mode. We'll report this...
2169	    PRINT_WARN("Maximum block size for buffered mode exceeded.\n");
2170	    tape34xx_error_recovery_has_failed(ti,ENOBUFS);
2171	    return;
2172	}
2173    case 0x4f:
2174	// These erpas are reserved -> bug
2175	tape34xx_error_recovery_HWBUG(ti,23);
2176	return;
2177    case 0x50:
2178	// Read buffered log (Overflow). Cu is running in extended beffered log mode, and a counter overflows.
2179	// This should never happen, since we're never running in extended buffered log mode -> bug.
2180	tape34xx_error_recovery_do_retry(ti);
2181	return;
2182    case 0x51:
2183	// Read buffered log (EOV). EOF processing occurs while the cu is in extended buffered log mode.
2184	// This should never happen, since we're never running in extended buffered log mode -> bug.
2185	tape34xx_error_recovery_do_retry(ti);
2186	return;
2187    case 0x52:
2188	// End of Volume complete. Rewind unload completed ok. We'll report to the user...
2189	if (tapestate_get(ti)!=TS_RUN_INIT) {
2190	    tape34xx_error_recovery_HWBUG(ti,24);
2191	    return;
2192	}
2193	tape34xx_error_recovery_succeded(ti);
2194	return;
2195    case 0x53:
2196	// Global command intercept. We'll have to reissue our command.
2197	tape34xx_error_recovery_do_retry(ti);
2198	return;
2199    case 0x54:
2200	// Channel interface recovery (temporary). This can be recovered by reissuing the command.
2201	tape34xx_error_recovery_do_retry(ti);
2202	return;
2203    case 0x55:
2204	// Channel interface recovery (permanent). This cannot be recovered, we'll inform the user.
2205	PRINT_WARN("A permanent channel interface error occurred.\n");
2206	tape34xx_error_recovery_has_failed(ti,EIO);
2207	return;
2208    case 0x56:
2209	// Channel protocol error. This cannot be recovered.
2210	PRINT_WARN("A channel protocol error occurred.\n");
2211	tape34xx_error_recovery_has_failed(ti,EIO);
2212	return;
2213    case 0x57:
2214	switch (cu_type) {
2215	case 0x3480:
2216	    // Attention intercept. We have to reissue the command.
2217	    PRINT_WARN("An attention intercept occurred, which will be recovered.\n");
2218	    tape34xx_error_recovery_do_retry(ti);
2219	    return;
2220	case 0x3490:
2221	    // Global status intercept. We have to reissue the command.
2222	    PRINT_WARN("An global status intercept was received, which will be recovered.\n");
2223	    tape34xx_error_recovery_do_retry(ti);
2224	    return;
2225	}
2226    case 0x58:
2227    case 0x59:
2228	// These erpas are reserved -> bug.
2229	tape34xx_error_recovery_HWBUG(ti,25);
2230	return;
2231    case 0x5a:
2232	// Tape length incompatible. The tape inserted is too long,
2233	// which could cause damage to the tape or the drive.
2234	PRINT_WARN("Tape length incompatible [should be IBM Cartridge System Tape]. May cause damage to drive or tape.n");
2235	tape34xx_error_recovery_has_failed(ti,EIO);
2236	return;
2237    case 0x5b:
2238	// Format 3480 XF incompatible
2239	if (sense[1]&SENSE_BEGINNING_OF_TAPE) {
2240	    // Everything is fine. The tape will be overwritten in a different format.
2241	    tape34xx_error_recovery_do_retry(ti);
2242	    return;
2243	}
2244	PRINT_WARN("Tape format is incompatible to the drive, which writes 3480-2 XF.\n");
2245	tape34xx_error_recovery_has_failed(ti,EIO);
2246	return;
2247    case 0x5c:
2248	// Format 3480-2 XF incompatible
2249	PRINT_WARN("Tape format is incompatible to the drive. The drive cannot access 3480-2 XF volumes.\n");
2250	tape34xx_error_recovery_has_failed(ti,EIO);
2251	return;
2252    case 0x5d:
2253	// Tape length violation.
2254	PRINT_WARN("Tape length violation [should be IBM Enhanced Capacity Cartridge System Tape]. May cause damage to drive or tape.\n");
2255	tape34xx_error_recovery_has_failed(ti,EMEDIUMTYPE);
2256	return;
2257    case 0x5e:
2258	// Compaction algorithm incompatible.
2259	PRINT_WARN("The volume is recorded using an incompatible compaction algorith, which is not supported by the control unit.\n");
2260	tape34xx_error_recovery_has_failed(ti,EMEDIUMTYPE);
2261	return;
2262    default:
2263	// Reserved erpas -> bug
2264	tape34xx_error_recovery_HWBUG(ti,26);
2265	return;
2266    }
2267}
2268
2269void tape34xx_error_recovery_has_failed (tape_info_t* ti,int error_id) {
2270#ifdef TAPE_DEBUG
2271    debug_text_event (tape_debug_area,3,"xerp fail");
2272    debug_text_event (tape_debug_area,3,(((tapestate_get (ti) < TS_SIZE) &&
2273		      (tapestate_get (ti) >= 0)) ?
2274	state_verbose[tapestate_get (ti)] : "UNKNOWN"));
2275#endif
2276    if ((tapestate_get(ti)!=TS_UNUSED) && (tapestate_get(ti)!=TS_IDLE)) {
2277	tape_dump_sense(&ti->devstat);
2278	ti->rc = -error_id;
2279	ti->wanna_wakeup=1;
2280	switch (tapestate_get(ti)) {
2281	case TS_REW_RELEASE_INIT:
2282	case TS_RFO_INIT:
2283	case TS_RBA_INIT:
2284	    tapestate_set(ti,TS_FAILED);
2285	    wake_up (&ti->wq);
2286	    break;
2287	case TS_BLOCK_INIT:
2288	    tapestate_set(ti,TS_FAILED);
2289	    schedule_tapeblock_exec_IO(ti);
2290	    break;
2291	default:
2292	    tapestate_set(ti,TS_FAILED);
2293	    wake_up_interruptible (&ti->wq);
2294	}
2295    } else {
2296	PRINT_WARN("Recieved an unsolicited IRQ.\n");
2297	tape_dump_sense(&ti->devstat);
2298    }
2299}
2300
2301void tape34xx_error_recovery_succeded(tape_info_t* ti) {
2302#ifdef TAPE_DEBUG
2303    debug_text_event (tape_debug_area,3,"xerp done");
2304    debug_text_event (tape_debug_area,3,(((tapestate_get (ti) < TS_SIZE) &&
2305		      (tapestate_get (ti) >= 0)) ?
2306	state_verbose[tapestate_get (ti)] : "UNKNOWN"));
2307#endif
2308    if ((tapestate_get(ti)!=TS_UNUSED) && (tapestate_get(ti)!=TS_DONE)) {
2309	tapestate_event (ti, TE_DONE);
2310    } else {
2311	PRINT_WARN("Recieved an unsolicited IRQ.\n");
2312	tape_dump_sense(&ti->devstat);
2313    }
2314}
2315
2316void tape34xx_error_recovery_do_retry(tape_info_t* ti) {
2317#ifdef TAPE_DEBUG
2318    debug_text_event (tape_debug_area,3,"xerp retr");
2319    debug_text_event (tape_debug_area,3,(((tapestate_get (ti) < TS_SIZE) &&
2320					  (tapestate_get (ti) >= 0)) ?
2321					 state_verbose[tapestate_get (ti)] : "UNKNOWN"));
2322#endif
2323    if ((tapestate_get(ti)!=TS_UNUSED) && (tapestate_get(ti)!=TS_IDLE)) {
2324	tape_dump_sense(&ti->devstat);
2325	while (do_IO (ti->devinfo.irq, ti->cqr->cpaddr, (unsigned long) ti->cqr, 0x00, ti->cqr->options));
2326    } else {
2327	PRINT_WARN("Recieved an unsolicited IRQ.\n");
2328	tape_dump_sense(&ti->devstat);
2329    }
2330}
2331
2332void
2333tape34xx_error_recovery_read_opposite (tape_info_t* ti) {
2334    switch (tapestate_get(ti)) {
2335    case TS_RFO_INIT:
2336	// We did read forward, but the data could not be read *correctly*.
2337	// We will read backward and then skip forward again.
2338	ti->cqr=tape34xx_read_opposite(ti,0);
2339	if (ti->cqr==NULL)
2340	    tape34xx_error_recovery_has_failed(ti,EIO);
2341	else
2342	    tape34xx_error_recovery_do_retry(ti);
2343	break;
2344    case TS_RBA_INIT:
2345	// We tried to read forward and backward, but hat no success -> failed.
2346	tape34xx_error_recovery_has_failed(ti,EIO);
2347	break;
2348    case TS_BLOCK_INIT:
2349	tape34xx_error_recovery_do_retry(ti);
2350	break;
2351    default:
2352	PRINT_WARN("read_opposite_recovery_called_with_state:%s\n",
2353		   (((tapestate_get (ti) < TS_SIZE) &&
2354		     (tapestate_get (ti) >= 0)) ?
2355		    state_verbose[tapestate_get (ti)] : "UNKNOWN"));
2356    }
2357}
2358
2359void
2360tape34xx_error_recovery_HWBUG (tape_info_t* ti,int condno) {
2361    devstat_t* stat=&ti->devstat;
2362    PRINT_WARN("An unexpected condition #%d was caught in tape error recovery.\n",condno);
2363    PRINT_WARN("Please report this incident.\n");
2364    PRINT_WARN("State of the tape:%s\n",
2365	       (((tapestate_get (ti) < TS_SIZE) &&
2366		 (tapestate_get (ti) >= 0)) ?
2367		state_verbose[tapestate_get (ti)] : "UNKNOWN"));
2368    PRINT_INFO ("Sense data: %02X%02X%02X%02X %02X%02X%02X%02X "
2369		" %02X%02X%02X%02X %02X%02X%02X%02X \n",
2370		stat->ii.sense.data[0], stat->ii.sense.data[1],
2371		stat->ii.sense.data[2], stat->ii.sense.data[3],
2372		stat->ii.sense.data[4], stat->ii.sense.data[5],
2373		stat->ii.sense.data[6], stat->ii.sense.data[7],
2374		stat->ii.sense.data[8], stat->ii.sense.data[9],
2375		stat->ii.sense.data[10], stat->ii.sense.data[11],
2376		stat->ii.sense.data[12], stat->ii.sense.data[13],
2377		stat->ii.sense.data[14], stat->ii.sense.data[15]);
2378    PRINT_INFO ("Sense data: %02X%02X%02X%02X %02X%02X%02X%02X "
2379		" %02X%02X%02X%02X %02X%02X%02X%02X \n",
2380		stat->ii.sense.data[16], stat->ii.sense.data[17],
2381		stat->ii.sense.data[18], stat->ii.sense.data[19],
2382		stat->ii.sense.data[20], stat->ii.sense.data[21],
2383		stat->ii.sense.data[22], stat->ii.sense.data[23],
2384		stat->ii.sense.data[24], stat->ii.sense.data[25],
2385		stat->ii.sense.data[26], stat->ii.sense.data[27],
2386		stat->ii.sense.data[28], stat->ii.sense.data[29],
2387		stat->ii.sense.data[30], stat->ii.sense.data[31]);
2388    tape34xx_error_recovery_has_failed(ti,EIO);
2389}
2390