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 (®->devreg);
291 list_add (®->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(®->list);
324 s390_device_unregister (®->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 = ⦥
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