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