1/*
2 * File...........: linux/drivers/s390/block/dasd.c
3 * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
4 *                  Horst Hummel <Horst.Hummel@de.ibm.com>
5 *                  Carsten Otte <Cotte@de.ibm.com>
6 * Bugreports.to..: <Linux390@de.ibm.com>
7 * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999-2001
8 *
9 * History of changes (starts July 2000)
10 * 11/09/00 complete redesign after code review
11 * 02/01/01 added dynamic registration of ioctls
12 *          fixed bug in registration of new majors
13 *          fixed handling of request during dasd_end_request
14 *          fixed handling of plugged queues
15 *          fixed partition handling and HDIO_GETGEO
16 *          fixed traditional naming scheme for devices beyond 702
17 *          fixed some race conditions related to modules
18 *          added devfs suupport
19 * 03/06/01 refined dynamic attach/detach for leaving devices which are online.
20 * 03/09/01 refined dynamic modifiaction of devices
21 * 03/12/01 moved policy in dasd_format to dasdfmt (renamed BIODASDFORMAT)
22 * 03/19/01 added BIODASDINFO-ioctl
23 *          removed 2.2 compatibility
24 * 04/27/01 fixed PL030119COT (dasd_disciplines does not work)
25 * 04/30/01 fixed PL030146HSM (module locking with dynamic ioctls)
26 *          fixed PL030130SBA (handling of invalid ranges)
27 * 05/02/01 fixed PL030145SBA (killing dasdmt)
28 *          fixed PL030149SBA (status of 'accepted' devices)
29 *          fixed PL030146SBA (BUG in ibm.c after adding device)
30 *          added BIODASDPRRD ioctl interface
31 * 05/11/01 fixed  PL030164MVE (trap in probeonly mode)
32 * 05/15/01 fixed devfs support for unformatted devices
33 * 06/26/01 hopefully fixed PL030172SBA,PL030234SBA
34 * 07/09/01 fixed PL030324MSH (wrong statistics output)
35 * 07/16/01 merged in new fixes for handling low-mem situations
36 */
37
38#include <linux/config.h>
39#include <linux/version.h>
40#include <linux/kmod.h>
41#include <linux/init.h>
42#include <linux/blkdev.h>
43#include <linux/stddef.h>
44#include <linux/kernel.h>
45#include <linux/tqueue.h>
46#include <linux/timer.h>
47#include <linux/slab.h>
48#include <linux/genhd.h>
49#include <linux/hdreg.h>
50#include <linux/interrupt.h>
51#include <linux/ctype.h>
52#ifdef CONFIG_PROC_FS
53#include <linux/proc_fs.h>
54#endif				/* CONFIG_PROC_FS */
55#include <linux/spinlock.h>
56#include <linux/devfs_fs_kernel.h>
57#include <linux/blkpg.h>
58#include <linux/wait.h>
59
60#include <asm/ccwcache.h>
61#include <asm/debug.h>
62
63#include <asm/atomic.h>
64#include <asm/delay.h>
65#include <asm/io.h>
66#include <asm/semaphore.h>
67#include <asm/ebcdic.h>
68#include <asm/uaccess.h>
69#include <asm/irq.h>
70#include <asm/s390_ext.h>
71#include <asm/s390dyn.h>
72#include <asm/idals.h>
73#include <asm/dasd.h>
74
75#include "dasd_int.h"
76
77#ifdef CONFIG_DASD_ECKD
78#include "dasd_eckd.h"
79#endif				/*  CONFIG_DASD_ECKD */
80#ifdef CONFIG_DASD_FBA
81#include "dasd_fba.h"
82#endif				/*  CONFIG_DASD_FBA */
83#ifdef CONFIG_DASD_DIAG
84#include "dasd_diag.h"
85#endif				/*  CONFIG_DASD_DIAG */
86
87/* SECTION: exported variables of dasd.c */
88
89debug_info_t *dasd_debug_area;
90
91MODULE_AUTHOR ("Holger Smolinski <Holger.Smolinski@de.ibm.com>");
92MODULE_DESCRIPTION ("Linux on S/390 DASD device driver,"
93		    " Copyright 2000 IBM Corporation");
94MODULE_SUPPORTED_DEVICE ("dasd");
95MODULE_PARM (dasd, "1-" __MODULE_STRING (256) "s");
96MODULE_PARM (dasd_disciplines, "1-" __MODULE_STRING (8) "s");
97EXPORT_SYMBOL (dasd_chanq_enq_head);
98EXPORT_SYMBOL (dasd_debug_area);
99EXPORT_SYMBOL (dasd_chanq_enq);
100EXPORT_SYMBOL (dasd_chanq_deq);
101EXPORT_SYMBOL (dasd_discipline_add);
102EXPORT_SYMBOL (dasd_discipline_del);
103EXPORT_SYMBOL (dasd_start_IO);
104EXPORT_SYMBOL (dasd_term_IO);
105EXPORT_SYMBOL (dasd_schedule_bh);
106EXPORT_SYMBOL (dasd_int_handler);
107EXPORT_SYMBOL (dasd_oper_handler);
108EXPORT_SYMBOL (dasd_alloc_request);
109EXPORT_SYMBOL (dasd_free_request);
110EXPORT_SYMBOL (dasd_ioctl_no_register);
111EXPORT_SYMBOL (dasd_ioctl_no_unregister);
112EXPORT_SYMBOL (dasd_default_erp_action);
113EXPORT_SYMBOL (dasd_default_erp_postaction);
114EXPORT_SYMBOL (dasd_sleep_on_req);
115EXPORT_SYMBOL (dasd_set_normalized_cda);
116EXPORT_SYMBOL (dasd_device_from_kdev);
117
118/* SECTION: Constant definitions to be used within this file */
119
120#define PRINTK_HEADER DASD_NAME":"
121#undef  DASD_PROFILE            /* fill profile information - used for */
122                                /* statistics and perfomance           */
123
124#define DASD_MIN_SIZE_FOR_QUEUE 32
125#undef CONFIG_DYNAMIC_QUEUE_MIN_SIZE
126#define DASD_CHANQ_MAX_SIZE 6
127
128/* SECTION: prototypes for static functions of dasd.c */
129
130static request_fn_proc do_dasd_request;
131static int dasd_set_device_level (unsigned int, dasd_discipline_t *, int);
132static request_queue_t *dasd_get_queue (kdev_t kdev);
133static void cleanup_dasd (void);
134static void dasd_plug_device (dasd_device_t * device);
135static int dasd_fillgeo (int kdev, struct hd_geometry *geo);
136static void dasd_enable_ranges (dasd_range_t *, dasd_discipline_t *, int);
137static void dasd_disable_ranges (dasd_range_t *, dasd_discipline_t *, int, int);
138static void dasd_enable_single_device ( unsigned long);
139static inline int dasd_state_init_to_ready(dasd_device_t*);
140static inline void dasd_setup_partitions ( dasd_device_t *);
141static inline void dasd_destroy_partitions ( dasd_device_t *);
142static inline int dasd_setup_blkdev(dasd_device_t*);
143static void dasd_deactivate_queue (dasd_device_t *);
144static inline int dasd_disable_blkdev(dasd_device_t*);
145static void dasd_flush_chanq ( dasd_device_t * device, int destroy );
146static void dasd_flush_request_queues ( dasd_device_t * device, int destroy );
147static struct block_device_operations dasd_device_operations;
148static inline dasd_device_t ** dasd_device_from_devno (int);
149static void dasd_process_queues (dasd_device_t * device);
150/* SECTION: static variables of dasd.c */
151
152static devfs_handle_t dasd_devfs_handle;
153static wait_queue_head_t dasd_init_waitq;
154static atomic_t dasd_init_pending = ATOMIC_INIT (0);
155
156#ifdef CONFIG_DASD_DYNAMIC
157
158/* SECTION: managing dynamic configuration of dasd_driver */
159
160static struct list_head dasd_devreg_head = LIST_HEAD_INIT (dasd_devreg_head);
161
162/*
163 * function: dasd_create_devreg
164 * creates a dasd_devreg_t related to a devno
165 */
166static inline dasd_devreg_t *
167dasd_create_devreg (int devno)
168{
169	dasd_devreg_t *r = kmalloc (sizeof (dasd_devreg_t), GFP_KERNEL);
170	if (r != NULL) {
171		memset (r, 0, sizeof (dasd_devreg_t));
172		r->devreg.ci.devno = devno;
173		r->devreg.flag = DEVREG_TYPE_DEVNO;
174		r->devreg.oper_func = dasd_oper_handler;
175	}
176	return r;
177}
178
179/*
180 * function: dasd_destroy_devreg
181 * destroys the dasd_devreg_t given as argument
182 */
183static inline void
184dasd_destroy_devreg (dasd_devreg_t * devreg)
185{
186	kfree (devreg);
187}
188
189#endif				/* CONFIG_DASD_DYNAMIC */
190
191/* SECTION: managing setup of dasd_driver */
192
193/* default setting is probeonly, autodetect */
194static int dasd_probeonly = 1;	/* is true, when probeonly mode is active */
195static int dasd_autodetect = 1;	/* is true, when autodetection is active */
196
197static dasd_range_t dasd_range_head =
198    { list:LIST_HEAD_INIT (dasd_range_head.list) };
199static spinlock_t range_lock = SPIN_LOCK_UNLOCKED;
200
201static inline dasd_range_t *
202dasd_create_range (int from, int to, int features)
203{
204	dasd_range_t *range = NULL;
205        int i;
206
207	if ( from > to ) {
208                printk (KERN_WARNING PRINTK_HEADER
209                        "Adding device range %04x-%04x: range invalid, ignoring.\n",
210                        from,
211                        to);
212
213		return NULL;
214	}
215	for (i=from;i<=to;i++) {
216                if (dasd_device_from_devno(i)) {
217                        printk (KERN_WARNING PRINTK_HEADER
218                                "device range %04x-%04x: device %04x is already in a range.\n",
219                                from,
220                                to,
221                                i);
222                }
223        }
224	range = (dasd_range_t *) kmalloc (sizeof (dasd_range_t), GFP_KERNEL);
225	if (range == NULL)
226		return NULL;
227	memset (range, 0, sizeof (dasd_range_t));
228	range->from = from;
229        range->to = to;
230        range->features = features;
231	return range;
232}
233
234/*
235 * function dasd_destroy_range
236 * destroy a range allocated wit dasd_crate_range
237 * CAUTION: must not be callen in arunning sysztem, because it destroys
238 * the mapping of DASDs
239 */
240static inline void
241dasd_destroy_range (dasd_range_t * range)
242{
243	kfree (range);
244}
245
246/*
247 * function: dasd_append_range
248 * appends the range given as argument to the list anchored at dasd_range_head.
249 */
250static inline void
251dasd_append_range (dasd_range_t * range)
252{
253	long flags;
254
255	spin_lock_irqsave (&range_lock, flags);
256	list_add_tail (&range->list, &dasd_range_head.list);
257	spin_unlock_irqrestore (&range_lock, flags);
258}
259
260/*
261 * function dasd_dechain_range
262 * removes a range from the chain of ranges
263 * CAUTION: must not be called in a running system because it destroys
264 * the mapping of devices
265 */
266static inline void
267dasd_dechain_range (dasd_range_t * range)
268{
269	unsigned long flags;
270
271	spin_lock_irqsave (&range_lock, flags);
272	list_del (&range->list);
273	spin_unlock_irqrestore (&range_lock, flags);
274}
275
276/*
277 * function: dasd_add_range
278 * creates a dasd_range_t according to the arguments and
279 * appends it to the list of ranges
280 * additionally a devreg_t is created and added to the list of devregs
281 */
282static inline dasd_range_t *
283dasd_add_range (int from, int to, int features)
284{
285	dasd_range_t *range;
286
287	range = dasd_create_range (from, to, features);
288	if (!range)
289		return NULL;
290
291	dasd_append_range (range);
292#ifdef CONFIG_DASD_DYNAMIC
293	/* allocate and chain devreg infos for the devnos... */
294	{
295		int i;
296		for (i = range->from; i <= range->to; i++) {
297			dasd_devreg_t *reg = dasd_create_devreg (i);
298			s390_device_register (&reg->devreg);
299			list_add (&reg->list, &dasd_devreg_head);
300		}
301	}
302#endif				/* CONFIG_DASD_DYNAMIC */
303	return range;
304}
305
306/*
307 * function: dasd_remove_range
308 * removes a range and the corresponding devregs from all of the chains
309 * CAUTION: must not be called in a running system because it destroys
310 * the mapping of devices!
311 */
312static inline void
313dasd_remove_range (dasd_range_t * range)
314{
315#ifdef CONFIG_DASD_DYNAMIC
316	/* deallocate and dechain devreg infos for the devnos... */
317	{
318		int i;
319		for (i = range->from; i <= range->to; i++) {
320			struct list_head *l;
321			dasd_devreg_t *reg = NULL;
322			list_for_each (l, &dasd_devreg_head) {
323				reg = list_entry (l, dasd_devreg_t, list);
324				if (reg->devreg.flag == DEVREG_TYPE_DEVNO &&
325				    reg->devreg.ci.devno == i &&
326				    reg->devreg.oper_func == dasd_oper_handler)
327					break;
328			}
329			if (l == &dasd_devreg_head)
330				BUG ();
331                        list_del(&reg->list);
332			s390_device_unregister (&reg->devreg);
333			dasd_destroy_devreg (reg);
334		}
335	}
336#endif				/* CONFIG_DASD_DYNAMIC */
337	dasd_dechain_range (range);
338	dasd_destroy_range (range);
339}
340
341/*
342 * function: dasd_devindex_from_devno
343 * finds the logical number of the devno supplied as argument in the list
344 * of dasd ranges and returns it or ENODEV when not found
345 */
346static int
347dasd_devindex_from_devno (int devno)
348{
349	dasd_range_t *temp;
350	int devindex = 0;
351	unsigned long flags;
352	struct list_head *l;
353
354	spin_lock_irqsave (&range_lock, flags);
355	list_for_each (l, &dasd_range_head.list) {
356		temp = list_entry (l, dasd_range_t, list);
357		if (devno >= temp->from && devno <= temp->to) {
358			spin_unlock_irqrestore (&range_lock, flags);
359			return devindex + devno - temp->from;
360		}
361		devindex += temp->to - temp->from + 1;
362	}
363	spin_unlock_irqrestore (&range_lock, flags);
364	return -ENODEV;
365}
366
367/*
368 * function: dasd_devno_from_devindex
369 */
370static int
371dasd_devno_from_devindex (int devindex)
372{
373	dasd_range_t *temp;
374	unsigned long flags;
375	struct list_head *l;
376
377	spin_lock_irqsave (&range_lock, flags);
378	list_for_each (l, &dasd_range_head.list) {
379		temp = list_entry (l, dasd_range_t, list);
380                if ( devindex < temp->to - temp->from + 1) {
381			spin_unlock_irqrestore (&range_lock, flags);
382			return temp->from + devindex;
383		}
384		devindex -= temp->to - temp->from + 1;
385	}
386	spin_unlock_irqrestore (&range_lock, flags);
387	return -ENODEV;
388}
389
390/* SECTION: parsing the dasd= parameter of the parmline/insmod cmdline */
391
392/*
393 * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
394 * it is named 'dasd' to directly be filled by insmod with the comma separated
395 * strings when running as a module.
396 * a maximum of 256 ranges can be supplied, as the parmline is limited to
397 * <1024 Byte anyway.
398 */
399char *dasd[256];
400char *dasd_disciplines[8];
401
402#ifndef MODULE
403/*
404 * function: dasd_split_parm_string
405 * splits the parmline given to the kernel into comma separated strings
406 * which are filled into the 'dasd[]' array, to be parsed later on
407 */
408static void
409dasd_split_parm_string (char *str)
410{
411	char *tmp = str;
412	int count = 0;
413	while (tmp != NULL && *tmp != '\0') {
414		char *end;
415		int len;
416		end = strchr (tmp, ',');
417		if (end == NULL) {
418			len = strlen (tmp) + 1;
419		} else {
420			len = (long) end - (long) tmp + 1;
421			*end = '\0';
422			end++;
423		}
424		dasd[count] = kmalloc (len * sizeof (char), GFP_ATOMIC);
425		if (dasd[count] == NULL) {
426			printk (KERN_WARNING PRINTK_HEADER
427				"can't store dasd= parameter no %d\n",
428				count + 1);
429			break;
430		}
431		memset (dasd[count], 0, len * sizeof (char));
432		memcpy (dasd[count], tmp, len * sizeof (char));
433		count++;
434		tmp = end;
435	};
436}
437
438static char dasd_parm_string[1024] __initdata = { 0, };
439
440/*
441 * function: dasd_setup
442 * is invoked for any single 'dasd=' parameter supplied in the parmline
443 * it merges all the arguments into dasd_parm_string
444 */
445void __init
446dasd_setup (char *str, int *ints)
447{
448	int len = strlen (dasd_parm_string);
449	if (len != 0) {
450		strcat (dasd_parm_string, ",");
451	}
452	strcat (dasd_parm_string, str);
453}
454
455/*
456 * function: dasd_call_setup
457 * is the 2.4 version of dasd_setup and
458 * is invoked for any single 'dasd=' parameter supplied in the parmline
459 */
460int __init
461dasd_call_setup (char *str)
462{
463	int dummy;
464	dasd_setup (str, &dummy);
465	return 1;
466}
467
468int __init
469dasd_disciplines_setup (char *str)
470{
471	return 1;
472}
473
474__setup ("dasd=", dasd_call_setup);
475__setup ("dasd_disciplines=", dasd_disciplines_setup);
476
477#endif				/* MODULE */
478
479/*
480 * function: dasd_strtoul
481 * provides a wrapper to simple_strtoul to strip leading '0x' and
482 * interpret any argument to dasd=[range,...] as hexadecimal
483 */
484static inline int
485dasd_strtoul (char *str, char **stra, int* features)
486{
487        char *temp=str;
488        char *buffer;
489        int val,i,start;
490
491        buffer=(char*)kmalloc((strlen(str)+1)*sizeof(char),GFP_ATOMIC);
492        if (buffer==NULL) {
493            printk (KERN_WARNING PRINTK_HEADER
494                    "can't parse dasd= parameter %s due to low memory\n",
495                    str);
496        }
497
498        /* remove leading '0x' */
499        if (*temp == '0') {
500                temp++;         /* strip leading zero */
501                if (*temp == 'x')
502                        temp++; /* strip leading x */
503        }
504
505        /* copy device no to buffer and convert to decimal */
506        for (i=0; temp[i]!='\0' && temp[i]!='(' &&
507                  temp[i]!='-'  && temp[i]!=' '; i++){
508                if (isxdigit(temp[i])) {
509                        buffer[i]=temp[i];
510                } else {
511                        return -EINVAL;
512                }
513        }
514
515        buffer[i]='\0';
516
517        val = simple_strtoul (buffer, &buffer, 16);
518
519        /* check for features - e.g. (ro) ; the '\0', ')' and '-' stops check */
520        *features = DASD_DEFAULT_FEATURES;
521
522        if (temp[i]=='(') {
523
524                while (temp[i]!='\0' && temp[i]!=')'&&temp[i]!='-') {
525                        start=++i;
526
527                        /* move next feature to buffer */
528                        for (;temp[i]!='\0'&&temp[i]!=':'&&temp[i]!=')'&&temp[i]!='-';i++)
529                                buffer[i-start]=temp[i];
530                        buffer[i-start]='\0';
531
532                        if (strlen(buffer)) {
533                                if (!strcmp(buffer,"ro")) { /* handle 'ro' feature */
534                                        (*features) |= DASD_FEATURE_READONLY;
535                                        break;
536                                }
537                                printk (KERN_WARNING PRINTK_HEADER
538                                        "unsupported feature: %s, ignoring setting",
539                                        buffer);
540                        }
541                }
542        }
543
544        *stra = temp+i;
545        return val;
546}
547
548/*
549 * function: dasd_parse
550 * examines the strings given in the string array str and
551 * creates and adds the ranges to the apropriate lists
552 */
553static int
554dasd_parse (char **str)
555{
556	char *temp;
557	int from, to;
558        int features;
559        int rc = 0;
560
561	if (*str) {
562		/* turn off probeonly mode, if any dasd parameter is present */
563		dasd_probeonly = 0;
564		dasd_autodetect = 0;
565	}
566	while (*str) {
567		temp = *str;
568		from = 0;
569		to = 0;
570		if (strcmp ("autodetect", *str) == 0) {
571			dasd_autodetect = 1;
572			printk (KERN_INFO "turning to autodetection mode\n");
573			break;
574		} else if (strcmp ("probeonly", *str) == 0) {
575			dasd_probeonly = 1;
576			printk (KERN_INFO "turning to probeonly mode\n");
577			break;
578		} else {
579			/* turn off autodetect mode, if any range is present */
580			dasd_autodetect = 0;
581			from = dasd_strtoul (temp, &temp, &features);
582                        to = from;
583			if (*temp == '-') {
584				temp++;
585				to = dasd_strtoul (temp, &temp, &features);
586			}
587                        if (from == -EINVAL ||
588                            to   == -EINVAL    ) {
589                                rc = -EINVAL;
590                                break;
591                        } else {
592                                dasd_add_range (from, to ,features);
593                        }
594                }
595		str++;
596	}
597
598        return rc;
599}
600
601/* SECTION: Dealing with devices registered to multiple major numbers */
602
603static spinlock_t dasd_major_lock = SPIN_LOCK_UNLOCKED;
604
605static major_info_t dasd_major_info[] = {
606	{
607	      list:LIST_HEAD_INIT (dasd_major_info[1].list)
608	 },
609	{
610	      list:LIST_HEAD_INIT (dasd_major_info[0].list),
611	      gendisk:{
612	  INIT_GENDISK (94, DASD_NAME, DASD_PARTN_BITS, DASD_PER_MAJOR)
613	  },
614      flags:DASD_MAJOR_INFO_IS_STATIC}
615};
616
617static major_info_t *
618get_new_major_info (void)
619{
620	major_info_t *major_info = NULL;
621
622	major_info = kmalloc (sizeof (major_info_t), GFP_KERNEL);
623	if (major_info) {
624		static major_info_t temp_major_info = {
625			gendisk:{
626				 INIT_GENDISK (0, DASD_NAME, DASD_PARTN_BITS,
627					       DASD_PER_MAJOR)}
628		};
629		memcpy (major_info, &temp_major_info, sizeof (major_info_t));
630	}
631	return major_info;
632}
633
634/*
635 * register major number
636 * is called with the 'static' major_info during init of the driver or 'NULL' to
637 * allocate an additional dynamic major.
638 */
639static int
640dasd_register_major (major_info_t * major_info)
641{
642	int rc = 0;
643	int major;
644	unsigned long flags;
645
646        /* allocate dynamic major */
647	if (major_info == NULL) {
648		major_info = get_new_major_info ();
649		if (!major_info) {
650			printk (KERN_WARNING PRINTK_HEADER
651				"Cannot get memory to allocate another major number\n");
652			return -ENOMEM;
653		}
654	}
655
656	major = major_info->gendisk.major;
657
658        /* init devfs array */
659	major_info->gendisk.de_arr = (devfs_handle_t *)
660	    kmalloc (DASD_PER_MAJOR * sizeof (devfs_handle_t), GFP_KERNEL);
661	if(major_info->gendisk.de_arr == NULL)
662		goto out_gd_de_arr;
663
664	memset (major_info->gendisk.de_arr, 0,
665		DASD_PER_MAJOR * sizeof (devfs_handle_t));
666
667        /* init flags */
668	major_info->gendisk.flags = (char *)
669	    kmalloc (DASD_PER_MAJOR * sizeof (char), GFP_KERNEL);
670	if(major_info->gendisk.flags == NULL)
671		goto out_gd_flags;
672
673	memset (major_info->gendisk.flags, 0, DASD_PER_MAJOR * sizeof (char));
674
675        /* register blockdevice */
676	rc = devfs_register_blkdev (major, DASD_NAME, &dasd_device_operations);
677	if (rc < 0) {
678		printk (KERN_WARNING PRINTK_HEADER
679			"Cannot register to major no %d, rc = %d\n",
680                        major,
681                        rc);
682		goto out_reg_blkdev;
683	} else {
684		major_info->flags |= DASD_MAJOR_INFO_REGISTERED;
685	}
686
687	/* Insert the new major info into dasd_major_info if needed (dynamic major) */
688	if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {
689		spin_lock_irqsave (&dasd_major_lock, flags);
690		list_add_tail (&major_info->list, &dasd_major_info[0].list);
691		spin_unlock_irqrestore (&dasd_major_lock, flags);
692	}
693
694	if (major == 0) {
695		major = rc;
696		rc = 0;
697	}
698
699        /* init array of devices */
700	major_info->dasd_device =
701	    (dasd_device_t **) kmalloc (DASD_PER_MAJOR *
702					sizeof (dasd_device_t *), GFP_ATOMIC);
703	if (!major_info->dasd_device)
704		goto out_devices;
705	memset (major_info->dasd_device, 0,
706		DASD_PER_MAJOR * sizeof (dasd_device_t *));
707
708        /* init blk_size */
709	blk_size[major] =
710	    (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);
711	if (!blk_size[major])
712		goto out_blk_size;
713	memset (blk_size[major], 0, (1 << MINORBITS) * sizeof (int));
714
715        /* init blksize_size */
716	blksize_size[major] =
717	    (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);
718	if (!blksize_size[major])
719		goto out_blksize_size;
720	memset (blksize_size[major], 0, (1 << MINORBITS) * sizeof (int));
721
722        /* init_hardsect_size */
723	hardsect_size[major] =
724	    (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);
725	if (!hardsect_size[major])
726		goto out_hardsect_size;
727	memset (hardsect_size[major], 0, (1 << MINORBITS) * sizeof (int));
728
729        /* init max_sectors */
730	max_sectors[major] =
731	    (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);
732	if (!max_sectors[major])
733		goto out_max_sectors;
734	memset (max_sectors[major], 0, (1 << MINORBITS) * sizeof (int));
735
736	/* finally do the gendisk stuff */
737	major_info->gendisk.part = kmalloc ((1 << MINORBITS) *
738					    sizeof (struct hd_struct),
739					    GFP_ATOMIC);
740	if (!major_info->gendisk.part)
741		goto out_gendisk;
742	memset (major_info->gendisk.part, 0, (1 << MINORBITS) *
743		sizeof (struct hd_struct));
744
745	INIT_BLK_DEV (major, do_dasd_request, dasd_get_queue, NULL);
746
747	major_info->gendisk.sizes = blk_size[major];
748	major_info->gendisk.major = major;
749	add_gendisk (&major_info->gendisk);
750	return major;
751
752        /* error handling - free the prior allocated memory */
753      out_gendisk:
754	kfree (max_sectors[major]);
755	max_sectors[major] = NULL;
756
757      out_max_sectors:
758	kfree (hardsect_size[major]);
759	hardsect_size[major] = NULL;
760
761      out_hardsect_size:
762	kfree (blksize_size[major]);
763	blksize_size[major] = NULL;
764
765      out_blksize_size:
766	kfree (blk_size[major]);
767	blk_size[major] = NULL;
768
769      out_blk_size:
770	kfree (major_info->dasd_device);
771
772      out_devices:
773	/* Delete the new major info from dasd_major_info list if needed (dynamic) +*/
774	if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {
775		spin_lock_irqsave (&dasd_major_lock, flags);
776		list_del (&major_info->list);
777		spin_unlock_irqrestore (&dasd_major_lock, flags);
778	}
779
780        /* unregister blockdevice */
781	rc = devfs_unregister_blkdev (major, DASD_NAME);
782	if (rc < 0) {
783		printk (KERN_WARNING PRINTK_HEADER
784			"Unable to unregister from major no %d, rc = %d\n",
785                        major,
786			rc);
787	} else {
788		major_info->flags &= ~DASD_MAJOR_INFO_REGISTERED;
789	}
790
791out_reg_blkdev:
792	kfree (major_info->gendisk.flags);
793
794out_gd_flags:
795	kfree (major_info->gendisk.de_arr);
796
797out_gd_de_arr:
798	/* Delete the new major info from dasd_major_info if needed */
799	if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {
800		kfree (major_info);
801	}
802
803	return -ENOMEM;
804}
805
806static int
807dasd_unregister_major (major_info_t * major_info)
808{
809	int rc = 0;
810	int major;
811	unsigned long flags;
812
813	if (major_info == NULL) {
814		return -EINVAL;
815	}
816	major = major_info->gendisk.major;
817	INIT_BLK_DEV (major, NULL, NULL, NULL);
818
819	del_gendisk (&major_info->gendisk);
820
821	kfree (major_info->dasd_device);
822	kfree (major_info->gendisk.part);
823
824	kfree (blk_size[major]);
825	kfree (blksize_size[major]);
826	kfree (hardsect_size[major]);
827	kfree (max_sectors[major]);
828
829	blk_size[major]      = NULL;
830	blksize_size[major]  = NULL;
831	hardsect_size[major] = NULL;
832	max_sectors[major]   = NULL;
833
834	rc = devfs_unregister_blkdev (major, DASD_NAME);
835	if (rc < 0) {
836		printk (KERN_WARNING PRINTK_HEADER
837			"Cannot unregister from major no %d, rc = %d\n",
838                        major,
839			rc);
840		return rc;
841	} else {
842		major_info->flags &= ~DASD_MAJOR_INFO_REGISTERED;
843	}
844
845	kfree (major_info->gendisk.flags);
846	kfree (major_info->gendisk.de_arr);
847
848	/* Delete the new major info from dasd_major_info if needed */
849	if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {
850		spin_lock_irqsave (&dasd_major_lock, flags);
851		list_del (&major_info->list);
852		spin_unlock_irqrestore (&dasd_major_lock, flags);
853		kfree (major_info);
854	}
855	return rc;
856}
857
858/*
859 * function: dasd_device_from_kdev
860 * finds the device structure corresponding to the kdev supplied as argument
861 * in the major_info structures and returns it or NULL when not found
862 */
863dasd_device_t *
864dasd_device_from_kdev (kdev_t kdev)
865{
866	major_info_t *major_info = NULL;
867	struct list_head *l;
868	unsigned long flags;
869
870	spin_lock_irqsave (&dasd_major_lock, flags);
871	list_for_each (l, &dasd_major_info[0].list) {
872		major_info = list_entry (l, major_info_t, list);
873		if (major_info->gendisk.major == MAJOR (kdev))
874			break;
875	}
876	spin_unlock_irqrestore (&dasd_major_lock, flags);
877	if (major_info != &dasd_major_info[0])
878		return major_info->dasd_device[MINOR (kdev) >> DASD_PARTN_BITS];
879	return NULL;
880}
881
882/*
883 * function: dasd_device_from_devno
884 * finds the address of the device structure corresponding to the devno
885 * supplied as argument in the major_info structures and returns
886 * it or NULL when not found
887 */
888static inline dasd_device_t **
889dasd_device_from_devno (int devno)
890{
891	major_info_t *major_info;
892	struct list_head *l;
893	int devindex = dasd_devindex_from_devno (devno);
894	unsigned long flags;
895
896	spin_lock_irqsave (&dasd_major_lock, flags);
897	list_for_each (l, &dasd_major_info[0].list) {
898		major_info = list_entry (l, major_info_t, list);
899		if (devindex < DASD_PER_MAJOR) {
900			spin_unlock_irqrestore (&dasd_major_lock, flags);
901			return &major_info->dasd_device[devindex];
902		}
903		devindex -= DASD_PER_MAJOR;
904	}
905	spin_unlock_irqrestore (&dasd_major_lock, flags);
906	return NULL;
907}
908
909/*
910 * function: dasd_features_from_devno
911 * finds the device range corresponding to the devno
912 * supplied as argument in the major_info structures and returns
913 * the features set for it
914 */
915
916static int
917dasd_features_from_devno (int devno)
918{
919	dasd_range_t *temp;
920	int devindex = 0;
921	unsigned long flags;
922	struct list_head *l;
923
924	spin_lock_irqsave (&range_lock, flags);
925	list_for_each (l, &dasd_range_head.list) {
926		temp = list_entry (l, dasd_range_t, list);
927		if (devno >= temp->from && devno <= temp->to) {
928			spin_unlock_irqrestore (&range_lock, flags);
929			return temp->features;
930		}
931		devindex += temp->to - temp->from + 1;
932	}
933	spin_unlock_irqrestore (&range_lock, flags);
934	return -ENODEV;
935}
936
937
938
939/* SECTION: managing dasd disciplines */
940
941/* anchor and spinlock for list of disciplines */
942static struct list_head dasd_disc_head = LIST_HEAD_INIT(dasd_disc_head);
943static spinlock_t discipline_lock = SPIN_LOCK_UNLOCKED;
944
945/*
946 * function dasd_discipline_enq
947 * chains the discpline given as argument to the head of disiplines
948 * head chaining policy is required to allow module disciplines to
949 * be preferred against those, who are statically linked
950 */
951static inline void
952dasd_discipline_enq (dasd_discipline_t * d)
953{
954    list_add(&d->list, &dasd_disc_head);
955}
956
957/*
958 * function dasd_discipline_deq
959 * removes the discipline given as argument from the list of disciplines
960 */
961static inline void
962dasd_discipline_deq (dasd_discipline_t * d)
963{
964        list_del(&d->list);
965}
966
967void
968dasd_discipline_add (dasd_discipline_t * d)
969{
970        unsigned long flags;
971        MOD_INC_USE_COUNT;
972	spin_lock_irqsave (&discipline_lock,flags);
973        dasd_discipline_enq (d);
974	spin_unlock_irqrestore (&discipline_lock,flags);
975        dasd_enable_ranges (&dasd_range_head, d, DASD_STATE_ONLINE);
976}
977
978void dasd_discipline_del (dasd_discipline_t * d)
979{
980        unsigned long flags;
981	spin_lock_irqsave (&discipline_lock,flags);
982        dasd_disable_ranges(&dasd_range_head, d, DASD_STATE_DEL, 1);
983        dasd_discipline_deq (d);
984	spin_unlock_irqrestore (&discipline_lock,flags);
985        MOD_DEC_USE_COUNT;
986}
987
988static inline dasd_discipline_t *
989dasd_find_disc (dasd_device_t * device, dasd_discipline_t *d)
990{
991        dasd_discipline_t *t;
992        struct list_head *l = d ? &d->list : dasd_disc_head.next;
993        do {
994                t = list_entry(l,dasd_discipline_t,list);
995                if ( ( t->id_check == NULL ||
996                       t->id_check (&device->devinfo) == 0 ) &&
997                     ( t->check_characteristics == NULL ||
998                       t->check_characteristics (device) == 0 ) )
999                        break;
1000                l = l->next;
1001                if ( d ||
1002                     l == &dasd_disc_head ) {
1003                        t = NULL;
1004                        break;
1005                }
1006         } while ( 1 );
1007	return t;
1008}
1009
1010/* SECTION: profiling stuff */
1011
1012static dasd_profile_info_t dasd_global_profile;
1013
1014#ifdef DASD_PROFILE
1015/*
1016 * macro: dasd_profile_add_counter
1017 * increments counter in global and local profiling structures
1018 * according to the value
1019 */
1020#define dasd_profile_add_counter( value, counter, device ) \
1021{ \
1022        int ind; \
1023        long help; \
1024	for (ind = 0, help = value >> 3; \
1025             ind < 31 && help; \
1026             help = help >> 1, ind++) {} \
1027	dasd_global_profile.counter[ind]++; \
1028        device->profile.counter[ind]++; \
1029}
1030
1031/*
1032 * function dasd_profile_add
1033 * adds the profiling information from the cqr given as argument to the
1034 * global and device specific profiling information
1035 */
1036void
1037dasd_profile_add (ccw_req_t * cqr)
1038{
1039	long strtime, irqtime, endtime, tottime; /* in microsecnds*/
1040	long tottimeps, sectors;
1041	dasd_device_t *device = cqr->device;
1042
1043	if (!cqr->req)		/* safeguard against abnormal cqrs */
1044		return;
1045
1046        if ((!cqr->buildclk) ||
1047            (!cqr->startclk) ||
1048            (!cqr->stopclk ) ||
1049            (!cqr->endclk  ) ||
1050            (!(sectors = ((struct request *) (cqr->req))->nr_sectors)))
1051                return;
1052
1053	strtime = ((cqr->startclk - cqr->buildclk) >> 12);
1054	irqtime = ((cqr->stopclk - cqr->startclk) >> 12);
1055	endtime = ((cqr->endclk - cqr->stopclk) >> 12);
1056	tottime = ((cqr->endclk - cqr->buildclk) >> 12);
1057	tottimeps = tottime / sectors;
1058
1059	if (!dasd_global_profile.dasd_io_reqs) {
1060		memset (&dasd_global_profile, 0, sizeof (dasd_profile_info_t));
1061	};
1062	if (!device->profile.dasd_io_reqs) {
1063		memset (&device->profile, 0, sizeof (dasd_profile_info_t));
1064	};
1065
1066	dasd_global_profile.dasd_io_reqs++;
1067	device->profile.dasd_io_reqs++;
1068	dasd_global_profile.dasd_io_sects+=sectors;
1069	device->profile.dasd_io_sects+=sectors;
1070	dasd_profile_add_counter (sectors, dasd_io_secs, device);
1071	dasd_profile_add_counter (tottime, dasd_io_times, device);
1072	dasd_profile_add_counter (tottimeps, dasd_io_timps, device);
1073	dasd_profile_add_counter (strtime, dasd_io_time1, device);
1074	dasd_profile_add_counter (irqtime, dasd_io_time2, device);
1075	dasd_profile_add_counter (irqtime / sectors, dasd_io_time2ps, device);
1076	dasd_profile_add_counter (endtime, dasd_io_time3, device);
1077}
1078#endif
1079
1080/* SECTION: All the gendisk stuff */
1081
1082
1083/* SECTION: Managing wrappers for ccwcache */
1084
1085ccw_req_t *
1086dasd_alloc_request (char *magic, int cplength, int datasize, dasd_device_t* device)
1087{
1088	ccw_req_t *rv = NULL;
1089
1090	if ((rv = ccw_alloc_request (magic, cplength, datasize)) != NULL) {
1091		return rv;
1092	}
1093	if ((((sizeof (ccw_req_t) + 7) & -8) +
1094	     cplength * sizeof (ccw1_t) + datasize) > PAGE_SIZE) {
1095		BUG ();
1096		}
1097        if (device->lowmem_cqr==NULL) {
1098                DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request,
1099                                         "(%04x) Low memory! Using emergency request %p.",
1100                                         device->devinfo.devno,
1101                                         device->lowmem_ccws);
1102
1103                device->lowmem_cqr=device->lowmem_ccws;
1104                rv = device->lowmem_ccws;
1105		memset (rv, 0, PAGE_SIZE);
1106		strncpy ((char *) (&rv->magic), magic, 4);
1107		ASCEBC ((char *) (&rv->magic), 4);
1108		rv->cplength = cplength;
1109		rv->datasize = datasize;
1110		rv->data = (void *) ((long) rv + PAGE_SIZE - datasize);
1111		rv->cpaddr = (ccw1_t *) ((long) rv + sizeof (ccw_req_t));
1112        } else {
1113                DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request,
1114                                         "(%04x) Refusing emergency mem for request "
1115                                         "NULL, already in use at %p.",
1116                                         device->devinfo.devno,
1117                                         device->lowmem_ccws);
1118	}
1119	return rv;
1120}
1121
1122/*
1123 * function dasd_free_request
1124 * returns a ccw_req_t to the appropriate cache or emergeny request line
1125 */
1126void
1127dasd_free_request (ccw_req_t * request, dasd_device_t* device)
1128{
1129#ifdef CONFIG_ARCH_S390X
1130        ccw1_t* ccw;
1131        /* clear any idals used for chain */
1132        ccw=request->cpaddr-1;
1133        do {
1134                ccw++;
1135                if ((ccw->cda < (unsigned long) device->lowmem_idals           ) ||
1136                    (ccw->cda >= (unsigned long) device->lowmem_idals+PAGE_SIZE)   )
1137                        clear_normalized_cda (ccw);
1138                else {
1139                        if (device->lowmem_idal_ptr != device->lowmem_idals)
1140                                DASD_MESSAGE (KERN_WARNING, device,
1141                                              "Freeing emergency idals from request at %p.",
1142                                              request);
1143                        device->lowmem_idal_ptr = device->lowmem_idals;
1144                        device->lowmem_cqr=NULL;
1145                }
1146        } while ((ccw->flags & CCW_FLAG_CC) ||
1147                 (ccw->flags & CCW_FLAG_DC)   );
1148#endif
1149        if (request != device->lowmem_ccws) {
1150                /* compare to lowmem_ccws to protect usage of lowmem_cqr for IDAL only ! */
1151		ccw_free_request (request);
1152        } else {
1153                DASD_MESSAGE (KERN_WARNING, device,
1154                              "Freeing emergency request at %p",
1155                              request);
1156                device->lowmem_cqr=NULL;
1157	}
1158}
1159
1160int
1161dasd_set_normalized_cda (ccw1_t * cp, unsigned long address,
1162                         ccw_req_t* request, dasd_device_t* device )
1163{
1164#ifdef CONFIG_ARCH_S390X
1165	int nridaws;
1166        int count = cp->count;
1167
1168        if (set_normalized_cda (cp, address)!=-ENOMEM) {
1169                return 0;
1170        }
1171
1172        if ((device->lowmem_cqr!=NULL) && (device->lowmem_cqr!=request)) {
1173                DASD_MESSAGE (KERN_WARNING, device,
1174                              "Refusing emergency idals for request %p, memory"
1175                              " is already in use for request %p",
1176                              request,
1177                              device->lowmem_cqr);
1178                return -ENOMEM;
1179        }
1180        device->lowmem_cqr=request;
1181        if (device->lowmem_idal_ptr == device->lowmem_idals) {
1182            DASD_MESSAGE (KERN_WARNING,device,
1183                          "Low memory! Using emergency IDALs for request %p.\n",
1184                          request);
1185        }
1186        nridaws = ((address & (IDA_BLOCK_SIZE-1)) + count +
1187		   (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
1188	if ( device->lowmem_idal_ptr>=device->lowmem_idals + PAGE_SIZE ) {
1189		/* Ouch! No Idals left for emergency request */
1190		BUG();
1191	}
1192	cp->flags |= CCW_FLAG_IDA;
1193	cp->cda = (__u32)(unsigned long)device->lowmem_idal_ptr;
1194        do {
1195		*((long*)device->lowmem_idal_ptr) = address;
1196		address = (address & -(IDA_BLOCK_SIZE)) + (IDA_BLOCK_SIZE);
1197		nridaws --;
1198                device->lowmem_idal_ptr += sizeof(unsigned long);
1199        } while ( nridaws > 0 );
1200#else
1201        cp -> cda = address;
1202#endif
1203	return 0;
1204}
1205
1206
1207/* SECTION: (de)queueing of requests to channel program queues */
1208
1209/*
1210 * function dasd_chanq_enq
1211 * appends the cqr given as argument to the queue
1212 * has to be called with the queue lock (namely the s390_irq_lock) acquired
1213 */
1214inline void
1215dasd_chanq_enq (dasd_chanq_t * q, ccw_req_t * cqr)
1216{
1217	if (q->head != NULL) {
1218		q->tail->next = cqr;
1219	} else
1220		q->head = cqr;
1221	cqr->next = NULL;
1222	q->tail = cqr;
1223	check_then_set (&cqr->status,
1224                        CQR_STATUS_FILLED,
1225                        CQR_STATUS_QUEUED);
1226
1227
1228#ifdef DASD_PROFILE
1229        /* save profile information for non erp cqr */
1230        if (cqr->refers == NULL) {
1231                unsigned int  counter = 0;
1232                ccw_req_t     *ptr;
1233                dasd_device_t *device = cqr->device;
1234
1235                /* count the length of the chanq for statistics */
1236                for (ptr = q->head;
1237                     ptr->next != NULL && counter <=31;
1238                     ptr = ptr->next) {
1239                        counter++;
1240                }
1241
1242                dasd_global_profile.dasd_io_nr_req[counter]++;
1243                device->profile.dasd_io_nr_req[counter]++;
1244        }
1245#endif
1246}
1247
1248/*
1249 * function dasd_chanq_enq_head
1250 * chains the cqr given as argument to the queue head
1251 * has to be called with the queue lock (namely the s390_irq_lock) acquired
1252 */
1253inline void
1254dasd_chanq_enq_head (dasd_chanq_t * q, ccw_req_t * cqr)
1255{
1256	cqr->next = q->head;
1257	q->head = cqr;
1258	if (q->tail == NULL)
1259		q->tail = cqr;
1260	check_then_set (&cqr->status, CQR_STATUS_FILLED, CQR_STATUS_QUEUED);
1261}
1262
1263/*
1264 * function dasd_chanq_deq
1265 * dechains the cqr given as argument from the queue
1266 * has to be called with the queue lock (namely the s390_irq_lock) acquired
1267 */
1268inline void
1269dasd_chanq_deq (dasd_chanq_t * q, ccw_req_t * cqr)
1270{
1271	ccw_req_t *prev;
1272
1273	if (cqr == NULL)
1274		BUG ();
1275
1276	if (cqr == q->head) {
1277		q->head = cqr->next;
1278		if (q->head == NULL)
1279			q->tail = NULL;
1280
1281	} else {
1282		prev = q->head;
1283		while (prev && prev->next != cqr)
1284			prev = prev->next;
1285		if (prev == NULL)
1286			return;
1287		prev->next = cqr->next;
1288		if (prev->next == NULL)
1289			q->tail = prev;
1290	}
1291	cqr->next = NULL;
1292}
1293
1294/* SECTION: Managing the device queues etc. */
1295
1296/*
1297 * DASD_TERM_IO
1298 *
1299 * attempts to terminate the the current IO and set it to failed if termination
1300 * was successful.
1301 * returns an appropriate return code
1302 */
1303int
1304dasd_term_IO (ccw_req_t * cqr)
1305{
1306	int rc = 0;
1307	dasd_device_t *device = cqr->device;
1308	int irq;
1309        int retries = 0;
1310
1311	if (!cqr) {
1312		BUG ();
1313	}
1314	irq = device->devinfo.irq;
1315	if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) {
1316		DASD_MESSAGE (KERN_WARNING, device,
1317			      " ccw_req_t 0x%08x magic doesn't match"
1318			      " discipline 0x%08x\n",
1319			      cqr->magic,
1320			      *(unsigned int *) device->discipline->name);
1321		return -EINVAL;
1322	}
1323
1324        while ((retries < 5                    ) &&
1325               (cqr->status == CQR_STATUS_IN_IO)   ) {
1326
1327                if ( retries < 2 )
1328                        rc = halt_IO(irq, (long)cqr,
1329                                     cqr->options | DOIO_WAIT_FOR_INTERRUPT);
1330                else
1331                        rc = clear_IO(irq, (long)cqr,
1332                                      cqr->options | DOIO_WAIT_FOR_INTERRUPT);
1333
1334                switch (rc) {
1335                case 0:         /* termination successful */
1336                        check_then_set (&cqr->status,
1337                                        CQR_STATUS_IN_IO,
1338                                        CQR_STATUS_FAILED);
1339
1340                        asm volatile ("STCK %0":"=m" (cqr->stopclk));
1341                        break;
1342                case -ENODEV:
1343                        DASD_MESSAGE (KERN_WARNING, device, "%s",
1344                                      "device gone, retry\n");
1345                        break;
1346                case -EIO:
1347                        DASD_MESSAGE (KERN_WARNING, device, "%s",
1348                                      "I/O error, retry\n");
1349                        break;
1350                case -EBUSY:
1351                        DASD_MESSAGE (KERN_WARNING, device, "%s",
1352                                      "device busy, retry later\n");
1353                        break;
1354                default:
1355                        DASD_MESSAGE (KERN_ERR, device,
1356                                      "line %d unknown RC=%d, please report"
1357                                      " to linux390@de.ibm.com\n",
1358                                      __LINE__,
1359                                      rc);
1360                        BUG ();
1361                        break;
1362                }
1363
1364                retries ++;
1365        }
1366	return rc;
1367}
1368
1369/*
1370 * function dasd_start_IO
1371 * attempts to start the IO and returns an appropriate return code
1372 */
1373int
1374dasd_start_IO (ccw_req_t * cqr)
1375{
1376	int rc = 0;
1377	dasd_device_t *device = cqr->device;
1378	int irq;
1379	unsigned long long now;
1380
1381	if (!cqr) {
1382		BUG ();
1383	}
1384	irq = device->devinfo.irq;
1385	if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) {
1386		DASD_MESSAGE (KERN_WARNING, device,
1387			      " ccw_req_t 0x%08x magic doesn't match"
1388			      " discipline 0x%08x\n",
1389			      cqr->magic,
1390			      *(unsigned int *) device->discipline->name);
1391		return -EINVAL;
1392	}
1393
1394	asm volatile ("STCK %0":"=m" (now));
1395        cqr->startclk = now;
1396
1397	rc = do_IO (irq, cqr->cpaddr, (long) cqr, cqr->lpm, cqr->options);
1398
1399	switch (rc) {
1400	case 0:
1401                if (cqr->options & DOIO_WAIT_FOR_INTERRUPT) {
1402                        /* request already finished (synchronous IO) */
1403                        DASD_MESSAGE (KERN_ERR, device, "%s",
1404                                      " do_IO finished request... "
1405                                      "DOIO_WAIT_FOR_INTERRUPT was set");
1406                        check_then_set (&cqr->status,
1407                                        CQR_STATUS_QUEUED,
1408                                        CQR_STATUS_DONE);
1409
1410                        cqr->stopclk = now;
1411                        dasd_schedule_bh (device);
1412
1413                } else {
1414                        check_then_set (&cqr->status,
1415                                        CQR_STATUS_QUEUED,
1416                                        CQR_STATUS_IN_IO);
1417                }
1418		break;
1419	case -EBUSY:
1420		DASD_MESSAGE (KERN_WARNING, device, "%s",
1421			      "device busy, retry later\n");
1422		break;
1423	case -ETIMEDOUT:
1424		DASD_MESSAGE (KERN_WARNING, device, "%s",
1425			      "request timeout - terminated\n");
1426	case -ENODEV:
1427	case -EIO:
1428		check_then_set (&cqr->status,
1429				CQR_STATUS_QUEUED,
1430                                CQR_STATUS_FAILED);
1431
1432                cqr->stopclk = now;
1433                dasd_schedule_bh (device);
1434		break;
1435	default:
1436		DASD_MESSAGE (KERN_ERR, device,
1437			      "line %d unknown RC=%d, please report"
1438			      " to linux390@de.ibm.com\n", __LINE__, rc);
1439		BUG ();
1440		break;
1441	}
1442
1443	return rc;
1444}
1445
1446int
1447dasd_sleep_on_req (ccw_req_t * req)
1448{
1449	unsigned long flags;
1450	int cs;
1451	int rc = 0;
1452	dasd_device_t *device = (dasd_device_t *) req->device;
1453
1454        if ( signal_pending(current) ) {
1455                return -ERESTARTSYS;
1456        }
1457	s390irq_spin_lock_irqsave (device->devinfo.irq, flags);
1458	dasd_chanq_enq (&device->queue, req);
1459	/* let the bh start the request to keep them in order */
1460	dasd_schedule_bh (device);
1461	do {
1462		s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags);
1463		wait_event ( device->wait_q,
1464			     (((cs = req->status) == CQR_STATUS_DONE) ||
1465			     (cs == CQR_STATUS_FAILED) ||
1466                             signal_pending(current)));
1467		s390irq_spin_lock_irqsave (device->devinfo.irq, flags);
1468                if ( signal_pending(current) ) {
1469                        rc = -ERESTARTSYS;
1470		     	if (req->status == CQR_STATUS_IN_IO )
1471                        	device->discipline->term_IO(req);
1472                        break;
1473                } else if ( req->status == CQR_STATUS_FAILED) {
1474                        rc = -EIO;
1475                        break;
1476                }
1477	} while (cs != CQR_STATUS_DONE && cs != CQR_STATUS_FAILED);
1478	s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags);
1479	return rc;
1480}				/* end dasd_sleep_on_req */
1481
1482static inline void
1483dasd_end_request (struct request *req, int uptodate)
1484{
1485	while (end_that_request_first (req, uptodate, DASD_NAME)) {
1486	}
1487#ifndef DEVICE_NO_RANDOM
1488	add_blkdev_randomness (MAJOR (req->rq_dev));
1489#endif
1490	end_that_request_last (req);
1491	return;
1492}
1493
1494/*
1495 * function dasd_get_queue
1496 * returns the queue corresponding to a device behind a kdev
1497 */
1498static request_queue_t *
1499dasd_get_queue (kdev_t kdev)
1500{
1501	dasd_device_t *device = dasd_device_from_kdev (kdev);
1502
1503	if (!device) {
1504		return NULL;
1505	}
1506
1507	return device->request_queue;
1508}
1509
1510/*
1511 * function dasd_check_expire_time
1512 * check the request given as argument for expiration
1513 * and returns 0 if not yet expired, EIO else
1514 */
1515static inline int
1516dasd_check_expire_time (ccw_req_t * cqr)
1517{
1518	unsigned long long now;
1519	int rc = 0;
1520
1521	asm volatile ("STCK %0":"=m" (now));
1522	if (cqr->expires && cqr->expires + cqr->startclk < now) {
1523		DASD_MESSAGE (KERN_ERR, ((dasd_device_t *) cqr->device),
1524			      "IO timeout 0x%08lx%08lx usecs in req %p\n",
1525			      (long) (cqr->expires >> 44),
1526			      (long) (cqr->expires >> 12), cqr);
1527		cqr->expires <<= 1;
1528                rc = -EIO;
1529	}
1530	return rc;
1531}
1532
1533/*
1534 * function dasd_finalize_request
1535 * implemets the actions to perform, when a request is finally finished
1536 * namely in status CQR_STATUS_DONE || CQR_STATUS_FAILED
1537 */
1538static inline void
1539dasd_finalize_request (ccw_req_t * cqr)
1540{
1541	dasd_device_t *device = cqr->device;
1542
1543	asm volatile ("STCK %0":"=m" (cqr->endclk));
1544	if (cqr->req) {
1545#ifdef DASD_PROFILE
1546		dasd_profile_add (cqr);
1547#endif
1548		dasd_end_request (cqr->req, (cqr->status == CQR_STATUS_DONE));
1549		/* free request if nobody is waiting on it */
1550		dasd_free_request (cqr, cqr->device);
1551	} else {
1552                if ( cqr == device->init_cqr && /* bring late devices online */
1553                     device->level <= DASD_STATE_ONLINE ) {
1554                        device->timer.function = dasd_enable_single_device;
1555                        device->timer.data     = (unsigned long) device;
1556                        device->timer.expires  = jiffies;
1557                        add_timer(&device->timer);
1558                }
1559		/* notify sleeping task about finished postprocessing */
1560		wake_up (&device->wait_q);
1561
1562	}
1563	return;
1564}
1565
1566/*
1567 * function dasd_process_queues
1568 * transfers the requests on the queue given as argument to the chanq
1569 * if possible, the request ist started on a fastpath
1570 */
1571static void
1572dasd_process_queues (dasd_device_t * device)
1573{
1574	unsigned long flags;
1575	struct request *req;
1576	request_queue_t *queue = device->request_queue;
1577	dasd_chanq_t *qp = &device->queue;
1578	int irq = device->devinfo.irq;
1579	ccw_req_t *final_requests = NULL;
1580	static int chanq_min_size = DASD_MIN_SIZE_FOR_QUEUE;
1581	int chanq_max_size = DASD_CHANQ_MAX_SIZE;
1582	ccw_req_t *cqr = NULL, *temp;
1583	dasd_erp_postaction_fn_t erp_postaction;
1584
1585
1586	s390irq_spin_lock_irqsave (irq, flags);
1587
1588	/* First we dechain the requests, processed with completed status */
1589	while (qp->head &&
1590	       ((qp->head->status == CQR_STATUS_DONE  ) ||
1591		(qp->head->status == CQR_STATUS_FAILED) ||
1592		(qp->head->status == CQR_STATUS_ERROR )   )) {
1593
1594		dasd_erp_action_fn_t erp_action;
1595		ccw_req_t            *erp_cqr = NULL;
1596
1597		/*  preprocess requests with CQR_STATUS_ERROR */
1598		if (qp->head->status == CQR_STATUS_ERROR) {
1599
1600                        qp->head->retries--;
1601
1602			if (qp->head->dstat->flag & DEVSTAT_HALT_FUNCTION) {
1603
1604                                check_then_set (&qp->head->status,
1605                                                CQR_STATUS_ERROR,
1606                                                CQR_STATUS_FAILED);
1607
1608                                asm volatile ("STCK %0":"=m" (qp->head->stopclk));
1609
1610                        } else if ((device->discipline->erp_action == NULL                          ) ||
1611                                   ((erp_action = device->discipline->erp_action (qp->head)) == NULL)   ) {
1612
1613				erp_cqr = dasd_default_erp_action (qp->head);
1614
1615			} else { /* call discipline ERP action */
1616
1617                                erp_cqr = erp_action (qp->head);
1618                        }
1619                        continue;
1620
1621		} else if (qp->head->refers) {	/* we deal with a finished ERP */
1622
1623			if (qp->head->status == CQR_STATUS_DONE) {
1624
1625                                DASD_MESSAGE (KERN_DEBUG, device, "%s",
1626                                              "ERP successful");
1627			} else {
1628
1629                                DASD_MESSAGE (KERN_ERR, device, "%s",
1630                                              "ERP unsuccessful");
1631			}
1632
1633			if ((device->discipline->erp_postaction == NULL                              )||
1634			    ((erp_postaction = device->discipline->erp_postaction (qp->head)) == NULL)  ) {
1635
1636                                dasd_default_erp_postaction (qp->head);
1637
1638			} else {  /* call ERP postaction of discipline */
1639
1640                                erp_postaction (qp->head);
1641                        }
1642
1643			continue;
1644		}
1645
1646		/* dechain request now */
1647		if (final_requests == NULL)
1648			final_requests = qp->head;
1649
1650		cqr      = qp->head;
1651		qp->head = qp->head->next;
1652
1653		if (qp->head == NULL)
1654			qp->tail = NULL;
1655
1656	} /* end while over completed requests */
1657
1658	if (cqr)
1659		cqr->next = NULL;
1660	/* Now clean the requests with final status */
1661	while (final_requests) {
1662		temp = final_requests;
1663		final_requests = temp->next;
1664		dasd_finalize_request (temp);
1665	}
1666	/* Now we try to fetch requests from the request queue */
1667	for (temp = cqr; temp != NULL; temp = temp->next)
1668		if (temp->status == CQR_STATUS_QUEUED)
1669			chanq_max_size--;
1670	while ((atomic_read(&device->plugged) == 0) &&
1671               (!queue->plugged) &&
1672	       (!list_empty (&queue->queue_head)) &&
1673	       (req = dasd_next_request (queue)) != NULL) {
1674		/* queue empty or certain critera fulfilled -> transfer */
1675		if (qp->head == NULL ||
1676		    chanq_max_size > 0 || (req->nr_sectors >= chanq_min_size)) {
1677			ccw_req_t *cqr = NULL;
1678                        if (is_read_only(device->kdev) && req->cmd == WRITE) {
1679
1680                                DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler,
1681                                                         "(%04x) Rejecting write request %p\n",
1682                                                         device->devinfo.devno,
1683                                                         req);
1684
1685                                dasd_end_request (req, 0);
1686                                dasd_dequeue_request (queue,req);
1687                        } else {
1688                            /* relocate request according to partition table */
1689                            req->sector +=
1690                                device->major_info->gendisk.
1691                                part[MINOR (req->rq_dev)].start_sect;
1692                            cqr = device->discipline->build_cp_from_req (device, req);
1693                            if (cqr == NULL) {
1694
1695                                    DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler,
1696                                                             "(%04x) CCW creation failed "
1697                                                             "on request %p\n",
1698                                                             device->devinfo.devno,
1699                                                             req);
1700                                    /* revert relocation of request */
1701                                    req->sector -=
1702                                        device->major_info->gendisk.
1703                                        part[MINOR (req->rq_dev)].start_sect;
1704                                    break;	/* terminate request queue loop */
1705
1706                            }
1707#ifdef CONFIG_DYNAMIC_QUEUE_MIN_SIZE
1708                            chanq_min_size =
1709                                (chanq_min_size + req->nr_sectors) >> 1;
1710#endif				/* CONFIG_DYNAMIC_QUEUE_MIN_SIZE */
1711                            dasd_dequeue_request (queue, req);
1712                            dasd_chanq_enq (qp, cqr);
1713                        }
1714		} else {	/* queue not empty OR criteria not met */
1715			break;	/* terminate request queue loop */
1716		}
1717	}
1718	/* we process the requests with non-final status */
1719	if (qp->head) {
1720		switch (qp->head->status) {
1721		case CQR_STATUS_QUEUED:
1722			/* try to start the first I/O that can be started */
1723			if (device->discipline->start_IO == NULL)
1724				BUG ();
1725                        device->discipline->start_IO(qp->head);
1726			break;
1727		case CQR_STATUS_IN_IO:
1728			/* Check, if to invoke the missing interrupt handler */
1729			if (dasd_check_expire_time (qp->head)) {
1730				/* to be filled with MIH */
1731			}
1732			break;
1733
1734		case CQR_STATUS_PENDING:
1735			/* just wait */
1736			break;
1737		default:
1738			BUG ();
1739		}
1740	}
1741	s390irq_spin_unlock_irqrestore (irq, flags);
1742
1743} /* end dasd_process_queues */
1744
1745/*
1746 * function dasd_run_bh
1747 * acquires the locks needed and then runs the bh
1748 */
1749static void
1750dasd_run_bh (dasd_device_t * device)
1751{
1752	long flags;
1753	spin_lock_irqsave (&io_request_lock, flags);
1754	atomic_set (&device->bh_scheduled, 0);
1755	dasd_process_queues (device);
1756	spin_unlock_irqrestore (&io_request_lock, flags);
1757}
1758
1759/*
1760 * function dasd_schedule_bh
1761 * schedules the request_fn to run with next run_bh cycle
1762 */
1763void
1764dasd_schedule_bh (dasd_device_t * device)
1765{
1766	/* Protect against rescheduling, when already running */
1767	if (atomic_compare_and_swap (0, 1, &device->bh_scheduled)) {
1768		return;
1769	}
1770
1771	INIT_LIST_HEAD (&device->bh_tq.list);
1772	device->bh_tq.sync = 0;
1773	device->bh_tq.routine = (void *) (void *) dasd_run_bh;
1774	device->bh_tq.data = device;
1775
1776	queue_task (&device->bh_tq, &tq_immediate);
1777	mark_bh (IMMEDIATE_BH);
1778	return;
1779}
1780
1781/*
1782 * function do_dasd_request
1783 * is called from ll_rw_blk.c and provides the caller of
1784 * dasd_process_queues
1785 */
1786static void
1787do_dasd_request (request_queue_t * queue)
1788{
1789        dasd_device_t *device = (dasd_device_t *)queue->queuedata;
1790	dasd_process_queues (device);
1791}
1792
1793/*
1794 * DASD_HANDLE_STATE_CHANGE_PENDING
1795 *
1796 * DESCRIPTION
1797 *   Handles the state change pending interrupt.
1798 *   Search for the device related request queue and check if the first
1799 *   cqr in queue in in status 'CQR_STATUE_PENDING'.
1800 *   If so the status is set to 'CQR_STATUS_QUEUED' to reactivate
1801 *   the device.
1802 *
1803 *  PARAMETER
1804 *   stat               device status of state change pending interrupt.
1805 */
1806void
1807dasd_handle_state_change_pending (devstat_t * stat)
1808{
1809	dasd_device_t **device_addr;
1810	ccw_req_t *cqr;
1811
1812	device_addr = dasd_device_from_devno (stat->devno);
1813
1814	if (device_addr == NULL) {
1815
1816		printk (KERN_DEBUG PRINTK_HEADER
1817			"unable to find device for state change pending "
1818			"interrupt: devno%04x\n",
1819                        stat->devno);
1820                return;
1821	}
1822
1823        /* re-activate first request in queue */
1824        cqr = (*device_addr)->queue.head;
1825
1826        if (cqr->status == CQR_STATUS_PENDING) {
1827
1828                DASD_MESSAGE (KERN_DEBUG, (*device_addr), "%s",
1829                              "device request queue restarted by "
1830                              "state change pending interrupt\n");
1831
1832                del_timer (&(*device_addr)->timer);
1833
1834                check_then_set (&cqr->status,
1835                                CQR_STATUS_PENDING, CQR_STATUS_QUEUED);
1836
1837                dasd_schedule_bh (*device_addr);
1838
1839        }
1840
1841} /* end dasd_handle_state_change_pending */
1842
1843/*
1844 * function dasd_int_handler
1845 * is the DASD driver's default interrupt handler for SSCH-IO
1846 */
1847void
1848dasd_int_handler (int irq, void *ds, struct pt_regs *regs)
1849{
1850	int ip;
1851	ccw_req_t *cqr;
1852	dasd_device_t *device;
1853        unsigned long long now;
1854	dasd_era_t era = dasd_era_none; /* default is everything is okay */
1855	devstat_t *stat = (devstat_t *)ds;
1856
1857        if (stat == NULL) {
1858                BUG();
1859	}
1860        DASD_DRIVER_DEBUG_EVENT (6, dasd_int_handler,
1861                                 "Interrupt: IRQ %02x, stat %02x, devno %04x",
1862                                 irq,
1863                                 stat->dstat,
1864                                 stat->devno);
1865        asm volatile ("STCK %0":"=m" (now));
1866
1867        /* first of all check for state change pending interrupt */
1868        if ((stat->dstat & DEV_STAT_ATTENTION ) &&
1869            (stat->dstat & DEV_STAT_DEV_END   ) &&
1870            (stat->dstat & DEV_STAT_UNIT_EXCEP)   ) {
1871                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
1872                                         "State change Interrupt: %04x",
1873                                         stat->devno);
1874                dasd_handle_state_change_pending (stat);
1875                return;
1876        }
1877
1878	ip = stat->intparm;
1879	if (!ip) {		/* no intparm: unsolicited interrupt */
1880                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
1881                                         "Unsolicited Interrupt: %04x",
1882                                         stat->devno);
1883		printk (KERN_DEBUG PRINTK_HEADER
1884                        "unsolicited interrupt: irq 0x%x devno %04x\n",
1885                        irq,
1886                        stat->devno);
1887		return;
1888	}
1889	if (ip & 0x80000001) {
1890                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
1891                                         "spurious Interrupt: %04x",
1892                                         stat->devno);
1893		printk (KERN_DEBUG PRINTK_HEADER
1894                        "spurious interrupt: irq 0x%x devno %04x, parm %08x\n",
1895                        irq,
1896                        stat->devno,ip);
1897		return;
1898	}
1899
1900	cqr = (ccw_req_t *)(long)ip;
1901
1902        /* check status - the request might have been killed because of dyn dettach */
1903	if (cqr->status != CQR_STATUS_IN_IO) {
1904                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
1905                                         "invalid status %02x on device %04x",
1906                                         cqr->status,
1907                                         stat->devno);
1908
1909		printk (KERN_DEBUG PRINTK_HEADER
1910                        "invalid status: irq 0x%x devno %04x, status %02x\n",
1911                        irq,
1912                        stat->devno,
1913                        cqr->status);
1914		return;
1915	}
1916
1917	device = (dasd_device_t *) cqr->device;
1918	if (device == NULL ||
1919            device != ds-offsetof(dasd_device_t,dev_status)) {
1920                BUG();
1921	}
1922	if (device->devinfo.irq != irq) {
1923                BUG();
1924	}
1925	if (strncmp (device->discipline->ebcname, (char *) &cqr->magic, 4)) {
1926                BUG();
1927	}
1928
1929        /* first of all lets try to find out the appropriate era_action */
1930        DASD_DEVICE_DEBUG_EVENT (4, device," Int: CS/DS 0x%04x",
1931                                 ((stat->cstat<<8)|stat->dstat));
1932
1933	/* first of all lets try to find out the appropriate era_action */
1934	if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL ||
1935	    stat->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) {
1936		/* anything abnormal ? */
1937		if (device->discipline->examine_error == NULL ||
1938		    stat->flag & DEVSTAT_HALT_FUNCTION) {
1939			era = dasd_era_fatal;
1940		} else {
1941			era = device->discipline->examine_error (cqr, stat);
1942		}
1943                DASD_DRIVER_DEBUG_EVENT (1, dasd_int_handler," era_code %d",
1944                                         era);
1945	}
1946        if ( era == dasd_era_none ) {
1947                check_then_set(&cqr->status,
1948                               CQR_STATUS_IN_IO,
1949                               CQR_STATUS_DONE);
1950
1951                cqr->stopclk=now;
1952		/* start the next queued request if possible -> fast_io */
1953                if (cqr->next &&
1954                    cqr->next->status == CQR_STATUS_QUEUED) {
1955                        if (device->discipline->start_IO (cqr->next) != 0) {
1956                                printk (KERN_WARNING PRINTK_HEADER
1957                                        "Interrupt fastpath failed!\n");
1958                        }
1959                }
1960        } else { /* error */
1961		if (cqr->dstat == NULL)
1962			cqr->dstat = kmalloc (sizeof (devstat_t), GFP_ATOMIC);
1963		if (cqr->dstat) {
1964			memcpy (cqr->dstat, stat, sizeof (devstat_t));
1965		} else {
1966			PRINT_ERR ("no memory for dstat...ignoring\n");
1967		}
1968
1969#ifdef ERP_DEBUG
1970		/* dump sense data */
1971		if (device->discipline            &&
1972                    device->discipline->dump_sense  ) {
1973
1974                        device->discipline->dump_sense (device,
1975                                                        cqr);
1976		}
1977#endif
1978
1979		switch (era) {
1980		case dasd_era_fatal:
1981			check_then_set (&cqr->status,
1982                                        CQR_STATUS_IN_IO,
1983					CQR_STATUS_FAILED);
1984
1985                        cqr->stopclk = now;
1986			break;
1987		case dasd_era_recover:
1988			check_then_set (&cqr->status,
1989                                        CQR_STATUS_IN_IO,
1990					CQR_STATUS_ERROR);
1991			break;
1992		default:
1993			BUG ();
1994		}
1995	}
1996        if ( cqr == device->init_cqr &&
1997             ( cqr->status == CQR_STATUS_DONE ||
1998               cqr->status == CQR_STATUS_FAILED )){
1999                dasd_state_init_to_ready(device);
2000                if ( atomic_read(&dasd_init_pending) == 0)
2001                        wake_up (&dasd_init_waitq);
2002        }
2003	dasd_schedule_bh (device);
2004
2005} /* end dasd_int_handler */
2006
2007/* SECTION: Some stuff related to error recovery */
2008
2009/*
2010 * DEFAULT_ERP_ACTION
2011 *
2012 * DESCRIPTION
2013 *   sets up the default-ERP ccw_req_t, namely one, which performs a TIC
2014 *   to the original channel program with a retry counter of 16
2015 *
2016 * PARAMETER
2017 *   cqr                failed CQR
2018 *
2019 * RETURN VALUES
2020 *   erp                CQR performing the ERP
2021 */
2022ccw_req_t *
2023dasd_default_erp_action (ccw_req_t * cqr)
2024{
2025
2026        dasd_device_t *device = cqr->device;
2027	ccw_req_t     *erp    = dasd_alloc_request ((char *) &cqr->magic, 1, 0, cqr->device);
2028
2029	printk (KERN_DEBUG PRINTK_HEADER "Default ERP called... \n");
2030
2031	if (!erp) {
2032
2033                DASD_MESSAGE (KERN_ERR, device, "%s",
2034                              "Unable to allocate ERP request");
2035
2036                check_then_set (&cqr->status,
2037                                CQR_STATUS_ERROR,
2038                                CQR_STATUS_FAILED);
2039
2040                asm volatile ("STCK %0":"=m" (cqr->stopclk));
2041
2042                return cqr;
2043	}
2044
2045	erp->cpaddr->cmd_code = CCW_CMD_TIC;
2046	erp->cpaddr->cda = (__u32) (addr_t) cqr->cpaddr;
2047	erp->function = dasd_default_erp_action;
2048	erp->refers = cqr;
2049	erp->device = cqr->device;
2050	erp->magic = cqr->magic;
2051	erp->retries = 16;
2052
2053	erp->status = CQR_STATUS_FILLED;
2054
2055        dasd_chanq_enq_head (&device->queue,
2056                             erp);
2057
2058	return erp;
2059
2060} /* end dasd_default_erp_action */
2061
2062/*
2063 * DEFAULT_ERP_POSTACTION
2064 *
2065 * DESCRIPTION
2066 *   Frees all ERPs of the current ERP Chain and set the status
2067 *   of the original CQR either to CQR_STATUS_DONE if ERP was successful
2068 *   or to CQR_STATUS_FAILED if ERP was NOT successful.
2069 *   NOTE: This function is only called if no discipline postaction
2070 *         is available
2071 *
2072 * PARAMETER
2073 *   erp                current erp_head
2074 *
2075 * RETURN VALUES
2076 *   cqr                pointer to the original CQR
2077 */
2078ccw_req_t *
2079dasd_default_erp_postaction (ccw_req_t *erp)
2080{
2081
2082	ccw_req_t     *cqr      = NULL,
2083                      *free_erp = NULL;
2084	dasd_device_t *device   = erp->device;
2085	int           success;
2086
2087	if (erp->refers   == NULL ||
2088            erp->function == NULL   ) {
2089
2090		BUG ();
2091	}
2092
2093	if (erp->status == CQR_STATUS_DONE)
2094		success = 1;
2095	else
2096		success = 0;
2097
2098	/* free all ERPs - but NOT the original cqr */
2099	while (erp->refers != NULL) {
2100
2101		free_erp = erp;
2102		erp      = erp->refers;
2103
2104		/* remove the request from the device queue */
2105		dasd_chanq_deq (&device->queue,
2106                                free_erp);
2107
2108		/* free the finished erp request */
2109		dasd_free_request (free_erp, free_erp->device);
2110	}
2111
2112	/* save ptr to original cqr */
2113	cqr = erp;
2114
2115	/* set corresponding status to original cqr */
2116	if (success) {
2117
2118		check_then_set (&cqr->status,
2119                                CQR_STATUS_ERROR,
2120				CQR_STATUS_DONE);
2121	} else {
2122
2123		check_then_set (&cqr->status,
2124				CQR_STATUS_ERROR,
2125                                CQR_STATUS_FAILED);
2126
2127                asm volatile ("STCK %0":"=m" (cqr->stopclk));
2128	}
2129
2130	return cqr;
2131
2132} /* end default_erp_postaction */
2133
2134/* SECTION: The helpers of the struct file_operations */
2135
2136/*
2137 * function dasd_format
2138 * performs formatting of _device_ according to _fdata_
2139 * Note: The discipline's format_function is assumed to deliver formatting
2140 * commands to format a single unit of the device. In terms of the ECKD
2141 * devices this means CCWs are generated to format a single track.
2142 */
2143
2144static int
2145dasd_format (dasd_device_t * device, format_data_t * fdata)
2146{
2147	int rc = 0;
2148	int openct = atomic_read (&device->open_count);
2149
2150	if (openct > 1) {
2151		DASD_MESSAGE (KERN_WARNING, device, "%s",
2152			      "dasd_format: device is open! expect errors.");
2153	}
2154	DASD_MESSAGE (KERN_INFO, device,
2155		      "formatting units %d to %d (%d B blocks) flags %d",
2156		      fdata->start_unit,
2157                      fdata->stop_unit,
2158		      fdata->blksize,
2159                      fdata->intensity);
2160	while ((!rc) && (fdata->start_unit <= fdata->stop_unit)) {
2161                ccw_req_t *req;
2162                dasd_format_fn_t ffn = device->discipline->format_device;
2163		ffn = device->discipline->format_device;
2164		if (ffn == NULL)
2165			break;
2166		req = ffn (device, fdata);
2167		if (req == NULL) {
2168			rc = -ENOMEM;
2169			break;
2170		}
2171		if ((rc = dasd_sleep_on_req (req)) != 0) {
2172			DASD_MESSAGE (KERN_WARNING, device,
2173				      " Formatting of unit %d failed with rc = %d\n",
2174				      fdata->start_unit, rc);
2175			break;
2176		}
2177		dasd_free_request (req, device);	/* request is no longer used */
2178	        if ( signal_pending(current) ) {
2179			rc = -ERESTARTSYS;
2180			break;
2181                }
2182		fdata->start_unit++;
2183	}
2184	return rc;
2185}				/* end dasd_format */
2186
2187static struct list_head dasd_ioctls = LIST_HEAD_INIT (dasd_ioctls);
2188
2189static dasd_ioctl_list_t *
2190dasd_find_ioctl (int no)
2191{
2192	struct list_head *curr;
2193	list_for_each (curr, &dasd_ioctls) {
2194		if (list_entry (curr, dasd_ioctl_list_t, list)->no == no) {
2195			return list_entry (curr, dasd_ioctl_list_t, list);
2196		}
2197	}
2198	return NULL;
2199}
2200
2201int
2202dasd_ioctl_no_register (struct module *owner, int no, dasd_ioctl_fn_t handler)
2203{
2204	dasd_ioctl_list_t *new;
2205	if (dasd_find_ioctl (no))
2206		return -EBUSY;
2207	new = kmalloc (sizeof (dasd_ioctl_list_t), GFP_KERNEL);
2208	if (new == NULL)
2209		return -ENOMEM;
2210	new->owner = owner;
2211	new->no = no;
2212	new->handler = handler;
2213	list_add (&new->list, &dasd_ioctls);
2214	MOD_INC_USE_COUNT;
2215	return 0;
2216}
2217
2218int
2219dasd_ioctl_no_unregister (struct module *owner, int no, dasd_ioctl_fn_t handler)
2220{
2221	dasd_ioctl_list_t *old = dasd_find_ioctl (no);
2222	if (old == NULL)
2223		return -ENOENT;
2224	if (old->no != no || old->handler != handler || owner != old->owner )
2225		return -EINVAL;
2226	list_del (&old->list);
2227	kfree (old);
2228	MOD_DEC_USE_COUNT;
2229	return 0;
2230}
2231
2232static int
2233dasd_revalidate (dasd_device_t * device)
2234{
2235        int rc = 0;
2236	int i;
2237	kdev_t kdev = device->kdev;
2238	int openct = atomic_read (&device->open_count);
2239	int start = MINOR (kdev);
2240	if (openct != 1) {
2241		DASD_MESSAGE (KERN_WARNING, device, "%s",
2242			      "BLKRRPART: device is open! expect errors.");
2243	}
2244	for (i = (1 << DASD_PARTN_BITS) - 1; i >= 0; i--) {
2245                int major = device->major_info->gendisk.major;
2246		invalidate_device(MKDEV (major, start+i), 1);
2247	}
2248        dasd_destroy_partitions(device);
2249        dasd_setup_partitions(device);
2250        return rc;
2251
2252}
2253static int
2254do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data)
2255{
2256	int rc = 0;
2257	dasd_device_t *device = dasd_device_from_kdev (inp->i_rdev);
2258	major_info_t *major_info;
2259
2260	if (!device) {
2261		printk (KERN_WARNING PRINTK_HEADER
2262			"No device registered as device (%d:%d)\n",
2263			MAJOR (inp->i_rdev),
2264                        MINOR (inp->i_rdev));
2265		return -EINVAL;
2266	}
2267	if ((_IOC_DIR (no) != _IOC_NONE) && (data == 0)) {
2268		PRINT_DEBUG ("empty data ptr");
2269		return -EINVAL;
2270	}
2271	major_info = device->major_info;
2272	switch (no) {
2273        case DASDAPIVER: {
2274			int ver = DASD_API_VERSION;
2275			rc = put_user(ver, (int *) data);
2276			break;
2277        }
2278	case BLKGETSIZE:{	/* Return device size */
2279			long blocks = major_info->gendisk.sizes
2280                                      [MINOR (inp->i_rdev)] << 1;
2281			rc = put_user(blocks, (long *) data);
2282			break;
2283		}
2284	case BLKGETSIZE64:{
2285			u64 blocks = major_info->gendisk.sizes
2286                                      [MINOR (inp->i_rdev)];
2287			rc = put_user(blocks << 10, (u64 *) data);
2288			break;
2289		}
2290	case BLKRRPART:{
2291			if (!capable (CAP_SYS_ADMIN)) {
2292				rc = -EACCES;
2293				break;
2294			}
2295			rc = dasd_revalidate (device);
2296			break;
2297		}
2298	case HDIO_GETGEO:{
2299			struct hd_geometry geo = { 0, };
2300			rc = dasd_fillgeo (inp->i_rdev, &geo);
2301			if (rc)
2302				break;
2303
2304			rc = copy_to_user ((struct hd_geometry *) data, &geo,
2305					   sizeof (struct hd_geometry));
2306			if (rc)
2307				rc = -EFAULT;
2308			break;
2309		}
2310	case BIODASDDISABLE:{
2311			if (!capable (CAP_SYS_ADMIN)) {
2312				rc = -EACCES;
2313				break;
2314			}
2315                        if ( device->level > DASD_STATE_ACCEPT) {
2316                                dasd_deactivate_queue(device);
2317                                if ( device->request_queue)
2318                                        dasd_flush_request_queues(device,0);
2319                                dasd_flush_chanq(device,0);
2320                                dasd_disable_blkdev(device);
2321                                dasd_set_device_level (device->devinfo.devno,
2322                                                       device->discipline,
2323                                                       DASD_STATE_ACCEPT);
2324                        }
2325                        break;
2326        }
2327	case BIODASDENABLE:{
2328                        dasd_range_t range = {
2329                                from: device->devinfo.devno,
2330                                to: device->devinfo.devno
2331                        };
2332			if (!capable (CAP_SYS_ADMIN)) {
2333				rc = -EACCES;
2334				break;
2335			}
2336                        dasd_enable_ranges (&range, device->discipline, 0);
2337                        break;
2338        }
2339	case BIODASDFMT:{
2340			/* fdata == NULL is no longer a valid arg to dasd_format ! */
2341			int partn = MINOR (inp->i_rdev) &
2342			    ((1 << major_info->gendisk.minor_shift) - 1);
2343			format_data_t fdata;
2344
2345			if (!capable (CAP_SYS_ADMIN)) {
2346				rc = -EACCES;
2347				break;
2348			}
2349                        if (dasd_features_from_devno(device->devinfo.devno)&DASD_FEATURE_READONLY) {
2350                                rc = -EROFS;
2351                                break;
2352                        }
2353			if (!data) {
2354				rc = -EINVAL;
2355				break;
2356			}
2357			rc = copy_from_user (&fdata, (void *) data,
2358					     sizeof (format_data_t));
2359			if (rc) {
2360				rc = -EFAULT;
2361				break;
2362			}
2363			if (partn != 0) {
2364				DASD_MESSAGE (KERN_WARNING, device, "%s",
2365					      "Cannot low-level format a partition");
2366				return -EINVAL;
2367			}
2368			rc = dasd_format (device, &fdata);
2369			break;
2370		}
2371	case BIODASDPRRST:{     /* reset device profile information */
2372			if (!capable (CAP_SYS_ADMIN)) {
2373				rc = -EACCES;
2374				break;
2375			}
2376			memset (&device->profile, 0,
2377				sizeof (dasd_profile_info_t));
2378			break;
2379		}
2380	case BIODASDPRRD:{      /* retrun device profile information */
2381			rc = copy_to_user((long *)data,
2382					  (long *)&device->profile,
2383					  sizeof(dasd_profile_info_t));
2384			if (rc)
2385				rc = -EFAULT;
2386			break;
2387		}
2388	case BIODASDRSRV:{      /* reserve */
2389			ccw_req_t *req;
2390			if (!capable (CAP_SYS_ADMIN)) {
2391				rc = -EACCES;
2392				break;
2393			}
2394			req = device->discipline->reserve (device);
2395			rc = dasd_sleep_on_req (req);
2396			dasd_free_request (req, device);
2397			break;
2398		}
2399	case BIODASDRLSE:{      /* release */
2400			ccw_req_t *req;
2401			if (!capable (CAP_SYS_ADMIN)) {
2402				rc = -EACCES;
2403				break;
2404			}
2405			req = device->discipline->release (device);
2406			rc = dasd_sleep_on_req (req);
2407			dasd_free_request (req, device);
2408			break;
2409		}
2410	case BIODASDSLCK:{      /* steal lock - unconditional reserve */
2411			ccw_req_t *req;
2412			if (!capable (CAP_SYS_ADMIN)) {
2413				rc = -EACCES;
2414				break;
2415			}
2416			req = device->discipline->steal_lock (device);
2417			rc = dasd_sleep_on_req (req);
2418			dasd_free_request (req, device);
2419			break;
2420		}
2421	case BIODASDINFO:{
2422			dasd_information_t dasd_info;
2423			unsigned long flags;
2424			rc = device->discipline->fill_info (device, &dasd_info);
2425                        dasd_info.label_block = device->sizes.pt_block;
2426			dasd_info.devno = device->devinfo.devno;
2427			dasd_info.schid = device->devinfo.irq;
2428			dasd_info.cu_type = device->devinfo.sid_data.cu_type;
2429			dasd_info.cu_model = device->devinfo.sid_data.cu_model;
2430			dasd_info.dev_type = device->devinfo.sid_data.dev_type;
2431			dasd_info.dev_model = device->devinfo.sid_data.dev_model;
2432			dasd_info.open_count =
2433			    atomic_read (&device->open_count);
2434			dasd_info.status = device->level;
2435			if (device->discipline) {
2436				memcpy (dasd_info.type,
2437					device->discipline->name, 4);
2438			} else {
2439				memcpy (dasd_info.type, "none", 4);
2440			}
2441			dasd_info.req_queue_len = 0;
2442			dasd_info.chanq_len = 0;
2443			if (device->request_queue->request_fn) {
2444				struct list_head *l;
2445				ccw_req_t *cqr = device->queue.head;
2446				spin_lock_irqsave (&io_request_lock, flags);
2447				list_for_each (l,
2448					       &device->request_queue->
2449					       queue_head) {
2450					dasd_info.req_queue_len++;
2451				}
2452				spin_unlock_irqrestore (&io_request_lock,
2453							flags);
2454				s390irq_spin_lock_irqsave (device->devinfo.irq,
2455							   flags);
2456				while (cqr) {
2457					cqr = cqr->next;
2458					dasd_info.chanq_len++;
2459				}
2460				s390irq_spin_unlock_irqrestore (device->devinfo.
2461								irq, flags);
2462			}
2463			rc =
2464			    copy_to_user ((long *) data, (long *) &dasd_info,
2465					  sizeof (dasd_information_t));
2466			if (rc)
2467				rc = -EFAULT;
2468			break;
2469		}
2470	case BLKSSZGET:
2471	case BLKROSET:
2472	case BLKROGET:
2473	case BLKRASET:
2474	case BLKRAGET:
2475	case BLKFLSBUF:
2476	case BLKPG:
2477	case BLKELVGET:
2478	case BLKELVSET:
2479		return blk_ioctl (inp->i_rdev, no, data);
2480		break;
2481	default:{
2482
2483			dasd_ioctl_list_t *old = dasd_find_ioctl (no);
2484			if (old) {
2485				if ( old->owner )
2486					__MOD_INC_USE_COUNT(old->owner);
2487				rc = old->handler (inp, no, data);
2488				if ( old->owner )
2489					__MOD_DEC_USE_COUNT(old->owner);
2490			} else {
2491				DASD_MESSAGE (KERN_INFO, device,
2492					      "ioctl 0x%08x=%s'0x%x'%d(%d) data %8lx\n",
2493					      no,
2494					      _IOC_DIR (no) == _IOC_NONE ? "0" :
2495					      _IOC_DIR (no) == _IOC_READ ? "r" :
2496					      _IOC_DIR (no) == _IOC_WRITE ? "w" :
2497                                              _IOC_DIR (no) ==
2498                                              (_IOC_READ | _IOC_WRITE) ? "rw" : "u",
2499                                              _IOC_TYPE (no),
2500					      _IOC_NR (no),
2501                                              _IOC_SIZE (no),
2502					      data);
2503				rc = -ENOTTY;
2504			}
2505			break;
2506		}
2507	}
2508	return rc;
2509}
2510
2511/* SECTION: The members of the struct file_operations */
2512
2513static int
2514dasd_ioctl (struct inode *inp, struct file *filp,
2515	    unsigned int no, unsigned long data)
2516{
2517	int rc = 0;
2518	if ((!inp) || !(inp->i_rdev)) {
2519		return -EINVAL;
2520	}
2521	rc = do_dasd_ioctl (inp, no, data);
2522	return rc;
2523}
2524
2525static int
2526dasd_open (struct inode *inp, struct file *filp)
2527{
2528	int rc = 0;
2529        unsigned long flags;
2530	dasd_device_t *device;
2531
2532	if ((!inp) || !(inp->i_rdev)) {
2533		rc = -EINVAL;
2534                goto fail;
2535	}
2536	if (dasd_probeonly) {
2537		printk ("\n" KERN_INFO PRINTK_HEADER
2538			"No access to device (%d:%d) due to probeonly mode\n",
2539			MAJOR (inp->i_rdev),
2540                        MINOR (inp->i_rdev));
2541		rc = -EPERM;
2542                goto fail;
2543	}
2544        spin_lock_irqsave(&discipline_lock,flags);
2545	device = dasd_device_from_kdev (inp->i_rdev);
2546	if (!device) {
2547		printk (KERN_WARNING PRINTK_HEADER
2548			"No device registered as (%d:%d)\n",
2549			MAJOR (inp->i_rdev),
2550                        MINOR (inp->i_rdev));
2551		rc = -ENODEV;
2552                goto unlock;
2553	}
2554	if (device->level <= DASD_STATE_ACCEPT ) {
2555		DASD_MESSAGE (KERN_WARNING, device, " %s",
2556                              " Cannot open unrecognized device\n");
2557		rc = -ENODEV;
2558                goto unlock;
2559	}
2560	if (atomic_inc_return (&device->open_count) == 1 ) {
2561                if ( device->discipline->owner )
2562                        __MOD_INC_USE_COUNT(device->discipline->owner);
2563        }
2564 unlock:
2565        spin_unlock_irqrestore(&discipline_lock,flags);
2566 fail:
2567	return rc;
2568}
2569
2570/*
2571 * DASD_RELEASE
2572 *
2573 * DESCRIPTION
2574 */
2575static int
2576dasd_release (struct inode *inp, struct file *filp)
2577{
2578	int rc = 0;
2579        int count;
2580	dasd_device_t *device;
2581
2582	if ((!inp) || !(inp->i_rdev)) {
2583		rc = -EINVAL;
2584                goto out;
2585	}
2586	device = dasd_device_from_kdev (inp->i_rdev);
2587	if (!device) {
2588		printk (KERN_WARNING PRINTK_HEADER
2589			"No device registered as %d:%d\n",
2590			MAJOR (inp->i_rdev),
2591                        MINOR (inp->i_rdev));
2592		rc = -EINVAL;
2593                goto out;
2594	}
2595
2596	if (device->level < DASD_STATE_ACCEPT ) {
2597		DASD_MESSAGE (KERN_WARNING, device, " %s",
2598                              " Cannot release unrecognized device\n");
2599		rc = -ENODEV;
2600                goto out;
2601	}
2602        count = atomic_dec_return (&device->open_count);
2603        if ( count == 0) {
2604                invalidate_buffers (inp->i_rdev);
2605                if ( device->discipline->owner )
2606                        __MOD_DEC_USE_COUNT(device->discipline->owner);
2607	} else if ( count == -1 ) { /* paranoia only */
2608                atomic_set (&device->open_count,0);
2609                printk (KERN_WARNING PRINTK_HEADER
2610                        "release called with open count==0\n");
2611        }
2612 out:
2613	return rc;
2614}
2615
2616static struct
2617block_device_operations dasd_device_operations =
2618{
2619	owner:THIS_MODULE,
2620	open:dasd_open,
2621	release:dasd_release,
2622	ioctl:dasd_ioctl,
2623};
2624
2625/* SECTION: Management of device list */
2626int
2627dasd_fillgeo(int kdev,struct hd_geometry *geo)
2628{
2629	dasd_device_t *device = dasd_device_from_kdev (kdev);
2630
2631	if (!device)
2632                return -EINVAL;
2633
2634        if (!device->discipline->fill_geometry)
2635		return -EINVAL;
2636
2637	device->discipline->fill_geometry (device, geo);
2638	geo->start = device->major_info->gendisk.part[MINOR(kdev)].start_sect
2639		     >> device->sizes.s2b_shift;;
2640        return 0;
2641}
2642
2643
2644/* This one is needed for naming 18000+ possible dasd devices */
2645int
2646dasd_device_name (char *str, int index, int partition, struct gendisk *hd)
2647{
2648	int len = 0;
2649	char first, second, third;
2650
2651	if (hd) {
2652		major_info_t *major_info = NULL;
2653		struct list_head *l;
2654
2655		list_for_each (l, &dasd_major_info[0].list) {
2656			major_info = list_entry (l, major_info_t, list);
2657			if (&major_info->gendisk == hd) {
2658				break;
2659			}
2660			index += DASD_PER_MAJOR;
2661		}
2662		if (major_info == &dasd_major_info[0]) {
2663			return -EINVAL;
2664		}
2665	}
2666	third = index % 26;
2667	second = ((index - 26) / 26) % 26;
2668	first = (((index - 702) / 26) / 26) % 26;
2669
2670	len = sprintf (str, "dasd");
2671	if (index > 701) {
2672		len += sprintf (str + len, "%c", first + 'a');
2673	}
2674	if (index > 25) {
2675		len += sprintf (str + len, "%c", second + 'a');
2676	}
2677	len += sprintf (str + len, "%c", third + 'a');
2678	if (partition) {
2679		if (partition > 9) {
2680			return -EINVAL;
2681		} else {
2682			len += sprintf (str + len, "%d", partition);
2683		}
2684	}
2685	str[len] = '\0';
2686	return 0;
2687}
2688
2689static void
2690dasd_plug_device (dasd_device_t * device)
2691{
2692	atomic_set(&device->plugged,1);
2693}
2694
2695static void
2696dasd_unplug_device (dasd_device_t * device)
2697{
2698	atomic_set(&device->plugged,0);
2699        dasd_schedule_bh(device);
2700}
2701
2702static void
2703dasd_flush_chanq ( dasd_device_t * device, int destroy )
2704{
2705        ccw_req_t *cqr;
2706        unsigned long flags;
2707        if ( destroy ) {
2708                s390irq_spin_lock_irqsave (device->devinfo.irq, flags);
2709                cqr = device->queue.head;
2710                while ( cqr != NULL ) {
2711                        if ( cqr->status == CQR_STATUS_IN_IO )
2712                                device->discipline->term_IO (cqr);
2713                        if ( cqr->status != CQR_STATUS_DONE ||
2714                             cqr->status != CQR_STATUS_FAILED ) {
2715
2716                                cqr->status = CQR_STATUS_FAILED;
2717                                asm volatile ("STCK %0":"=m" (cqr->stopclk));
2718
2719                        }
2720                        dasd_schedule_bh(device);
2721                        cqr = cqr->next;
2722                }
2723                s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags);
2724        }
2725        wait_event( device->wait_q, device->queue.head == NULL );
2726}
2727
2728static void
2729dasd_flush_request_queues ( dasd_device_t * device, int destroy )
2730{
2731        int i;
2732        int major = MAJOR(device->kdev);
2733        int minor = MINOR(device->kdev);
2734        for ( i = 0; i < (1 << DASD_PARTN_BITS); i ++) {
2735                if ( destroy )
2736                        destroy_buffers(MKDEV(major,minor+i));
2737                else
2738                        invalidate_buffers(MKDEV(major,minor+i));
2739        }
2740}
2741
2742static int
2743dasd_disable_volume ( dasd_device_t * device, int force )
2744{
2745        int rc = 0;
2746        int target  = DASD_STATE_KNOWN;
2747        int count = atomic_read (&device->open_count);
2748
2749	if ( count ) {
2750		DASD_MESSAGE (KERN_EMERG, device, "%s",
2751			      "device has vanished although it was open!");
2752        }
2753        if ( force ) {
2754                dasd_deactivate_queue(device);
2755                dasd_flush_chanq(device,force);
2756                dasd_flush_request_queues(device,force);
2757                dasd_disable_blkdev(device);
2758                target = DASD_STATE_DEL;
2759        }
2760
2761        /* unregister partitions ('ungrok_partitions') */
2762        devfs_register_partitions(&device->major_info->gendisk,
2763                                  MINOR(device->kdev),1);
2764
2765        DASD_MESSAGE (KERN_WARNING, device,
2766                      "disabling device, target state: %d",target);
2767
2768        dasd_set_device_level (device->devinfo.devno,
2769                               device->discipline,
2770                               target);
2771        return rc;
2772}
2773
2774static void
2775dasd_disable_ranges (dasd_range_t *range,
2776                     dasd_discipline_t *d,
2777                     int all, int force )
2778{
2779        dasd_range_t *rrange;
2780        int j;
2781
2782        if (range == &dasd_range_head) {
2783                rrange = list_entry (range->list.next,
2784                                     dasd_range_t, list);
2785        } else {
2786                rrange = range;
2787        }
2788        do {
2789                for (j = rrange->from; j <= rrange->to; j++) {
2790                        dasd_device_t **dptr;
2791                        dasd_device_t *device;
2792                        dptr = dasd_device_from_devno(j);
2793                        if ( dptr == NULL ) {
2794                            continue;
2795                        }
2796                        device = *dptr;
2797                        if (device == NULL ||
2798                            (d != NULL &&
2799                             device -> discipline != d))
2800                                continue;
2801
2802                        dasd_disable_volume(device, force);
2803                }
2804                rrange = list_entry (rrange->list.next, dasd_range_t, list);
2805        } while ( all && rrange && rrange != range );
2806}
2807
2808static void
2809dasd_enable_single_device ( unsigned long arg ) {
2810        dasd_device_t * device =(dasd_device_t *) arg;
2811        int devno = device->devinfo.devno;
2812        dasd_range_t range = { from: devno, to:devno };
2813        dasd_enable_ranges (&range,NULL,0);
2814}
2815
2816static void
2817dasd_enable_ranges (dasd_range_t *range, dasd_discipline_t *d, int all )
2818{
2819        int retries = 0;
2820	int j;
2821        kdev_t tempdev;
2822	dasd_range_t *rrange;
2823
2824	if (range == NULL)
2825		return;
2826
2827        do {
2828                if (range == &dasd_range_head) {
2829                        rrange = list_entry (range->list.next,
2830                                             dasd_range_t, list);
2831                } else {
2832                        rrange = range;
2833                }
2834                do {
2835                        for (j = rrange->from; j <= rrange->to; j++) {
2836                                if ( dasd_devindex_from_devno(j) < 0 )
2837                                        continue;
2838                                dasd_set_device_level (j, d, DASD_STATE_ONLINE);
2839                        }
2840                        rrange = list_entry (rrange->list.next, dasd_range_t, list);
2841                } while ( all && rrange && rrange != range );
2842
2843                if (atomic_read (&dasd_init_pending) == 0) /* we are done, exit loop */
2844                        break;
2845
2846                if ( retries == 0 ) {
2847                        printk (KERN_INFO PRINTK_HEADER
2848                                "waiting for responses...\n");
2849                } else if ( retries < 5 ) {
2850                        printk (KERN_INFO PRINTK_HEADER
2851                                "waiting a little bit longer...\n");
2852                } else {
2853                        printk (KERN_INFO PRINTK_HEADER
2854                                "giving up, enable late devices manually!\n");
2855                        break;
2856                }
2857                interruptible_sleep_on_timeout (&dasd_init_waitq, (1 * HZ));
2858                retries ++;
2859        } while (1);
2860        /* now setup block devices */
2861
2862        /* Now do block device and partition setup */
2863        if (range == &dasd_range_head) {
2864                rrange = list_entry (range->list.next,
2865                                     dasd_range_t, list);
2866        } else {
2867                rrange = range;
2868        }
2869        do {
2870                for (j = rrange->from; j <= rrange->to; j++) {
2871                        dasd_device_t **dptr;
2872                        dasd_device_t *device;
2873                        if ( dasd_devindex_from_devno(j) < 0 )
2874                                continue;
2875                        dptr = dasd_device_from_devno(j);
2876                        device = *dptr;
2877                        if (device == NULL )
2878                                continue;
2879                        if ( ((d == NULL && device->discipline != NULL) ||
2880                              (device->discipline == d )) &&
2881                             device->level >= DASD_STATE_READY &&
2882                             device->request_queue == NULL ) {
2883                                if (dasd_features_from_devno(j)&DASD_FEATURE_READONLY) {
2884                                        for (tempdev=device->kdev;
2885                                             tempdev<(device->kdev +(1 << DASD_PARTN_BITS));
2886                                             tempdev++)
2887                                                set_device_ro (tempdev, 1);
2888
2889                                        printk (KERN_WARNING PRINTK_HEADER
2890                                                "setting read-only mode for device /dev/%s\n",
2891                                                device->name);
2892                                }
2893                                dasd_setup_blkdev(device);
2894                                dasd_setup_partitions(device);
2895                        }
2896                }
2897                rrange = list_entry (rrange->list.next, dasd_range_t, list);
2898        } while ( all && rrange && rrange != range );
2899}
2900
2901#ifdef CONFIG_DASD_DYNAMIC
2902/*
2903 * DASD_NOT_OPER_HANDLER
2904 *
2905 * DESCRIPTION
2906 *   handles leaving devices
2907 */
2908static void
2909dasd_not_oper_handler (int irq, int status)
2910{
2911	dasd_device_t *device = NULL;
2912	major_info_t *major_info = NULL;
2913	struct list_head *l;
2914	int i, devno = -ENODEV;
2915
2916	/* find out devno of leaving device: CIO has already deleted this information ! */
2917	list_for_each (l, &dasd_major_info[0].list) {
2918		major_info = list_entry (l, major_info_t, list);
2919		for (i = 0; i < DASD_PER_MAJOR; i++) {
2920			device = major_info->dasd_device[i];
2921			if (device && device->devinfo.irq == irq) {
2922				devno = device->devinfo.devno;
2923				break;
2924			}
2925		}
2926		if (devno != -ENODEV)
2927			break;
2928	}
2929
2930	DASD_DRIVER_DEBUG_EVENT (5, dasd_not_oper_handler,
2931                                 "called for devno %04x",
2932                                 devno);
2933
2934	if (devno < 0) {
2935		printk (KERN_WARNING PRINTK_HEADER
2936			"not_oper_handler called on irq 0x%04x no devno!\n",
2937                        irq);
2938		return;
2939	}
2940        dasd_disable_volume(device, 1);
2941}
2942
2943/*
2944 * DASD_OPER_HANDLER
2945 *
2946 * DESCRIPTION
2947 *   called by the machine check handler to make an device operational
2948 */
2949int
2950dasd_oper_handler (int irq, devreg_t * devreg)
2951{
2952	int devno;
2953	int rc = 0;
2954	major_info_t *major_info = NULL;
2955        dasd_range_t *rptr,range;
2956        dasd_device_t *device = NULL;
2957	struct list_head *l;
2958        int i;
2959
2960	devno = get_devno_by_irq (irq);
2961	if (devno == -ENODEV) {
2962		rc = -ENODEV;
2963                goto out;
2964	}
2965
2966	DASD_DRIVER_DEBUG_EVENT (5, dasd_oper_handler,
2967                                 "called for devno %04x",
2968                                 devno);
2969
2970	/* find out devno of device */
2971	list_for_each (l, &dasd_major_info[0].list) {
2972		major_info = list_entry (l, major_info_t, list);
2973		for (i = 0; i < DASD_PER_MAJOR; i++) {
2974			device = major_info->dasd_device[i];
2975			if (device && device->devinfo.irq == irq) {
2976				devno = device->devinfo.devno;
2977				break;
2978			}
2979		}
2980		if (devno != -ENODEV)
2981			break;
2982	}
2983	if (devno < 0) {
2984                BUG();
2985	}
2986        if ( device &&
2987             device->level == DASD_STATE_READY ) {
2988            dasd_set_device_level (device->devinfo.devno,
2989                                   device->discipline, DASD_STATE_ONLINE);
2990
2991        } else {
2992            if (dasd_autodetect) {
2993		rptr = dasd_add_range (devno, devno, DASD_DEFAULT_FEATURES);
2994                if ( rptr == NULL ) {
2995                    rc = -ENOMEM;
2996                    goto out;
2997                }
2998            } else {
2999                range.from = devno;
3000                range.to = devno;
3001                rptr = &range;
3002            }
3003            dasd_enable_ranges (rptr, NULL, 0);
3004        }
3005 out:
3006	return rc;
3007}
3008#endif				/* CONFIG_DASD_DYNAMIC */
3009
3010static inline dasd_device_t **
3011dasd_find_device_addr ( int devno )
3012{
3013        dasd_device_t **device_addr;
3014
3015	DASD_DRIVER_DEBUG_EVENT (1, dasd_find_device_addr,
3016                                 "devno %04x",
3017                                 devno);
3018	if ( dasd_devindex_from_devno (devno) < 0 ) {
3019                DASD_DRIVER_DEBUG_EXCEPTION (1, dasd_find_device_addr,
3020                                             "no dasd: devno %04x",
3021                                             devno);
3022		return NULL;
3023	}
3024        /* allocate major numbers on demand  for new devices */
3025	while ((device_addr = dasd_device_from_devno (devno)) == NULL) {
3026                int rc;
3027
3028		if ((rc = dasd_register_major (NULL)) <= 0) {
3029
3030                        DASD_DRIVER_DEBUG_EXCEPTION (1, dasd_find_device_addr,
3031                                                     "%s",
3032                                                     "out of major numbers!");
3033                        break;
3034		}
3035	}
3036        return device_addr;
3037}
3038
3039static inline int
3040dasd_state_del_to_new (dasd_device_t **addr )
3041{
3042        dasd_device_t* device;
3043        int rc = 0;
3044	if (*addr == NULL) { /* allocate device descriptor on demand for new device */
3045                device = kmalloc (sizeof (dasd_device_t), GFP_ATOMIC);
3046		if (device == NULL ) {
3047			rc = -ENOMEM;
3048                        goto out;
3049		}
3050		memset (device, 0, sizeof (dasd_device_t));
3051                *addr = device;
3052                device->lowmem_ccws = (void*)get_free_page (GFP_ATOMIC|GFP_DMA);
3053                if (device->lowmem_ccws == NULL) {
3054                        rc = -ENOMEM;
3055                        goto noccw;
3056	}
3057#ifdef CONFIG_ARCH_S390X
3058                device->lowmem_idals =
3059                    device->lowmem_idal_ptr = (void*) get_free_page (GFP_ATOMIC|GFP_DMA);
3060                if (device->lowmem_idals == NULL) {
3061                        rc = -ENOMEM;
3062                        goto noidal;
3063                }
3064#endif
3065}
3066        goto out;
3067#ifdef CONFIG_ARCH_S390X
3068 noidal:
3069        free_page ((long) device->lowmem_ccws);
3070#endif
3071 noccw:
3072        kfree(device);
3073 out:
3074        return rc;
3075}
3076
3077static inline int
3078dasd_state_new_to_del (dasd_device_t **addr )
3079{
3080        dasd_device_t *device = *addr;
3081        if (device && device->private) {
3082                kfree(device->private);
3083                device->private = NULL;
3084        }
3085#ifdef CONFIG_ARCH_S390X
3086        free_page ((long)(device->lowmem_idals));
3087#endif
3088        free_page((long)(device->lowmem_ccws));
3089        kfree(device);
3090        *addr = NULL;
3091        return 0;
3092}
3093
3094static inline int
3095dasd_state_new_to_known (dasd_device_t **dptr, int devno, dasd_discipline_t *disc)
3096{
3097        int rc = 0;
3098	umode_t devfs_perm  = S_IFBLK | S_IRUSR | S_IWUSR;
3099        struct list_head *l;
3100        major_info_t *major_info = NULL;
3101        int i;
3102        dasd_device_t *device = *dptr;
3103        devfs_handle_t dir;
3104        char buffer[5];
3105
3106
3107	list_for_each (l, &dasd_major_info[0].list) {
3108                major_info = list_entry (l, major_info_t, list);
3109		for (i = 0; i < DASD_PER_MAJOR; i++) {
3110			if (major_info->dasd_device[i] == device) {
3111				device->kdev = MKDEV (major_info->gendisk.major,
3112                                                      i << DASD_PARTN_BITS);
3113				break;
3114			}
3115		}
3116		if (i < DASD_PER_MAJOR) /* we found one */
3117			break;
3118	}
3119        if ( major_info == NULL || major_info == &dasd_major_info[0] )
3120                BUG();
3121
3122        device->major_info = major_info;
3123        dasd_device_name (device->name,
3124                          (((long)dptr -
3125                            (long)device->major_info->dasd_device) /
3126                           sizeof (dasd_device_t *)),
3127                          0, &device->major_info->gendisk);
3128        init_waitqueue_head (&device->wait_q);
3129
3130        rc = get_dev_info_by_devno (devno, &device->devinfo);
3131        if ( rc ) {
3132                goto out;
3133        }
3134
3135	DASD_DRIVER_DEBUG_EVENT (5, dasd_state_new_to_known,
3136                                 "got devinfo CU-type %04x and dev-type %04x",
3137                                 device->devinfo.sid_data.cu_type,
3138                                 device->devinfo.sid_data.dev_type);
3139
3140
3141        if ( devno != device->devinfo.devno )
3142                BUG();
3143        device->discipline = dasd_find_disc (device, disc);
3144        if ( device->discipline == NULL ) {
3145                rc = -ENODEV;
3146                goto out;
3147        }
3148        sprintf (buffer, "%04x",
3149                 device->devinfo.devno);
3150        dir = devfs_mk_dir (dasd_devfs_handle, buffer, device);
3151        device->major_info->gendisk.de_arr[MINOR(device->kdev)
3152                                          >> DASD_PARTN_BITS] = dir;
3153	if (dasd_features_from_devno(device->devinfo.devno)&DASD_FEATURE_READONLY) {
3154	        devfs_perm &= ~(S_IWUSR);
3155	}
3156        device->devfs_entry = devfs_register (dir,"device",DEVFS_FL_DEFAULT,
3157                                              MAJOR(device->kdev),
3158                                              MINOR(device->kdev),
3159                                              devfs_perm,
3160                                              &dasd_device_operations,NULL);
3161        device->level = DASD_STATE_KNOWN;
3162 out:
3163        return rc;
3164}
3165
3166static inline int
3167dasd_state_known_to_new (dasd_device_t *device )
3168{
3169        int rc = 0;
3170        /* don't reset to zeros because of persistent data durich detach/attach! */
3171        devfs_unregister(device->devfs_entry);
3172        devfs_unregister(device->major_info->gendisk.de_arr[MINOR(device->kdev) >> DASD_PARTN_BITS]);
3173
3174        return rc;
3175}
3176
3177static inline int
3178dasd_state_known_to_accept (dasd_device_t *device)
3179{
3180        int rc = 0;
3181        device->debug_area = debug_register (device->name, 0, 2,
3182                                             3 * sizeof (long));
3183        debug_register_view (device->debug_area, &debug_sprintf_view);
3184        debug_register_view (device->debug_area, &debug_hex_ascii_view);
3185        DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area created",
3186                                 device);
3187
3188        if (device->discipline->int_handler) {
3189                rc = s390_request_irq_special (device->devinfo.irq,
3190                                               device->discipline->int_handler,
3191                                               dasd_not_oper_handler,
3192                                               0, DASD_NAME,
3193                                               &device->dev_status);
3194                if ( rc ) {
3195                        printk("No request IRQ\n");
3196                        goto out;
3197                }
3198        }
3199        device->level = DASD_STATE_ACCEPT;
3200 out:
3201        return rc;
3202}
3203
3204static inline int
3205dasd_state_accept_to_known (dasd_device_t *device )
3206{
3207        if ( device->discipline == NULL )
3208                goto out;
3209        if (device->discipline->int_handler) {
3210                free_irq (device->devinfo.irq, &device->dev_status);
3211        }
3212        DASD_DEVICE_DEBUG_EVENT (0, device,"%p debug area deleted",
3213                                 device);
3214        if ( device->debug_area != NULL )
3215                debug_unregister (device->debug_area);
3216        device->discipline = NULL;
3217        device->level = DASD_STATE_KNOWN;
3218 out:
3219        return 0;
3220}
3221
3222static inline int
3223dasd_state_accept_to_init (dasd_device_t *device)
3224{
3225        int rc = 0;
3226        unsigned long flags;
3227
3228        if ( device->discipline->init_analysis ) {
3229                device->init_cqr=device->discipline->init_analysis (device);
3230                if ( device->init_cqr != NULL ) {
3231                        if ( device->discipline->start_IO == NULL )
3232                                BUG();
3233                        atomic_inc (&dasd_init_pending);
3234                        s390irq_spin_lock_irqsave (device->devinfo.irq,
3235                                                   flags);
3236                        rc = device->discipline->start_IO (device->init_cqr);
3237                        s390irq_spin_unlock_irqrestore(device->devinfo.irq,
3238                                                       flags);
3239                        if ( rc )
3240                                goto out;
3241                        device->level = DASD_STATE_INIT;
3242                } else {
3243                        rc = -ENOMEM;
3244                }
3245        } else {
3246                rc = dasd_state_init_to_ready ( device );
3247        }
3248 out:
3249        return rc;
3250}
3251
3252static inline int
3253dasd_state_init_to_ready (dasd_device_t *device )
3254{
3255        int rc = 0;
3256        if (device->discipline->do_analysis != NULL)
3257                if ( device->discipline->do_analysis (device) == 0 )
3258                        switch (device->sizes.bp_block) {
3259                        case 512:
3260                        case 1024:
3261                        case 2048:
3262                        case 4096:
3263                                break;
3264                        default:
3265                                rc = -EMEDIUMTYPE;
3266                        }
3267        if ( device->init_cqr ) {
3268                /* This pointer is no longer needed, BUT dont't free the       */
3269                /* memory, because this is done in bh for finished request!!!! */
3270                atomic_dec(&dasd_init_pending);
3271                device->init_cqr = NULL;
3272        }
3273        device->level = DASD_STATE_READY;
3274        return rc;
3275}
3276
3277static inline int
3278dasd_state_ready_to_accept (dasd_device_t *device )
3279{
3280        int rc = 0;
3281        unsigned long flags;
3282
3283        s390irq_spin_lock_irqsave (device->devinfo.irq, flags);
3284        if ( device->init_cqr != NULL &&  atomic_read(&dasd_init_pending) != 0 ) {
3285                if ( device->discipline->term_IO == NULL )
3286                        BUG();
3287                device->discipline->term_IO (device->init_cqr);
3288                atomic_dec (&dasd_init_pending);
3289                dasd_free_request (device->init_cqr, device);
3290                device->init_cqr = NULL;
3291        }
3292        s390irq_spin_unlock_irqrestore(device->devinfo.irq, flags);
3293        memset(&device->sizes,0,sizeof(dasd_sizes_t));
3294        device->level = DASD_STATE_ACCEPT;
3295        return rc;
3296}
3297
3298static inline int
3299dasd_state_ready_to_online (dasd_device_t *device )
3300{
3301        int rc = 0;
3302        dasd_unplug_device (device);
3303        device->level = DASD_STATE_ONLINE;
3304        return rc;
3305}
3306
3307static inline int
3308dasd_state_online_to_ready (dasd_device_t *device )
3309{
3310        int rc = 0;
3311        dasd_plug_device (device);
3312        device->level = DASD_STATE_READY;
3313        return rc;
3314}
3315
3316static inline int
3317dasd_setup_blkdev (dasd_device_t *device )
3318{
3319        int rc = 0;
3320        int i;
3321        int major = MAJOR(device->kdev);
3322        int minor = MINOR(device->kdev);
3323
3324        for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
3325                if (i == 0)
3326                        device->major_info->gendisk.sizes[minor] =
3327                                (device->sizes.blocks << device->
3328                                 sizes.s2b_shift) >> 1;
3329                else
3330                        device->major_info->gendisk.sizes[minor + i] = 0;
3331                hardsect_size[major][minor + i] = device->sizes.bp_block;
3332                blksize_size[major][minor + i] = device->sizes.bp_block;
3333                max_sectors[major][minor + i] =
3334                        device->discipline->max_blocks <<
3335                        device->sizes.s2b_shift;
3336		device->major_info->gendisk.part[minor+i].start_sect = 0;
3337		device->major_info->gendisk.part[minor+i].nr_sects = 0;
3338        }
3339        device->request_queue = kmalloc(sizeof(request_queue_t),GFP_KERNEL);
3340        device->request_queue->queuedata = device;
3341        blk_init_queue (device->request_queue, do_dasd_request);
3342        blk_queue_headactive (device->request_queue, 0);
3343        elevator_init (&(device->request_queue->elevator),ELEVATOR_NOOP);
3344        return rc;
3345}
3346
3347static void
3348dasd_deactivate_queue (dasd_device_t *device)
3349{
3350        int i;
3351        int minor = MINOR(device->kdev);
3352
3353        for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
3354                device->major_info->gendisk.sizes[minor + i] = 0;
3355        }
3356}
3357
3358static inline int
3359dasd_disable_blkdev (dasd_device_t *device )
3360{
3361        int i;
3362        int major = MAJOR(device->kdev);
3363        int minor = MINOR(device->kdev);
3364
3365        for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
3366                destroy_buffers(MKDEV(major,minor+i));
3367                device->major_info->gendisk.sizes[minor + i] = 0;
3368                hardsect_size[major][minor + i] = 0;
3369                blksize_size[major][minor + i] = 0;
3370                max_sectors[major][minor + i] = 0;
3371        }
3372        if (device->request_queue) {
3373            blk_cleanup_queue (device->request_queue);
3374            kfree(device->request_queue);
3375            device->request_queue = NULL;
3376        }
3377        return 0;
3378}
3379
3380
3381/*
3382 * function dasd_setup_partitions
3383 * calls the function in genhd, which is appropriate to setup a partitioned disk
3384 */
3385static inline void
3386dasd_setup_partitions ( dasd_device_t * device )
3387{
3388	register_disk (&device->major_info->gendisk,
3389                       device->kdev,
3390		       1 << DASD_PARTN_BITS,
3391		       &dasd_device_operations,
3392		       (device->sizes.blocks << device->sizes.s2b_shift));
3393}
3394
3395static inline void
3396dasd_destroy_partitions ( dasd_device_t * device )
3397{
3398        int i;
3399        int minor = MINOR(device->kdev);
3400
3401        for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
3402                device->major_info->gendisk.part[minor+i].start_sect = 0;
3403                device->major_info->gendisk.part[minor+i].nr_sects   = 0;
3404        }
3405        devfs_register_partitions(&device->major_info->gendisk,
3406                                  MINOR(device->kdev),1);
3407}
3408
3409static inline void
3410dasd_resetup_partitions ( dasd_device_t * device )
3411{
3412    BUG();
3413    dasd_destroy_partitions ( device ) ;
3414    dasd_setup_partitions ( device ) ;
3415}
3416
3417/*
3418 * function dasd_set_device_level
3419 */
3420static int
3421dasd_set_device_level (unsigned int devno,
3422                       dasd_discipline_t * discipline,
3423                       int to_state)
3424{
3425	int rc = 0;
3426        dasd_device_t **device_addr;
3427        dasd_device_t *device;
3428        int from_state;
3429
3430        device_addr = dasd_find_device_addr ( devno );
3431        if ( device_addr == NULL ) {
3432                rc = -ENODEV;
3433                goto out;
3434        }
3435        device = *device_addr;
3436
3437        if ( device == NULL ) {
3438                from_state = DASD_STATE_DEL;
3439                if ( to_state == DASD_STATE_DEL )
3440                        goto out;
3441        } else {
3442                from_state = device->level;
3443        }
3444
3445        DASD_DRIVER_DEBUG_EVENT (3, dasd_set_device_level,
3446                                 "devno %04x; from %i to %i",
3447                                 devno,
3448                                 from_state,
3449                                 to_state);
3450
3451        if ( from_state == to_state )
3452                goto out;
3453
3454        if ( to_state < from_state )
3455                goto shutdown;
3456
3457        /* First check for bringup */
3458        if ( from_state <= DASD_STATE_DEL &&
3459             to_state >= DASD_STATE_NEW ) {
3460                rc = dasd_state_del_to_new(device_addr);
3461                if ( rc ) {
3462                        goto bringup_fail;
3463                }
3464                device = *device_addr;
3465        }
3466        if ( from_state <= DASD_STATE_NEW &&
3467             to_state >= DASD_STATE_KNOWN ) {
3468                rc = dasd_state_new_to_known( device_addr, devno, discipline );
3469                if ( rc ) {
3470                        goto bringup_fail;
3471                }
3472        }
3473        if ( from_state <= DASD_STATE_KNOWN &&
3474             to_state >= DASD_STATE_ACCEPT ) {
3475                rc = dasd_state_known_to_accept(device);
3476                if ( rc ) {
3477                        goto bringup_fail;
3478                }
3479        }
3480        if ( dasd_probeonly ) {
3481            goto out;
3482        }
3483        if ( from_state <= DASD_STATE_ACCEPT &&
3484             to_state >= DASD_STATE_INIT ) {
3485                rc = dasd_state_accept_to_init(device);
3486                if ( rc ) {
3487                        goto bringup_fail;
3488                }
3489        }
3490        if ( from_state <= DASD_STATE_INIT &&
3491             to_state >= DASD_STATE_READY ) {
3492                rc = -EAGAIN;
3493                goto out;
3494        }
3495        if ( from_state <= DASD_STATE_READY &&
3496             to_state >= DASD_STATE_ONLINE ) {
3497                rc = dasd_state_ready_to_online(device);
3498                if ( rc ) {
3499                        goto bringup_fail;
3500                }
3501        }
3502        goto out;
3503 bringup_fail:   /* revert changes */
3504        to_state = from_state;
3505        from_state = device->level;
3506
3507        /* now do a shutdown */
3508 shutdown:
3509        if ( from_state >= DASD_STATE_ONLINE &&
3510             to_state <= DASD_STATE_READY )
3511                if (dasd_state_online_to_ready(device))
3512                        BUG();
3513
3514        if ( from_state >= DASD_STATE_READY &&
3515             to_state <= DASD_STATE_ACCEPT )
3516                if ( dasd_state_ready_to_accept(device))
3517                        BUG();
3518
3519        if ( from_state >= DASD_STATE_ACCEPT &&
3520             to_state <= DASD_STATE_KNOWN )
3521                if ( dasd_state_accept_to_known(device))
3522                        BUG();
3523
3524        if ( from_state >= DASD_STATE_KNOWN &&
3525             to_state <= DASD_STATE_NEW )
3526                if ( dasd_state_known_to_new(device))
3527                        BUG();
3528
3529        if ( from_state >= DASD_STATE_NEW &&
3530             to_state <= DASD_STATE_DEL)
3531                if (dasd_state_new_to_del(device_addr))
3532                        BUG();
3533        goto out;
3534 out:
3535        return rc;
3536}
3537
3538/* SECTION: Procfs stuff */
3539typedef struct {
3540	char *data;
3541	int len;
3542} tempinfo_t;
3543
3544void
3545dasd_fill_inode (struct inode *inode, int fill)
3546{
3547	if (fill)
3548		MOD_INC_USE_COUNT;
3549	else
3550		MOD_DEC_USE_COUNT;
3551}
3552
3553static struct proc_dir_entry *dasd_proc_root_entry = NULL;
3554static struct proc_dir_entry *dasd_devices_entry;
3555static struct proc_dir_entry *dasd_statistics_entry;
3556
3557static int
3558dasd_devices_open (struct inode *inode, struct file *file)
3559{
3560	int rc = 0;
3561	int size = 1;
3562	int len = 0;
3563	major_info_t *temp = NULL;
3564	struct list_head *l;
3565	tempinfo_t *info;
3566	int i;
3567        unsigned long flags;
3568        int index = 0;
3569
3570        MOD_INC_USE_COUNT;
3571        spin_lock_irqsave(&discipline_lock,flags);
3572	info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
3573	if (info == NULL) {
3574                printk (KERN_WARNING "No memory available for data\n");
3575                MOD_DEC_USE_COUNT;
3576                return -ENOMEM;
3577	} else {
3578		file->private_data = (void *) info;
3579	}
3580	list_for_each (l, &dasd_major_info[0].list) {
3581                size += 128 * 1 << (MINORBITS - DASD_PARTN_BITS);
3582	}
3583	info->data = (char *) vmalloc (size);
3584	DASD_DRIVER_DEBUG_EVENT (1, dasd_devices_open, "area: %p, size 0x%x",
3585				 info->data,
3586                                 size);
3587	if (size && info->data == NULL) {
3588		printk (KERN_WARNING "No memory available for data\n");
3589		vfree (info);
3590                MOD_DEC_USE_COUNT;
3591		return -ENOMEM;
3592	}
3593	list_for_each (l, &dasd_major_info[0].list) {
3594		temp = list_entry (l, major_info_t, list);
3595		for (i = 0; i < 1 << (MINORBITS - DASD_PARTN_BITS); i++) {
3596			dasd_device_t *device;
3597                        int devno = dasd_devno_from_devindex(index+i);
3598                        int features;
3599
3600                        if ( devno == -ENODEV )
3601                                continue;
3602
3603                        features = dasd_features_from_devno(devno);
3604                        if (features < DASD_DEFAULT_FEATURES)
3605                                features = DASD_DEFAULT_FEATURES;
3606
3607                        device = temp->dasd_device[i];
3608			if (device) {
3609
3610				len += sprintf (info->data + len,
3611						"%04x(%s) at (%3d:%3d) is %-7s%4s: ",
3612						device->devinfo.devno,
3613						device->discipline ?
3614						device->
3615						discipline->name : "none",
3616						temp->gendisk.major,
3617						i << DASD_PARTN_BITS,
3618						device->name,
3619                                                (features & DASD_FEATURE_READONLY) ?
3620                                                "(ro)" : " ");
3621
3622				switch (device->level) {
3623				case DASD_STATE_NEW:
3624                                        len +=
3625					    sprintf (info->data + len,
3626						     "new");
3627                                        break;
3628				case DASD_STATE_KNOWN:
3629					len +=
3630					    sprintf (info->data + len,
3631						     "detected");
3632					break;
3633				case DASD_STATE_ACCEPT:
3634                                        len += sprintf (info->data + len,"accepted");
3635					break;
3636				case DASD_STATE_INIT:
3637					len +=
3638					    sprintf (info->data + len,
3639						     "busy   ");
3640					break;
3641				case DASD_STATE_READY:
3642				case DASD_STATE_ONLINE:
3643                                    if ( atomic_read(&device->plugged) )
3644                                        len +=
3645                                            sprintf (info->data + len,
3646                                                     "fenced ");
3647                                    else
3648                                        len +=
3649                                            sprintf (info->data + len,
3650                                                     "active ");
3651                                    if ( device->sizes.bp_block == 512 ||
3652                                         device->sizes.bp_block == 1024 ||
3653                                         device->sizes.bp_block == 2048 ||
3654                                         device->sizes.bp_block == 4096 )
3655					len +=
3656					    sprintf (info->data + len,
3657						     "at blocksize: %d, %ld blocks, %ld MB",
3658						     device->sizes.bp_block,
3659						     device->sizes.blocks,
3660						     ((device->
3661						       sizes.bp_block >> 9) *
3662						      device->sizes.
3663						      blocks) >> 11);
3664                                    else
3665                                        len +=
3666                                            sprintf (info->data + len,
3667                                                     "n/f    ");
3668					break;
3669				default:
3670					len +=
3671					    sprintf (info->data + len,
3672						     "no stat");
3673					break;
3674				}
3675			} else {
3676                                char buffer[7];
3677                                dasd_device_name (buffer, i, 0, &temp->gendisk);
3678                                if ( devno < 0  ) {
3679                                        len += sprintf (info->data + len,
3680                                                        "none");
3681                                } else {
3682                                        len += sprintf (info->data + len,
3683                                                        "%04x",devno);
3684                                }
3685                                len += sprintf (info->data + len,
3686                                                "(none) at (%3d:%3d) is %-7s%4s: unknown",
3687						temp->gendisk.major,
3688						i << DASD_PARTN_BITS,
3689						buffer,
3690                                                (features & DASD_FEATURE_READONLY) ?
3691                                                "(ro)" : " ");
3692                        }
3693                        if ( dasd_probeonly )
3694                            len += sprintf(info->data + len,"(probeonly)");
3695                        len += sprintf(info->data + len,"\n");
3696		}
3697                index += 1 << (MINORBITS - DASD_PARTN_BITS);
3698	}
3699	info->len = len;
3700        spin_unlock_irqrestore(&discipline_lock,flags);
3701	return rc;
3702}
3703
3704#define MIN(a,b) ((a)<(b)?(a):(b))
3705
3706static ssize_t
3707dasd_generic_read (struct file *file, char *user_buf, size_t user_len,
3708		   loff_t * offset)
3709{
3710	loff_t len;
3711	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
3712
3713	if (*offset >= p_info->len) {
3714		return 0;	/* EOF */
3715	} else {
3716		len = MIN (user_len, (p_info->len - *offset));
3717		if (copy_to_user (user_buf, &(p_info->data[*offset]), len))
3718			return -EFAULT;
3719		(*offset) += len;
3720		return len;	/* number of bytes "read" */
3721	}
3722}
3723
3724static ssize_t
3725dasd_devices_write (struct file *file, const char *user_buf,
3726		    size_t user_len, loff_t * offset)
3727{
3728	char *buffer;
3729	int off = 0;
3730	char *temp;
3731	dasd_range_t range;
3732        int features;
3733
3734	if (user_len > PAGE_SIZE)
3735		return -EINVAL;
3736
3737	buffer = vmalloc (user_len+1);
3738	if (buffer == NULL)
3739		return -ENOMEM;
3740	if (copy_from_user (buffer, user_buf, user_len)) {
3741		vfree (buffer);
3742		return -EFAULT;
3743	}
3744
3745        /* replace LF with '\0' */
3746        if (buffer[user_len -1] == '\n') {
3747                buffer[user_len -1] = '\0';
3748        } else {
3749                buffer[user_len] = '\0';
3750        }
3751
3752	printk (KERN_INFO PRINTK_HEADER "/proc/dasd/devices: '%s'\n", buffer);
3753	if (strncmp (buffer, "set ", 4) && strncmp (buffer, "add ", 4)) {
3754		printk (KERN_WARNING PRINTK_HEADER
3755			"/proc/dasd/devices: only 'set' and 'add' are supported verbs\n");
3756		return -EINVAL;
3757	}
3758	off += 4;
3759	while (buffer[off] && !isalnum (buffer[off]))
3760		off++;
3761	if (!strncmp (buffer + off, "device", strlen ("device"))) {
3762		off += strlen ("device");
3763		while (buffer[off] && !isalnum (buffer[off]))
3764			off++;
3765	}
3766	if (!strncmp (buffer + off, "range=", strlen ("range="))) {
3767		off += strlen ("range=");
3768		while (buffer[off] && !isalnum (buffer[off]))
3769			off++;
3770	}
3771
3772	temp = buffer + off;
3773	range.from = dasd_strtoul (temp, &temp, &features);
3774	range.to = range.from;
3775
3776	if (*temp == '-') {
3777		temp++;
3778		range.to = dasd_strtoul (temp, &temp, &features);
3779	}
3780
3781        if (range.from == -EINVAL ||
3782            range.to   == -EINVAL   ) {
3783
3784                printk (KERN_WARNING PRINTK_HEADER
3785                        "/proc/dasd/devices: range parse error in '%s'\n",
3786                        buffer);
3787        } else {
3788                off = (long) temp - (long) buffer;
3789                if (!strncmp (buffer, "add", strlen ("add"))) {
3790                        dasd_add_range (range.from, range.to, features);
3791                        dasd_enable_ranges (&range, NULL, 0);
3792                } else {
3793                        while (buffer[off] && !isalnum (buffer[off]))
3794                                off++;
3795                        if (!strncmp (buffer + off, "on", strlen ("on"))) {
3796                                dasd_enable_ranges (&range, NULL, 0);
3797                        } else if (!strncmp (buffer + off, "off", strlen ("off"))) {
3798                                dasd_disable_ranges (&range, NULL, 0, 1);
3799                        } else {
3800                                printk (KERN_WARNING PRINTK_HEADER
3801                                        "/proc/dasd/devices: parse error in '%s'\n",
3802                                        buffer);
3803                        }
3804                }
3805        }
3806
3807	vfree (buffer);
3808	return user_len;
3809}
3810
3811static int
3812dasd_devices_close (struct inode *inode, struct file *file)
3813{
3814	int rc = 0;
3815	tempinfo_t *p_info = (tempinfo_t *) file->private_data;
3816	if (p_info) {
3817		if (p_info->data)
3818			vfree (p_info->data);
3819		vfree (p_info);
3820	}
3821	MOD_DEC_USE_COUNT;
3822	return rc;
3823}
3824
3825static struct file_operations dasd_devices_file_ops = {
3826	read:dasd_generic_read,	/* read */
3827	write:dasd_devices_write,	/* write */
3828	open:dasd_devices_open,	/* open */
3829	release:dasd_devices_close,	/* close */
3830};
3831
3832static struct inode_operations dasd_devices_inode_ops = {
3833};
3834
3835static int
3836dasd_statistics_open (struct inode *inode, struct file *file)
3837{
3838	int rc = 0;
3839	int len = 0;
3840	tempinfo_t *info;
3841	int shift, i, help = 0;
3842
3843        MOD_INC_USE_COUNT;
3844	info = (tempinfo_t *) vmalloc (sizeof (tempinfo_t));
3845	if (info == NULL) {
3846		printk (KERN_WARNING "No memory available for data\n");
3847                MOD_DEC_USE_COUNT;
3848		return -ENOMEM;
3849	} else {
3850		file->private_data = (void *) info;
3851	}
3852	info->data = (char *) vmalloc (PAGE_SIZE);
3853	if (info->data == NULL) {
3854		printk (KERN_WARNING "No memory available for data\n");
3855		vfree (info);
3856		file->private_data = NULL;
3857                MOD_DEC_USE_COUNT;
3858		return -ENOMEM;
3859	}
3860
3861        /* prevent couter 'ouverflow' on output */
3862	for (shift = 0, help = dasd_global_profile.dasd_io_reqs;
3863	     help > 9999999; help = help >> 1, shift++) ;
3864
3865	len = sprintf (info->data, "%d dasd I/O requests\n",
3866                       dasd_global_profile.dasd_io_reqs);
3867	len += sprintf (info->data + len, "with %d sectors(512B each)\n",
3868                        dasd_global_profile.dasd_io_sects);
3869
3870	len += sprintf (info->data + len,
3871                        "   __<4    ___8    __16    __32    __64 "
3872                        "   _128    _256    _512    __1k    __2k "
3873                        "   __4k    __8k    _16k    _32k    _64k "
3874                        "   128k\n");
3875
3876	len += sprintf (info->data + len,
3877                        "   _256    _512    __1M    __2M    __4M "
3878                        "   __8M    _16M    _32M    _64M    128M "
3879                        "   256M    512M    __1G    __2G    __4G "
3880                        "   _>4G\n");
3881
3882	len += sprintf (info->data + len, "Histogram of sizes (512B secs)\n");
3883	for (i = 0; i < 16; i++) {
3884		len += sprintf (info->data + len, "%7d ",
3885                                dasd_global_profile.dasd_io_secs[i] >> shift);
3886	}
3887	len += sprintf (info->data + len, "\n");
3888
3889	len += sprintf (info->data + len, "Histogram of I/O times (microseconds)\n");
3890	for (i = 0; i < 16; i++) {
3891		len += sprintf (info->data + len, "%7d ",
3892                                dasd_global_profile.dasd_io_times[i] >> shift);
3893	}
3894	len += sprintf (info->data + len, "\n");
3895	for (; i < 32; i++) {
3896		len += sprintf (info->data + len, "%7d ",
3897                                dasd_global_profile.dasd_io_times[i] >> shift);
3898	}
3899	len += sprintf (info->data + len, "\n");
3900
3901	len += sprintf (info->data + len, "Histogram of I/O times per sector\n");
3902	for (i = 0; i < 16; i++) {
3903		len += sprintf (info->data + len, "%7d ",
3904                                dasd_global_profile.dasd_io_timps[i] >> shift);
3905	}
3906	len += sprintf (info->data + len, "\n");
3907	for (; i < 32; i++) {
3908		len += sprintf (info->data + len, "%7d ",
3909                                dasd_global_profile.dasd_io_timps[i] >> shift);
3910	}
3911	len += sprintf (info->data + len, "\n");
3912
3913	len += sprintf (info->data + len, "Histogram of I/O time till ssch\n");
3914	for (i = 0; i < 16; i++) {
3915		len += sprintf (info->data + len, "%7d ",
3916                                dasd_global_profile.dasd_io_time1[i] >> shift);
3917	}
3918	len += sprintf (info->data + len, "\n");
3919	for (; i < 32; i++) {
3920		len += sprintf (info->data + len, "%7d ",
3921                                dasd_global_profile.dasd_io_time1[i] >> shift);
3922	}
3923	len += sprintf (info->data + len, "\n");
3924
3925	len += sprintf (info->data + len,
3926                        "Histogram of I/O time between ssch and irq\n");
3927	for (i = 0; i < 16; i++) {
3928		len += sprintf (info->data + len, "%7d ",
3929                                dasd_global_profile.dasd_io_time2[i] >> shift);
3930	}
3931	len += sprintf (info->data + len, "\n");
3932	for (; i < 32; i++) {
3933		len += sprintf (info->data + len, "%7d ",
3934                                dasd_global_profile.dasd_io_time2[i] >> shift);
3935	}
3936	len += sprintf (info->data + len, "\n");
3937
3938	len += sprintf (info->data + len,
3939                        "Histogram of I/O time between ssch and irq per sector\n");
3940	for (i = 0; i < 16; i++) {
3941		len += sprintf (info->data + len, "%7d ",
3942                                dasd_global_profile.dasd_io_time2ps[i] >> shift);
3943	}
3944	len += sprintf (info->data + len, "\n");
3945	for (; i < 32; i++) {
3946		len += sprintf (info->data + len, "%7d ",
3947                                dasd_global_profile.dasd_io_time2ps[i] >> shift);
3948	}
3949	len += sprintf (info->data + len, "\n");
3950
3951	len += sprintf (info->data + len,
3952                        "Histogram of I/O time between irq and end\n");
3953	for (i = 0; i < 16; i++) {
3954		len +=
3955		    sprintf (info->data + len, "%7d ",
3956			     dasd_global_profile.dasd_io_time3[i] >> shift);
3957	}
3958	len += sprintf (info->data + len, "\n");
3959	for (; i < 32; i++) {
3960		len += sprintf (info->data + len, "%7d ",
3961                                dasd_global_profile.dasd_io_time3[i] >> shift);
3962	}
3963	len += sprintf (info->data + len, "\n");
3964
3965	len += sprintf (info->data + len,
3966                        "# of req in chanq at enqueuing (1..32) \n");
3967	for (i = 0; i < 16; i++) {
3968		len += sprintf (info->data + len, "%7d ",
3969                                dasd_global_profile.dasd_io_nr_req[i] >> shift);
3970	}
3971	len += sprintf (info->data + len, "\n");
3972	for (; i < 32; i++) {
3973		len += sprintf (info->data + len, "%7d ",
3974                                dasd_global_profile.dasd_io_nr_req[i] >> shift);
3975	}
3976	len += sprintf (info->data + len, "\n");
3977
3978	info->len = len;
3979	return rc;
3980}
3981
3982static ssize_t
3983dasd_statistics_write (struct file *file, const char *user_buf,
3984		       size_t user_len, loff_t * offset)
3985{
3986	char *buffer;
3987
3988	if(user_len > 65536)
3989		user_len = 65536;
3990
3991	buffer = vmalloc (user_len);
3992
3993	if (buffer == NULL)
3994		return -ENOMEM;
3995	if (copy_from_user (buffer, user_buf, user_len)) {
3996		vfree (buffer);
3997		return -EFAULT;
3998	}
3999	buffer[user_len] = 0;
4000	printk (KERN_INFO PRINTK_HEADER "/proc/dasd/statictics: '%s'\n",
4001		buffer);
4002	if (strncmp (buffer, "reset", 4)) {
4003		memset (&dasd_global_profile, 0, sizeof (dasd_profile_info_t));
4004	}
4005	return user_len;
4006}
4007
4008static struct file_operations dasd_statistics_file_ops = {
4009	read:dasd_generic_read,	/* read */
4010	open:dasd_statistics_open,	/* open */
4011	write:dasd_statistics_write,	/* write */
4012	release:dasd_devices_close,	/* close */
4013};
4014
4015static struct inode_operations dasd_statistics_inode_ops = {
4016};
4017
4018int
4019dasd_proc_init (void)
4020{
4021	int rc = 0;
4022	dasd_proc_root_entry = proc_mkdir ("dasd", &proc_root);
4023	dasd_devices_entry = create_proc_entry ("devices",
4024						S_IFREG | S_IRUGO | S_IWUSR,
4025						dasd_proc_root_entry);
4026	dasd_devices_entry->proc_fops = &dasd_devices_file_ops;
4027	dasd_devices_entry->proc_iops = &dasd_devices_inode_ops;
4028	dasd_statistics_entry = create_proc_entry ("statistics",
4029						   S_IFREG | S_IRUGO | S_IWUSR,
4030						   dasd_proc_root_entry);
4031	dasd_statistics_entry->proc_fops = &dasd_statistics_file_ops;
4032	dasd_statistics_entry->proc_iops = &dasd_statistics_inode_ops;
4033	return rc;
4034}
4035
4036void
4037dasd_proc_cleanup (void)
4038{
4039	remove_proc_entry ("devices", dasd_proc_root_entry);
4040	remove_proc_entry ("statistics", dasd_proc_root_entry);
4041	remove_proc_entry ("dasd", &proc_root);
4042}
4043
4044int
4045dasd_request_module ( void *name ) {
4046	int rc = -ERESTARTSYS;
4047    	strcpy(current->comm, name);
4048   	daemonize();
4049   	while ( current->fs->root == NULL ) { /* wait for root-FS */
4050        	DECLARE_WAIT_QUEUE_HEAD(wait);
4051        	sleep_on_timeout(&wait,HZ); /* wait in steps of one second */
4052	}
4053	while ( (rc=request_module(name)) != 0 ) {
4054        	DECLARE_WAIT_QUEUE_HEAD(wait);
4055		printk ( KERN_INFO "request_module returned %d for %s\n",
4056                         rc,
4057                         (char*)name);
4058        	sleep_on_timeout(&wait,5* HZ); /* wait in steps of 5 seconds */
4059    	}
4060    	return rc;
4061}
4062
4063
4064/* SECTION: Initializing the driver */
4065int __init
4066dasd_init (void)
4067{
4068	int rc = 0;
4069	int irq;
4070	major_info_t *major_info = NULL;
4071	struct list_head *l;
4072
4073	printk (KERN_INFO PRINTK_HEADER "initializing...\n");
4074	dasd_debug_area = debug_register (DASD_NAME, 0, 2, 5 * sizeof (long));
4075	debug_register_view (dasd_debug_area, &debug_sprintf_view);
4076	debug_register_view (dasd_debug_area, &debug_hex_ascii_view);
4077
4078	init_waitqueue_head (&dasd_init_waitq);
4079
4080	if (dasd_debug_area == NULL) {
4081		goto failed;
4082	}
4083	DASD_DRIVER_DEBUG_EVENT (0, dasd_init, "%s",
4084                                 "ENTRY");
4085	dasd_devfs_handle = devfs_mk_dir (NULL, DASD_NAME, NULL);
4086	if (dasd_devfs_handle < 0) {
4087		DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s",
4088                                         "no devfs");
4089		goto failed;
4090	}
4091	list_for_each (l, &dasd_major_info[0].list) {
4092		major_info = list_entry (l, major_info_t, list);
4093		if ((rc = dasd_register_major (major_info)) > 0) {
4094			DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
4095						 "major %d: success",
4096						 major_info->gendisk.major);
4097			printk (KERN_INFO PRINTK_HEADER
4098				"Registered successfully to major no %u\n",
4099				major_info->gendisk.major);
4100		} else {
4101			DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
4102						 "major %d: failed",
4103						 major_info->gendisk.major);
4104			printk (KERN_WARNING PRINTK_HEADER
4105				"Couldn't register successfully to major no %d\n",
4106				major_info->gendisk.major);
4107			/* revert registration of major infos */
4108			goto failed;
4109		}
4110	}
4111#ifndef MODULE
4112	dasd_split_parm_string (dasd_parm_string);
4113#endif				/* ! MODULE */
4114	rc = dasd_parse (dasd);
4115	if (rc) {
4116		DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s",
4117                                         "invalid range found");
4118		goto failed;
4119	}
4120
4121	rc = dasd_proc_init ();
4122	if (rc) {
4123		DASD_DRIVER_DEBUG_EVENT (1, dasd_init, "%s", "no proc-FS");
4124		goto failed;
4125	}
4126	genhd_dasd_name = dasd_device_name;
4127	genhd_dasd_ioctl = dasd_ioctl;
4128
4129	if (dasd_autodetect) {	/* update device range to all devices */
4130		for (irq = get_irq_first (); irq != -ENODEV;
4131		     irq = get_irq_next (irq)) {
4132			int devno = get_devno_by_irq (irq);
4133			int index = dasd_devindex_from_devno (devno);
4134			if (index == -ENODEV) {	/* not included in ranges */
4135				DASD_DRIVER_DEBUG_EVENT (2, dasd_init,
4136							 "add %04x to range",
4137							 devno);
4138				dasd_add_range (devno, devno, DASD_DEFAULT_FEATURES);
4139			}
4140		}
4141	}
4142
4143	if (MACHINE_IS_VM) {
4144#ifdef CONFIG_DASD_DIAG
4145		rc = dasd_diag_init ();
4146		if (rc == 0) {
4147			DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
4148						 "DIAG discipline %s",
4149						 "success");
4150			printk (KERN_INFO PRINTK_HEADER
4151				"Registered DIAG discipline successfully\n");
4152		} else {
4153			DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
4154						 "DIAG discipline %s",
4155						 "failed");
4156			goto failed;
4157		}
4158#endif /* CONFIG_DASD_DIAG */
4159#if defined(CONFIG_DASD_DIAG_MODULE) && defined(CONFIG_DASD_AUTO_DIAG)
4160                kernel_thread(dasd_request_module,"dasd_diag_mod",SIGCHLD);
4161#endif /* CONFIG_DASD_AUTO_DIAG */
4162	}
4163#ifdef CONFIG_DASD_ECKD
4164	rc = dasd_eckd_init ();
4165	if (rc == 0) {
4166		DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
4167					 "ECKD discipline %s", "success");
4168		printk (KERN_INFO PRINTK_HEADER
4169			"Registered ECKD discipline successfully\n");
4170	} else {
4171		DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
4172					 "ECKD discipline %s", "failed");
4173		goto failed;
4174	}
4175#endif /* CONFIG_DASD_ECKD */
4176#if defined(CONFIG_DASD_ECKD_MODULE) && defined(CONFIG_DASD_AUTO_ECKD)
4177        kernel_thread(dasd_request_module,"dasd_eckd_mod",SIGCHLD);
4178#endif /* CONFIG_DASD_AUTO_ECKD */
4179#ifdef CONFIG_DASD_FBA
4180	rc = dasd_fba_init ();
4181	if (rc == 0) {
4182		DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
4183					 "FBA discipline %s", "success");
4184
4185		printk (KERN_INFO PRINTK_HEADER
4186			"Registered FBA discipline successfully\n");
4187	} else {
4188		DASD_DRIVER_DEBUG_EVENT (1, dasd_init,
4189					 "FBA discipline %s", "failed");
4190		goto failed;
4191	}
4192#endif /* CONFIG_DASD_FBA */
4193#if defined(CONFIG_DASD_FBA_MODULE) && defined(CONFIG_DASD_AUTO_FBA)
4194        kernel_thread(dasd_request_module,"dasd_fba_mod",SIGCHLD);
4195#endif /* CONFIG_DASD_AUTO_FBA */
4196        {
4197                char **disc=dasd_disciplines;
4198                while (*disc) {
4199                        kernel_thread(dasd_request_module,*disc,SIGCHLD);
4200                        disc++;
4201                }
4202        }
4203
4204	rc = 0;
4205	goto out;
4206      failed:
4207	printk (KERN_INFO PRINTK_HEADER
4208		"initialization not performed due to errors\n");
4209	cleanup_dasd ();
4210      out:
4211	DASD_DRIVER_DEBUG_EVENT (0, dasd_init, "%s", "LEAVE");
4212	printk (KERN_INFO PRINTK_HEADER "initialization finished\n");
4213	return rc;
4214}
4215
4216static void
4217cleanup_dasd (void)
4218{
4219	int i,rc=0;
4220	major_info_t *major_info = NULL;
4221	struct list_head *l,*n;
4222	dasd_range_t *range;
4223
4224	printk (KERN_INFO PRINTK_HEADER "shutting down\n");
4225        DASD_DRIVER_DEBUG_EVENT(0,"cleanup_dasd","%s","ENTRY");
4226	dasd_disable_ranges (&dasd_range_head, NULL, 1, 1);
4227        if (MACHINE_IS_VM) {
4228#ifdef CONFIG_DASD_DIAG
4229                dasd_diag_cleanup ();
4230                DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd",
4231                                         "DIAG discipline %s", "success");
4232                printk (KERN_INFO PRINTK_HEADER
4233			"De-Registered DIAG discipline successfully\n");
4234#endif /* CONFIG_DASD_ECKD_BUILTIN */
4235	}
4236#ifdef CONFIG_DASD_FBA
4237	dasd_fba_cleanup ();
4238	DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd",
4239				 "FBA discipline %s", "success");
4240	printk (KERN_INFO PRINTK_HEADER
4241		"De-Registered FBA discipline successfully\n");
4242#endif /* CONFIG_DASD_ECKD_BUILTIN */
4243#ifdef CONFIG_DASD_ECKD
4244	dasd_eckd_cleanup ();
4245	DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd",
4246				 "ECKD discipline %s", "success");
4247	printk (KERN_INFO PRINTK_HEADER
4248		"De-Registered ECKD discipline successfully\n");
4249#endif /* CONFIG_DASD_ECKD_BUILTIN */
4250
4251	genhd_dasd_name = NULL;
4252	genhd_dasd_ioctl = NULL;
4253	dasd_proc_cleanup ();
4254
4255	list_for_each_safe (l, n, &dasd_major_info[0].list) {
4256		major_info = list_entry (l, major_info_t, list);
4257		for (i = 0; i < DASD_PER_MAJOR; i++) {
4258			kfree (major_info->dasd_device[i]);
4259		}
4260		if ((major_info->flags & DASD_MAJOR_INFO_REGISTERED) &&
4261		    (rc = dasd_unregister_major (major_info)) == 0) {
4262			DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd",
4263						 "major %d: success",
4264						 major_info->gendisk.major);
4265			printk (KERN_INFO PRINTK_HEADER
4266				"Unregistered successfully from major no %u\n",
4267				major_info->gendisk.major);
4268		} else {
4269			DASD_DRIVER_DEBUG_EVENT (1, "cleanup_dasd",
4270						 "major %d: failed",
4271						 major_info->gendisk.major);
4272			printk (KERN_WARNING PRINTK_HEADER
4273				"Couldn't unregister successfully from major no %d rc = %d\n",
4274				major_info->gendisk.major, rc);
4275  		}
4276  	}
4277	list_for_each_safe (l, n, &dasd_range_head.list) {
4278		range = list_entry (l, dasd_range_t, list);
4279                dasd_remove_range(range);
4280        }
4281
4282#ifndef MODULE
4283        for( i = 0; i < 256; i++ )
4284                if ( dasd[i] ) {
4285                        kfree(dasd[i]);
4286                        dasd[i] = NULL;
4287                }
4288#endif /* MODULE */
4289        if (dasd_devfs_handle)
4290                devfs_unregister(dasd_devfs_handle);
4291        if (dasd_debug_area != NULL )
4292                debug_unregister(dasd_debug_area);
4293	printk (KERN_INFO PRINTK_HEADER "shutdown completed\n");
4294        DASD_DRIVER_DEBUG_EVENT(0,"cleanup_dasd","%s","LEAVE");
4295}
4296
4297#ifdef MODULE
4298int
4299init_module (void)
4300{
4301	int rc = 0;
4302	rc = dasd_init ();
4303	return rc;
4304}
4305
4306void
4307cleanup_module (void)
4308{
4309	cleanup_dasd ();
4310	return;
4311}
4312#endif
4313
4314/*
4315 * Overrides for Emacs so that we follow Linus's tabbing style.
4316 * Emacs will notice this stuff at the end of the file and automatically
4317 * adjust the settings for this buffer only.  This must remain at the end
4318 * of the file.
4319 * ---------------------------------------------------------------------------
4320 * Local variables:
4321 * c-indent-level: 4
4322 * c-brace-imaginary-offset: 0
4323 * c-brace-offset: -4
4324 * c-argdecl-indent: 4
4325 * c-label-offset: -4
4326 * c-continued-statement-offset: 4
4327 * c-continued-brace-offset: 0
4328 * indent-tabs-mode: nil
4329 * tab-width: 8
4330 * End:
4331 */
4332