File: /usr/src/linux/drivers/s390/block/dasd.c

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