dasd.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:131k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  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. #include <linux/config.h>
  38. #include <linux/version.h>
  39. #include <linux/kmod.h>
  40. #include <linux/init.h>
  41. #include <linux/blkdev.h>
  42. #include <linux/stddef.h>
  43. #include <linux/kernel.h>
  44. #include <linux/tqueue.h>
  45. #include <linux/timer.h>
  46. #include <linux/slab.h>
  47. #include <linux/genhd.h>
  48. #include <linux/hdreg.h>
  49. #include <linux/interrupt.h>
  50. #include <linux/ctype.h>
  51. #ifdef CONFIG_PROC_FS
  52. #include <linux/proc_fs.h>
  53. #endif /* CONFIG_PROC_FS */
  54. #include <linux/spinlock.h>
  55. #include <linux/devfs_fs_kernel.h>
  56. #include <linux/blkpg.h>
  57. #include <linux/wait.h>
  58. #include <asm/ccwcache.h>
  59. #include <asm/debug.h>
  60. #include <asm/atomic.h>
  61. #include <asm/delay.h>
  62. #include <asm/io.h>
  63. #include <asm/semaphore.h>
  64. #include <asm/ebcdic.h>
  65. #include <asm/uaccess.h>
  66. #include <asm/irq.h>
  67. #include <asm/s390_ext.h>
  68. #include <asm/s390dyn.h>
  69. #include <asm/idals.h>
  70. #include <asm/dasd.h>
  71. #include "dasd_int.h"
  72. #ifdef CONFIG_DASD_ECKD
  73. #include "dasd_eckd.h"
  74. #endif /*  CONFIG_DASD_ECKD */
  75. #ifdef CONFIG_DASD_FBA
  76. #include "dasd_fba.h"
  77. #endif /*  CONFIG_DASD_FBA */
  78. #ifdef CONFIG_DASD_DIAG
  79. #include "dasd_diag.h"
  80. #endif /*  CONFIG_DASD_DIAG */
  81. /* SECTION: exported variables of dasd.c */
  82. debug_info_t *dasd_debug_area;
  83. MODULE_AUTHOR ("Holger Smolinski <Holger.Smolinski@de.ibm.com>");
  84. MODULE_DESCRIPTION ("Linux on S/390 DASD device driver,"
  85.     " Copyright 2000 IBM Corporation");
  86. MODULE_SUPPORTED_DEVICE ("dasd");
  87. MODULE_PARM (dasd, "1-" __MODULE_STRING (256) "s");
  88. MODULE_PARM (dasd_disciplines, "1-" __MODULE_STRING (8) "s");
  89. EXPORT_SYMBOL (dasd_chanq_enq_head);
  90. EXPORT_SYMBOL (dasd_debug_area);
  91. EXPORT_SYMBOL (dasd_chanq_enq);
  92. EXPORT_SYMBOL (dasd_chanq_deq);
  93. EXPORT_SYMBOL (dasd_discipline_add);
  94. EXPORT_SYMBOL (dasd_discipline_del);
  95. EXPORT_SYMBOL (dasd_start_IO);
  96. EXPORT_SYMBOL (dasd_term_IO);
  97. EXPORT_SYMBOL (dasd_schedule_bh);
  98. EXPORT_SYMBOL (dasd_int_handler);
  99. EXPORT_SYMBOL (dasd_oper_handler);
  100. EXPORT_SYMBOL (dasd_alloc_request);
  101. EXPORT_SYMBOL (dasd_free_request);
  102. EXPORT_SYMBOL (dasd_ioctl_no_register);
  103. EXPORT_SYMBOL (dasd_ioctl_no_unregister);
  104. EXPORT_SYMBOL (dasd_default_erp_action);
  105. EXPORT_SYMBOL (dasd_default_erp_postaction);
  106. EXPORT_SYMBOL (dasd_sleep_on_req);
  107. EXPORT_SYMBOL (dasd_set_normalized_cda);
  108. EXPORT_SYMBOL (dasd_device_from_kdev);
  109. /* SECTION: Constant definitions to be used within this file */
  110. #define PRINTK_HEADER DASD_NAME":"
  111. #undef  DASD_PROFILE            /* fill profile information - used for */
  112.                                 /* statistics and perfomance           */
  113. #define DASD_MIN_SIZE_FOR_QUEUE 32
  114. #undef CONFIG_DYNAMIC_QUEUE_MIN_SIZE
  115. #define DASD_CHANQ_MAX_SIZE 6
  116. /* SECTION: prototypes for static functions of dasd.c */
  117. static request_fn_proc do_dasd_request;
  118. static int dasd_set_device_level (unsigned int, dasd_discipline_t *, int);
  119. static request_queue_t *dasd_get_queue (kdev_t kdev);
  120. static void cleanup_dasd (void);
  121. static void dasd_plug_device (dasd_device_t * device);
  122. static int dasd_fillgeo (int kdev, struct hd_geometry *geo);
  123. static void dasd_enable_ranges (dasd_range_t *, dasd_discipline_t *, int); 
  124. static void dasd_disable_ranges (dasd_range_t *, dasd_discipline_t *, int, int); 
  125. static void dasd_enable_single_device ( unsigned long);
  126. static inline int dasd_state_init_to_ready(dasd_device_t*);
  127. static inline void dasd_setup_partitions ( dasd_device_t *);
  128. static inline void dasd_destroy_partitions ( dasd_device_t *);
  129. static inline int dasd_setup_blkdev(dasd_device_t*);
  130. static void dasd_deactivate_queue (dasd_device_t *);
  131. static inline int dasd_disable_blkdev(dasd_device_t*);
  132. static void dasd_flush_chanq ( dasd_device_t * device, int destroy ); 
  133. static void dasd_flush_request_queues ( dasd_device_t * device, int destroy );
  134. static struct block_device_operations dasd_device_operations;
  135. static inline dasd_device_t ** dasd_device_from_devno (int);
  136. static void dasd_process_queues (dasd_device_t * device);
  137. /* SECTION: static variables of dasd.c */
  138. static devfs_handle_t dasd_devfs_handle;
  139. static wait_queue_head_t dasd_init_waitq;
  140. static atomic_t dasd_init_pending = ATOMIC_INIT (0);
  141. #ifdef CONFIG_DASD_DYNAMIC
  142. /* SECTION: managing dynamic configuration of dasd_driver */
  143. static struct list_head dasd_devreg_head = LIST_HEAD_INIT (dasd_devreg_head);
  144. /*
  145.  * function: dasd_create_devreg
  146.  * creates a dasd_devreg_t related to a devno
  147.  */
  148. static inline dasd_devreg_t *
  149. dasd_create_devreg (int devno)
  150. {
  151. dasd_devreg_t *r = kmalloc (sizeof (dasd_devreg_t), GFP_KERNEL);
  152. if (r != NULL) {
  153. memset (r, 0, sizeof (dasd_devreg_t));
  154. r->devreg.ci.devno = devno;
  155. r->devreg.flag = DEVREG_TYPE_DEVNO;
  156. r->devreg.oper_func = dasd_oper_handler;
  157. }
  158. return r;
  159. }
  160. /*
  161.  * function: dasd_destroy_devreg
  162.  * destroys the dasd_devreg_t given as argument
  163.  */
  164. static inline void
  165. dasd_destroy_devreg (dasd_devreg_t * devreg)
  166. {
  167. kfree (devreg);
  168. }
  169. #endif /* CONFIG_DASD_DYNAMIC */
  170. /* SECTION: managing setup of dasd_driver */
  171. /* default setting is probeonly, autodetect */
  172. static int dasd_probeonly = 1; /* is true, when probeonly mode is active */
  173. static int dasd_autodetect = 1; /* is true, when autodetection is active */
  174. static dasd_range_t dasd_range_head =
  175.     { list:LIST_HEAD_INIT (dasd_range_head.list) };
  176. static spinlock_t range_lock = SPIN_LOCK_UNLOCKED;
  177. /*
  178.  * function: dasd_create_range
  179.  * creates a dasd_range_t according to the arguments
  180.  * FIXME: no check is performed for reoccurrence of a devno
  181.  */
  182. static inline dasd_range_t *
  183. dasd_create_range (int from, int to, int features)
  184. {
  185. dasd_range_t *range = NULL;
  186.         int i;
  187. if ( from > to ) {
  188.                 printk (KERN_WARNING PRINTK_HEADER 
  189.                         "Adding device range %04x-%04x: range invalid, ignoring.n",
  190.                         from,
  191.                         to);
  192. return NULL;
  193. }
  194. for (i=from;i<=to;i++) {
  195.                 if (dasd_device_from_devno(i)) {
  196.                         printk (KERN_WARNING PRINTK_HEADER 
  197.                                 "device range %04x-%04x: device %04x is already in a range.n",
  198.                                 from,
  199.                                 to,
  200.                                 i);
  201.                 }
  202.         }
  203. range = (dasd_range_t *) kmalloc (sizeof (dasd_range_t), GFP_KERNEL);
  204. if (range == NULL)
  205. return NULL;
  206. memset (range, 0, sizeof (dasd_range_t));
  207. range->from = from;
  208.         range->to = to;
  209.         range->features = features;
  210. return range;
  211. }
  212. /*
  213.  * function dasd_destroy_range
  214.  * destroy a range allocated wit dasd_crate_range
  215.  * CAUTION: must not be callen in arunning sysztem, because it destroys
  216.  * the mapping of DASDs
  217.  */
  218. static inline void
  219. dasd_destroy_range (dasd_range_t * range)
  220. {
  221. kfree (range);
  222. }
  223. /*
  224.  * function: dasd_append_range
  225.  * appends the range given as argument to the list anchored at dasd_range_head.
  226.  */
  227. static inline void
  228. dasd_append_range (dasd_range_t * range)
  229. {
  230. long flags;
  231. spin_lock_irqsave (&range_lock, flags);
  232. list_add_tail (&range->list, &dasd_range_head.list);
  233. spin_unlock_irqrestore (&range_lock, flags);
  234. }
  235. /*
  236.  * function dasd_dechain_range
  237.  * removes a range from the chain of ranges
  238.  * CAUTION: must not be called in a running system because it destroys
  239.  * the mapping of devices
  240.  */
  241. static inline void
  242. dasd_dechain_range (dasd_range_t * range)
  243. {
  244. unsigned long flags;
  245. spin_lock_irqsave (&range_lock, flags);
  246. list_del (&range->list);
  247. spin_unlock_irqrestore (&range_lock, flags);
  248. }
  249. /*
  250.  * function: dasd_add_range
  251.  * creates a dasd_range_t according to the arguments and
  252.  * appends it to the list of ranges
  253.  * additionally a devreg_t is created and added to the list of devregs
  254.  */
  255. static inline dasd_range_t *
  256. dasd_add_range (int from, int to, int features)
  257. {
  258. dasd_range_t *range;
  259. range = dasd_create_range (from, to, features);
  260. if (!range)
  261. return NULL;
  262. dasd_append_range (range);
  263. #ifdef CONFIG_DASD_DYNAMIC
  264. /* allocate and chain devreg infos for the devnos... */
  265. {
  266. int i;
  267. for (i = range->from; i <= range->to; i++) {
  268. dasd_devreg_t *reg = dasd_create_devreg (i);
  269. s390_device_register (&reg->devreg);
  270. list_add (&reg->list, &dasd_devreg_head);
  271. }
  272. }
  273. #endif /* CONFIG_DASD_DYNAMIC */
  274. return range;
  275. }
  276. /*
  277.  * function: dasd_remove_range
  278.  * removes a range and the corresponding devregs from all of the chains
  279.  * CAUTION: must not be called in a running system because it destroys
  280.  * the mapping of devices!
  281.  */
  282. static inline void
  283. dasd_remove_range (dasd_range_t * range)
  284. {
  285. #ifdef CONFIG_DASD_DYNAMIC
  286. /* deallocate and dechain devreg infos for the devnos... */
  287. {
  288. int i;
  289. for (i = range->from; i <= range->to; i++) {
  290. struct list_head *l;
  291. dasd_devreg_t *reg = NULL;
  292. list_for_each (l, &dasd_devreg_head) {
  293. reg = list_entry (l, dasd_devreg_t, list);
  294. if (reg->devreg.flag == DEVREG_TYPE_DEVNO &&
  295.     reg->devreg.ci.devno == i &&
  296.     reg->devreg.oper_func == dasd_oper_handler)
  297. break;
  298. }
  299. if (l == &dasd_devreg_head)
  300. BUG ();
  301.                         list_del(&reg->list);
  302. s390_device_unregister (&reg->devreg);
  303. dasd_destroy_devreg (reg);
  304. }
  305. }
  306. #endif /* CONFIG_DASD_DYNAMIC */
  307. dasd_dechain_range (range);
  308. dasd_destroy_range (range);
  309. }
  310. /* 
  311.  * function: dasd_devindex_from_devno
  312.  * finds the logical number of the devno supplied as argument in the list
  313.  * of dasd ranges and returns it or ENODEV when not found
  314.  */
  315. static int
  316. dasd_devindex_from_devno (int devno)
  317. {
  318. dasd_range_t *temp;
  319. int devindex = 0;
  320. unsigned long flags;
  321. struct list_head *l;
  322. spin_lock_irqsave (&range_lock, flags);
  323. list_for_each (l, &dasd_range_head.list) {
  324. temp = list_entry (l, dasd_range_t, list);
  325. if (devno >= temp->from && devno <= temp->to) {
  326. spin_unlock_irqrestore (&range_lock, flags);
  327. return devindex + devno - temp->from;
  328. }
  329. devindex += temp->to - temp->from + 1;
  330. }
  331. spin_unlock_irqrestore (&range_lock, flags);
  332. return -ENODEV;
  333. }
  334. /*
  335.  * function: dasd_devno_from_devindex
  336.  */
  337. static int
  338. dasd_devno_from_devindex (int devindex)
  339. {
  340. dasd_range_t *temp;
  341. unsigned long flags;
  342. struct list_head *l;
  343. spin_lock_irqsave (&range_lock, flags);
  344. list_for_each (l, &dasd_range_head.list) {
  345. temp = list_entry (l, dasd_range_t, list);
  346.                 if ( devindex < temp->to - temp->from + 1) {
  347. spin_unlock_irqrestore (&range_lock, flags);
  348. return temp->from + devindex;
  349. }
  350. devindex -= temp->to - temp->from + 1;
  351. }
  352. spin_unlock_irqrestore (&range_lock, flags);
  353. return -ENODEV;
  354. }
  355. /* SECTION: parsing the dasd= parameter of the parmline/insmod cmdline */
  356. /*
  357.  * char *dasd[] is intended to hold the ranges supplied by the dasd= statement
  358.  * it is named 'dasd' to directly be filled by insmod with the comma separated
  359.  * strings when running as a module.
  360.  * a maximum of 256 ranges can be supplied, as the parmline is limited to
  361.  * <1024 Byte anyway.
  362.  */
  363. char *dasd[256];
  364. char *dasd_disciplines[8];
  365. #ifndef MODULE
  366. /*
  367.  * function: dasd_split_parm_string
  368.  * splits the parmline given to the kernel into comma separated strings
  369.  * which are filled into the 'dasd[]' array, to be parsed later on
  370.  */
  371. static void
  372. dasd_split_parm_string (char *str)
  373. {
  374. char *tmp = str;
  375. int count = 0;
  376. while (tmp != NULL && *tmp != '') {
  377. char *end;
  378. int len;
  379. end = strchr (tmp, ',');
  380. if (end == NULL) {
  381. len = strlen (tmp) + 1;
  382. } else {
  383. len = (long) end - (long) tmp + 1;
  384. *end = '';
  385. end++;
  386. }
  387. dasd[count] = kmalloc (len * sizeof (char), GFP_ATOMIC);
  388. if (dasd[count] == NULL) {
  389. printk (KERN_WARNING PRINTK_HEADER
  390. "can't store dasd= parameter no %dn",
  391. count + 1);
  392. break;
  393. }
  394. memset (dasd[count], 0, len * sizeof (char));
  395. memcpy (dasd[count], tmp, len * sizeof (char));
  396. count++;
  397. tmp = end;
  398. };
  399. }
  400. /*
  401.  * dasd_parm_string holds a concatenated version of all 'dasd=' parameters
  402.  * supplied in the parmline, which is later to be split by
  403.  * dasd_split_parm_string
  404.  * FIXME: why first concatenate then split ?
  405.  */
  406. static char dasd_parm_string[1024] __initdata = { 0, };
  407. /*
  408.  * function: dasd_setup
  409.  * is invoked for any single 'dasd=' parameter supplied in the parmline
  410.  * it merges all the arguments into dasd_parm_string
  411.  */
  412. void __init
  413. dasd_setup (char *str, int *ints)
  414. {
  415. int len = strlen (dasd_parm_string);
  416. if (len != 0) {
  417. strcat (dasd_parm_string, ",");
  418. }
  419. strcat (dasd_parm_string, str);
  420. }
  421. /*
  422.  * function: dasd_call_setup
  423.  * is the 2.4 version of dasd_setup and
  424.  * is invoked for any single 'dasd=' parameter supplied in the parmline
  425.  */
  426. int __init
  427. dasd_call_setup (char *str)
  428. {
  429. int dummy;
  430. dasd_setup (str, &dummy);
  431. return 1;
  432. }
  433. int __init
  434. dasd_disciplines_setup (char *str)
  435. {
  436. return 1;
  437. }
  438. __setup ("dasd=", dasd_call_setup);
  439. __setup ("dasd_disciplines=", dasd_disciplines_setup);
  440. #endif /* MODULE */
  441. /*
  442.  * function: dasd_strtoul
  443.  * provides a wrapper to simple_strtoul to strip leading '0x' and
  444.  * interpret any argument to dasd=[range,...] as hexadecimal
  445.  */
  446. static inline int
  447. dasd_strtoul (char *str, char **stra, int* features)
  448. {
  449.         char *temp=str;
  450.         char *buffer;
  451.         int val,i,start;
  452.         buffer=(char*)kmalloc((strlen(str)+1)*sizeof(char),GFP_ATOMIC);
  453.         if (buffer==NULL) {
  454.             printk (KERN_WARNING PRINTK_HEADER
  455.                     "can't parse dasd= parameter %s due to low memoryn",
  456.                     str);
  457.         }
  458.         /* remove leading '0x' */
  459.         if (*temp == '0') {
  460.                 temp++;         /* strip leading zero */
  461.                 if (*temp == 'x')
  462.                         temp++; /* strip leading x */
  463.         }
  464.         /* copy device no to buffer and convert to decimal */
  465.         for (i=0; temp[i]!='' && temp[i]!='(' && 
  466.                   temp[i]!='-'  && temp[i]!=' '; i++){
  467.                 if (isxdigit(temp[i])) {
  468.                         buffer[i]=temp[i];
  469.                 } else {
  470.                         return -EINVAL;
  471.                 }
  472.         }
  473.         buffer[i]='';
  474.         val = simple_strtoul (buffer, &buffer, 16);
  475.         /* check for features - e.g. (ro) ; the '', ')' and '-' stops check */
  476.         *features = DASD_DEFAULT_FEATURES;
  477.         if (temp[i]=='(') {
  478.                 while (temp[i]!='' && temp[i]!=')'&&temp[i]!='-') { 
  479.                         start=++i;      
  480.         
  481.                         /* move next feature to buffer */
  482.                         for (;temp[i]!=''&&temp[i]!=':'&&temp[i]!=')'&&temp[i]!='-';i++)
  483.                                 buffer[i-start]=temp[i];
  484.                         buffer[i-start]='';
  485.                         if (strlen(buffer)) { 
  486.                                 if (!strcmp(buffer,"ro")) { /* handle 'ro' feature */
  487.                                         (*features) |= DASD_FEATURE_READONLY;
  488.                                         break;
  489.                                 }
  490.                                 printk (KERN_WARNING PRINTK_HEADER 
  491.                                         "unsupported feature: %s, ignoring setting",
  492.                                         buffer);
  493.                         }
  494.                 }
  495.         }
  496.         *stra = temp+i;
  497.         return val;
  498. }
  499. /*
  500.  * function: dasd_parse
  501.  * examines the strings given in the string array str and
  502.  * creates and adds the ranges to the apropriate lists
  503.  */
  504. static int
  505. dasd_parse (char **str)
  506. {
  507. char *temp;
  508. int from, to;
  509.         int features;
  510.         int rc = 0;
  511. if (*str) {
  512. /* turn off probeonly mode, if any dasd parameter is present */
  513. dasd_probeonly = 0;
  514. dasd_autodetect = 0;
  515. }
  516. while (*str) {
  517. temp = *str;
  518. from = 0;
  519. to = 0;
  520. if (strcmp ("autodetect", *str) == 0) {
  521. dasd_autodetect = 1;
  522. printk (KERN_INFO "turning to autodetection moden");
  523. break;
  524. } else if (strcmp ("probeonly", *str) == 0) {
  525. dasd_probeonly = 1;
  526. printk (KERN_INFO "turning to probeonly moden");
  527. break;
  528. } else {
  529. /* turn off autodetect mode, if any range is present */
  530. dasd_autodetect = 0;
  531. from = dasd_strtoul (temp, &temp, &features);
  532.                         to = from;
  533. if (*temp == '-') {
  534. temp++;
  535. to = dasd_strtoul (temp, &temp, &features);
  536. }
  537.                         if (from == -EINVAL ||
  538.                             to   == -EINVAL    ) {
  539.                                 rc = -EINVAL;
  540.                                 break;
  541.                         } else {
  542.                                 dasd_add_range (from, to ,features);
  543.                         }
  544.                 }
  545. str++;
  546. }
  547.         return rc;
  548. }
  549. /* SECTION: Dealing with devices registered to multiple major numbers */
  550. static spinlock_t dasd_major_lock = SPIN_LOCK_UNLOCKED;
  551. static major_info_t dasd_major_info[] = {
  552. {
  553.       list:LIST_HEAD_INIT (dasd_major_info[1].list)
  554.  },
  555. {
  556.       list:LIST_HEAD_INIT (dasd_major_info[0].list),
  557.       gendisk:{
  558.   INIT_GENDISK (94, DASD_NAME, DASD_PARTN_BITS, DASD_PER_MAJOR)
  559.   },
  560.       flags:DASD_MAJOR_INFO_IS_STATIC}
  561. };
  562. static major_info_t *
  563. get_new_major_info (void)
  564. {
  565. major_info_t *major_info = NULL;
  566. major_info = kmalloc (sizeof (major_info_t), GFP_KERNEL);
  567. if (major_info) {
  568. static major_info_t temp_major_info = {
  569. gendisk:{
  570.  INIT_GENDISK (0, DASD_NAME, DASD_PARTN_BITS,
  571.        DASD_PER_MAJOR)}
  572. };
  573. memcpy (major_info, &temp_major_info, sizeof (major_info_t));
  574. }
  575. return major_info;
  576. }
  577. /*
  578.  * register major number
  579.  * is called with the 'static' major_info during init of the driver or 'NULL' to
  580.  * allocate an additional dynamic major.
  581.  */
  582. static int
  583. dasd_register_major (major_info_t * major_info)
  584. {
  585. int rc = 0;
  586. int major;
  587. unsigned long flags;
  588.         /* allocate dynamic major */
  589. if (major_info == NULL) {
  590. major_info = get_new_major_info ();
  591. if (!major_info) {
  592. printk (KERN_WARNING PRINTK_HEADER
  593. "Cannot get memory to allocate another major numbern");
  594. return -ENOMEM;
  595. }
  596. }
  597. major = major_info->gendisk.major;
  598.         /* init devfs array */
  599. major_info->gendisk.de_arr = (devfs_handle_t *)
  600.     kmalloc (DASD_PER_MAJOR * sizeof (devfs_handle_t), GFP_KERNEL);
  601. if(major_info->gendisk.de_arr == NULL)
  602. goto out_gd_de_arr;
  603. memset (major_info->gendisk.de_arr, 0,
  604. DASD_PER_MAJOR * sizeof (devfs_handle_t));
  605.         /* init flags */
  606. major_info->gendisk.flags = (char *)
  607.     kmalloc (DASD_PER_MAJOR * sizeof (char), GFP_KERNEL);
  608. if(major_info->gendisk.flags == NULL)
  609. goto out_gd_flags;
  610. memset (major_info->gendisk.flags, 0, DASD_PER_MAJOR * sizeof (char));
  611.         /* register blockdevice */
  612. rc = devfs_register_blkdev (major, DASD_NAME, &dasd_device_operations);
  613. if (rc < 0) {
  614. printk (KERN_WARNING PRINTK_HEADER
  615. "Cannot register to major no %d, rc = %dn",
  616.                         major, 
  617.                         rc);
  618. goto out_reg_blkdev; 
  619. } else {
  620. major_info->flags |= DASD_MAJOR_INFO_REGISTERED;
  621. }
  622. /* Insert the new major info into dasd_major_info if needed (dynamic major) */
  623. if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {
  624. spin_lock_irqsave (&dasd_major_lock, flags);
  625. list_add_tail (&major_info->list, &dasd_major_info[0].list);
  626. spin_unlock_irqrestore (&dasd_major_lock, flags);
  627. }
  628. if (major == 0) {
  629. major = rc;
  630. rc = 0;
  631. }
  632.         /* init array of devices */
  633. major_info->dasd_device =
  634.     (dasd_device_t **) kmalloc (DASD_PER_MAJOR *
  635. sizeof (dasd_device_t *), GFP_ATOMIC);
  636. if (!major_info->dasd_device)
  637. goto out_devices;
  638. memset (major_info->dasd_device, 0,
  639. DASD_PER_MAJOR * sizeof (dasd_device_t *));
  640.         /* init blk_size */
  641. blk_size[major] =
  642.     (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);
  643. if (!blk_size[major])
  644. goto out_blk_size;
  645. memset (blk_size[major], 0, (1 << MINORBITS) * sizeof (int));
  646.         /* init blksize_size */
  647. blksize_size[major] =
  648.     (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);
  649. if (!blksize_size[major])
  650. goto out_blksize_size;
  651. memset (blksize_size[major], 0, (1 << MINORBITS) * sizeof (int));
  652.         /* init_hardsect_size */
  653. hardsect_size[major] =
  654.     (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);
  655. if (!hardsect_size[major])
  656. goto out_hardsect_size;
  657. memset (hardsect_size[major], 0, (1 << MINORBITS) * sizeof (int));
  658.         /* init max_sectors */
  659. max_sectors[major] =
  660.     (int *) kmalloc ((1 << MINORBITS) * sizeof (int), GFP_ATOMIC);
  661. if (!max_sectors[major])
  662. goto out_max_sectors;
  663. memset (max_sectors[major], 0, (1 << MINORBITS) * sizeof (int));
  664. /* finally do the gendisk stuff */
  665. major_info->gendisk.part = kmalloc ((1 << MINORBITS) *
  666.     sizeof (struct hd_struct),
  667.     GFP_ATOMIC);
  668. if (!major_info->gendisk.part)
  669. goto out_gendisk;
  670. memset (major_info->gendisk.part, 0, (1 << MINORBITS) *
  671. sizeof (struct hd_struct));
  672. INIT_BLK_DEV (major, do_dasd_request, dasd_get_queue, NULL);
  673. major_info->gendisk.sizes = blk_size[major];
  674. major_info->gendisk.major = major;
  675. add_gendisk (&major_info->gendisk);
  676. return major;
  677.         /* error handling - free the prior allocated memory */  
  678.       out_gendisk:
  679. kfree (max_sectors[major]);
  680. max_sectors[major] = NULL;
  681.       out_max_sectors:
  682. kfree (hardsect_size[major]);
  683. hardsect_size[major] = NULL;
  684.       out_hardsect_size:
  685. kfree (blksize_size[major]);
  686. blksize_size[major] = NULL;
  687.       out_blksize_size:
  688. kfree (blk_size[major]);
  689. blk_size[major] = NULL;
  690.       out_blk_size:
  691. kfree (major_info->dasd_device);
  692.       out_devices:
  693. /* Delete the new major info from dasd_major_info list if needed (dynamic) +*/
  694. if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {
  695. spin_lock_irqsave (&dasd_major_lock, flags);
  696. list_del (&major_info->list);
  697. spin_unlock_irqrestore (&dasd_major_lock, flags);
  698. }
  699.         /* unregister blockdevice */
  700. rc = devfs_unregister_blkdev (major, DASD_NAME);
  701. if (rc < 0) {
  702. printk (KERN_WARNING PRINTK_HEADER
  703. "Unable to unregister from major no %d, rc = %dn", 
  704.                         major,
  705. rc);
  706. } else {
  707. major_info->flags &= ~DASD_MAJOR_INFO_REGISTERED;
  708. }
  709. out_reg_blkdev:
  710. kfree (major_info->gendisk.flags);
  711. out_gd_flags:
  712. kfree (major_info->gendisk.de_arr);
  713. out_gd_de_arr:
  714. /* Delete the new major info from dasd_major_info if needed */
  715. if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {
  716. kfree (major_info);
  717. }
  718. return -ENOMEM;
  719. }
  720. static int
  721. dasd_unregister_major (major_info_t * major_info)
  722. {
  723. int rc = 0;
  724. int major;
  725. unsigned long flags;
  726. if (major_info == NULL) {
  727. return -EINVAL;
  728. }
  729. major = major_info->gendisk.major;
  730. INIT_BLK_DEV (major, NULL, NULL, NULL);
  731. del_gendisk (&major_info->gendisk);
  732. kfree (major_info->dasd_device);
  733. kfree (major_info->gendisk.part);
  734. kfree (blk_size[major]);
  735. kfree (blksize_size[major]);
  736. kfree (hardsect_size[major]);
  737. kfree (max_sectors[major]);
  738. blk_size[major]      = NULL;
  739. blksize_size[major]  = NULL;
  740. hardsect_size[major] = NULL;
  741. max_sectors[major]   = NULL;
  742. rc = devfs_unregister_blkdev (major, DASD_NAME);
  743. if (rc < 0) {
  744. printk (KERN_WARNING PRINTK_HEADER
  745. "Cannot unregister from major no %d, rc = %dn",
  746.                         major,
  747. rc);
  748. return rc;
  749. } else {
  750. major_info->flags &= ~DASD_MAJOR_INFO_REGISTERED;
  751. }
  752. kfree (major_info->gendisk.flags);
  753. kfree (major_info->gendisk.de_arr);
  754. /* Delete the new major info from dasd_major_info if needed */
  755. if (!(major_info->flags & DASD_MAJOR_INFO_IS_STATIC)) {
  756. spin_lock_irqsave (&dasd_major_lock, flags);
  757. list_del (&major_info->list);
  758. spin_unlock_irqrestore (&dasd_major_lock, flags);
  759. kfree (major_info);
  760. }
  761. return rc;
  762. }
  763. /*
  764.  * function: dasd_device_from_kdev
  765.  * finds the device structure corresponding to the kdev supplied as argument
  766.  * in the major_info structures and returns it or NULL when not found
  767.  */
  768. dasd_device_t *
  769. dasd_device_from_kdev (kdev_t kdev)
  770. {
  771. major_info_t *major_info = NULL;
  772. struct list_head *l;
  773. unsigned long flags;
  774. spin_lock_irqsave (&dasd_major_lock, flags);
  775. list_for_each (l, &dasd_major_info[0].list) {
  776. major_info = list_entry (l, major_info_t, list);
  777. if (major_info->gendisk.major == MAJOR (kdev))
  778. break;
  779. }
  780. spin_unlock_irqrestore (&dasd_major_lock, flags);
  781. if (major_info != &dasd_major_info[0])
  782. return major_info->dasd_device[MINOR (kdev) >> DASD_PARTN_BITS];
  783. return NULL;
  784. }
  785. /*
  786.  * function: dasd_device_from_devno
  787.  * finds the address of the device structure corresponding to the devno
  788.  * supplied as argument in the major_info structures and returns
  789.  * it or NULL when not found
  790.  */
  791. static inline dasd_device_t **
  792. dasd_device_from_devno (int devno)
  793. {
  794. major_info_t *major_info;
  795. struct list_head *l;
  796. int devindex = dasd_devindex_from_devno (devno);
  797. unsigned long flags;
  798. spin_lock_irqsave (&dasd_major_lock, flags);
  799. list_for_each (l, &dasd_major_info[0].list) {
  800. major_info = list_entry (l, major_info_t, list);
  801. if (devindex < DASD_PER_MAJOR) {
  802. spin_unlock_irqrestore (&dasd_major_lock, flags);
  803. return &major_info->dasd_device[devindex];
  804. }
  805. devindex -= DASD_PER_MAJOR;
  806. }
  807. spin_unlock_irqrestore (&dasd_major_lock, flags);
  808. return NULL;
  809. }
  810. /*
  811.  * function: dasd_features_from_devno
  812.  * finds the device range corresponding to the devno
  813.  * supplied as argument in the major_info structures and returns
  814.  * the features set for it
  815.  */
  816. static int
  817. dasd_features_from_devno (int devno)
  818. {
  819. dasd_range_t *temp;
  820. int devindex = 0;
  821. unsigned long flags;
  822. struct list_head *l;
  823. spin_lock_irqsave (&range_lock, flags);
  824. list_for_each (l, &dasd_range_head.list) {
  825. temp = list_entry (l, dasd_range_t, list);
  826. if (devno >= temp->from && devno <= temp->to) {
  827. spin_unlock_irqrestore (&range_lock, flags);
  828. return temp->features;
  829. }
  830. devindex += temp->to - temp->from + 1;
  831. }
  832. spin_unlock_irqrestore (&range_lock, flags);
  833. return -ENODEV;
  834. }
  835. /* SECTION: managing dasd disciplines */
  836. /* anchor and spinlock for list of disciplines */
  837. static struct list_head dasd_disc_head = LIST_HEAD_INIT(dasd_disc_head);
  838. static spinlock_t discipline_lock = SPIN_LOCK_UNLOCKED;
  839. /*
  840.  * function dasd_discipline_enq
  841.  * chains the discpline given as argument to the head of disiplines
  842.  * head chaining policy is required to allow module disciplines to
  843.  * be preferred against those, who are statically linked
  844.  */
  845. static inline void
  846. dasd_discipline_enq (dasd_discipline_t * d)
  847. {
  848.     list_add(&d->list, &dasd_disc_head);
  849. }
  850. /*
  851.  * function dasd_discipline_deq
  852.  * removes the discipline given as argument from the list of disciplines
  853.  */
  854. static inline void
  855. dasd_discipline_deq (dasd_discipline_t * d)
  856. {
  857.         list_del(&d->list);
  858. }
  859. void
  860. dasd_discipline_add (dasd_discipline_t * d)
  861. {
  862.         unsigned long flags;
  863.         MOD_INC_USE_COUNT;
  864. spin_lock_irqsave (&discipline_lock,flags);
  865.         dasd_discipline_enq (d);
  866. spin_unlock_irqrestore (&discipline_lock,flags);
  867.         dasd_enable_ranges (&dasd_range_head, d, DASD_STATE_ONLINE);
  868. }
  869. void dasd_discipline_del (dasd_discipline_t * d)
  870. {
  871.         unsigned long flags;
  872. spin_lock_irqsave (&discipline_lock,flags);
  873.         dasd_disable_ranges(&dasd_range_head, d, DASD_STATE_DEL, 1);
  874.         dasd_discipline_deq (d);
  875. spin_unlock_irqrestore (&discipline_lock,flags);
  876.         MOD_DEC_USE_COUNT;
  877. }
  878. static inline dasd_discipline_t *
  879. dasd_find_disc (dasd_device_t * device, dasd_discipline_t *d)
  880. {
  881.         dasd_discipline_t *t;
  882.         struct list_head *l = d ? &d->list : dasd_disc_head.next;
  883.         do {
  884.                 t = list_entry(l,dasd_discipline_t,list);
  885.                 if ( ( t->id_check == NULL ||
  886.                        t->id_check (&device->devinfo) == 0 ) &&
  887.                      ( t->check_characteristics == NULL ||
  888.                        t->check_characteristics (device) == 0 ) )
  889.                         break;
  890.                 l = l->next;
  891.                 if ( d || 
  892.                      l == &dasd_disc_head ) {
  893.                         t = NULL;
  894.                         break;
  895.                 }
  896.          } while ( 1 );
  897. return t;
  898. }
  899. /* SECTION: profiling stuff */
  900. static dasd_profile_info_t dasd_global_profile;
  901. #ifdef DASD_PROFILE
  902. /*
  903.  * macro: dasd_profile_add_counter
  904.  * increments counter in global and local profiling structures
  905.  * according to the value
  906.  */
  907. #define dasd_profile_add_counter( value, counter, device ) 
  908.         int ind; 
  909.         long help; 
  910. for (ind = 0, help = value >> 3; 
  911.              ind < 31 && help; 
  912.              help = help >> 1, ind++) {} 
  913. dasd_global_profile.counter[ind]++; 
  914.         device->profile.counter[ind]++; 
  915. }
  916. /*
  917.  * function dasd_profile_add
  918.  * adds the profiling information from the cqr given as argument to the
  919.  * global and device specific profiling information
  920.  */
  921. void
  922. dasd_profile_add (ccw_req_t * cqr)
  923. {
  924. long strtime, irqtime, endtime, tottime; /* in microsecnds*/
  925. long tottimeps, sectors;
  926. dasd_device_t *device = cqr->device;
  927. if (!cqr->req) /* safeguard against abnormal cqrs */
  928. return;
  929.         if ((!cqr->buildclk) ||
  930.             (!cqr->startclk) ||
  931.             (!cqr->stopclk ) ||
  932.             (!cqr->endclk  ) ||
  933.             (!(sectors = ((struct request *) (cqr->req))->nr_sectors)))
  934.                 return;
  935. strtime = ((cqr->startclk - cqr->buildclk) >> 12);
  936. irqtime = ((cqr->stopclk - cqr->startclk) >> 12);
  937. endtime = ((cqr->endclk - cqr->stopclk) >> 12);
  938. tottime = ((cqr->endclk - cqr->buildclk) >> 12);
  939. tottimeps = tottime / sectors;
  940. if (!dasd_global_profile.dasd_io_reqs) {
  941. memset (&dasd_global_profile, 0, sizeof (dasd_profile_info_t));
  942. };
  943. if (!device->profile.dasd_io_reqs) {
  944. memset (&device->profile, 0, sizeof (dasd_profile_info_t));
  945. };
  946. dasd_global_profile.dasd_io_reqs++;
  947. device->profile.dasd_io_reqs++;
  948. dasd_global_profile.dasd_io_sects+=sectors;
  949. device->profile.dasd_io_sects+=sectors;
  950. dasd_profile_add_counter (sectors, dasd_io_secs, device);
  951. dasd_profile_add_counter (tottime, dasd_io_times, device);
  952. dasd_profile_add_counter (tottimeps, dasd_io_timps, device);
  953. dasd_profile_add_counter (strtime, dasd_io_time1, device);
  954. dasd_profile_add_counter (irqtime, dasd_io_time2, device);
  955. dasd_profile_add_counter (irqtime / sectors, dasd_io_time2ps, device);
  956. dasd_profile_add_counter (endtime, dasd_io_time3, device);
  957. }
  958. #endif
  959. /* SECTION: All the gendisk stuff */
  960. /* SECTION: Managing wrappers for ccwcache */
  961. /*
  962.  * function dasd_alloc_request
  963.  * tries to return space for a channel program of length cplength with
  964.  * additional data of size datasize.
  965.  * If the ccwcache cannot fulfill the request it tries the emergeny requests
  966.  * before giving up finally
  967.  * FIXME: initialization of ccw_req_t should be done by function of ccwcache
  968.  */
  969. ccw_req_t *
  970. dasd_alloc_request (char *magic, int cplength, int datasize, dasd_device_t* device)
  971. {
  972. ccw_req_t *rv = NULL;
  973. if ((rv = ccw_alloc_request (magic, cplength, datasize)) != NULL) {
  974. return rv;
  975. }
  976. if ((((sizeof (ccw_req_t) + 7) & -8) +
  977.      cplength * sizeof (ccw1_t) + datasize) > PAGE_SIZE) {
  978. BUG ();
  979. }
  980.         if (device->lowmem_cqr==NULL) {
  981.                 DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request,
  982.                                          "(%04x) Low memory! Using emergency request %p.",
  983.                                          device->devinfo.devno,
  984.                                          device->lowmem_ccws);
  985.                 device->lowmem_cqr=device->lowmem_ccws;
  986.                 rv = device->lowmem_ccws;
  987. memset (rv, 0, PAGE_SIZE);
  988. strncpy ((char *) (&rv->magic), magic, 4);
  989. ASCEBC ((char *) (&rv->magic), 4);
  990. rv->cplength = cplength;
  991. rv->datasize = datasize;
  992. rv->data = (void *) ((long) rv + PAGE_SIZE - datasize);
  993. rv->cpaddr = (ccw1_t *) ((long) rv + sizeof (ccw_req_t));
  994.         } else {
  995.                 DASD_DRIVER_DEBUG_EVENT (2, dasd_alloc_request,
  996.                                          "(%04x) Refusing emergency mem for request "
  997.                                          "NULL, already in use at %p.",
  998.                                          device->devinfo.devno,
  999.                                          device->lowmem_ccws);
  1000. }
  1001. return rv;
  1002. }
  1003. /*
  1004.  * function dasd_free_request
  1005.  * returns a ccw_req_t to the appropriate cache or emergeny request line
  1006.  */
  1007. void
  1008. dasd_free_request (ccw_req_t * request, dasd_device_t* device)
  1009. {
  1010. #ifdef CONFIG_ARCH_S390X
  1011.         ccw1_t* ccw;
  1012.         /* clear any idals used for chain */
  1013.         ccw=request->cpaddr-1;
  1014.         do {
  1015.                 ccw++;
  1016.                 if ((ccw->cda < (unsigned long) device->lowmem_idals           ) || 
  1017.                     (ccw->cda >= (unsigned long) device->lowmem_idals+PAGE_SIZE)   )
  1018.                         clear_normalized_cda (ccw);
  1019.                 else {
  1020.                         if (device->lowmem_idal_ptr != device->lowmem_idals)
  1021.                                 DASD_MESSAGE (KERN_WARNING, device,
  1022.                                               "Freeing emergency idals from request at %p.",
  1023.                                               request);
  1024.                         device->lowmem_idal_ptr = device->lowmem_idals;
  1025.                         device->lowmem_cqr=NULL;
  1026.                 }
  1027.         } while ((ccw->flags & CCW_FLAG_CC) || 
  1028.                  (ccw->flags & CCW_FLAG_DC)   );
  1029. #endif
  1030.         if (request != device->lowmem_ccws) { 
  1031.                 /* compare to lowmem_ccws to protect usage of lowmem_cqr for IDAL only ! */
  1032. ccw_free_request (request);
  1033.         } else {
  1034.                 DASD_MESSAGE (KERN_WARNING, device,
  1035.                               "Freeing emergency request at %p",
  1036.                               request);
  1037.                 device->lowmem_cqr=NULL;
  1038. }
  1039. }
  1040. int
  1041. dasd_set_normalized_cda (ccw1_t * cp, unsigned long address, 
  1042.                          ccw_req_t* request, dasd_device_t* device )
  1043. {
  1044. #ifdef CONFIG_ARCH_S390X
  1045. int nridaws;
  1046.         int count = cp->count;
  1047.         
  1048.         if (set_normalized_cda (cp, address)!=-ENOMEM) {
  1049.                 return 0;
  1050.         }
  1051.         if ((device->lowmem_cqr!=NULL) && (device->lowmem_cqr!=request)) {
  1052.                 DASD_MESSAGE (KERN_WARNING, device, 
  1053.                               "Refusing emergency idals for request %p, memory"
  1054.                               " is already in use for request %p",
  1055.                               request,
  1056.                               device->lowmem_cqr);
  1057.                 return -ENOMEM;
  1058.         }
  1059.         device->lowmem_cqr=request;
  1060.         if (device->lowmem_idal_ptr == device->lowmem_idals) {
  1061.             DASD_MESSAGE (KERN_WARNING,device, 
  1062.                           "Low memory! Using emergency IDALs for request %p.n",
  1063.                           request);
  1064.         }
  1065.         nridaws = ((address & (IDA_BLOCK_SIZE-1)) + count + 
  1066.    (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG;
  1067. if ( device->lowmem_idal_ptr>=device->lowmem_idals + PAGE_SIZE ) {
  1068. /* Ouch! No Idals left for emergency request */
  1069. BUG();
  1070. }
  1071. cp->flags |= CCW_FLAG_IDA;
  1072. cp->cda = (__u32)(unsigned long)device->lowmem_idal_ptr;
  1073.         do {
  1074. *((long*)device->lowmem_idal_ptr) = address;
  1075. address = (address & -(IDA_BLOCK_SIZE)) + (IDA_BLOCK_SIZE);
  1076. nridaws --;
  1077.                 device->lowmem_idal_ptr += sizeof(unsigned long);
  1078.         } while ( nridaws > 0 );
  1079. #else 
  1080.         cp -> cda = address;
  1081. #endif
  1082. return 0;
  1083. }
  1084. /* SECTION: (de)queueing of requests to channel program queues */
  1085. /*
  1086.  * function dasd_chanq_enq
  1087.  * appends the cqr given as argument to the queue
  1088.  * has to be called with the queue lock (namely the s390_irq_lock) acquired
  1089.  */
  1090. inline void
  1091. dasd_chanq_enq (dasd_chanq_t * q, ccw_req_t * cqr)
  1092. {
  1093. if (q->head != NULL) {
  1094. q->tail->next = cqr;
  1095. } else
  1096. q->head = cqr;
  1097. cqr->next = NULL;
  1098. q->tail = cqr;
  1099. check_then_set (&cqr->status, 
  1100.                         CQR_STATUS_FILLED, 
  1101.                         CQR_STATUS_QUEUED);
  1102.        
  1103. #ifdef DASD_PROFILE
  1104.         /* save profile information for non erp cqr */
  1105.         if (cqr->refers == NULL) {
  1106.                 unsigned int  counter = 0;
  1107.                 ccw_req_t     *ptr;
  1108.                 dasd_device_t *device = cqr->device;
  1109.                 /* count the length of the chanq for statistics */
  1110.                 for (ptr = q->head; 
  1111.                      ptr->next != NULL && counter <=31; 
  1112.                      ptr = ptr->next) {
  1113.                         counter++;
  1114.                 }                
  1115.                 
  1116.                 dasd_global_profile.dasd_io_nr_req[counter]++;
  1117.                 device->profile.dasd_io_nr_req[counter]++;
  1118.         }
  1119. #endif 
  1120. }
  1121. /*
  1122.  * function dasd_chanq_enq_head
  1123.  * chains the cqr given as argument to the queue head
  1124.  * has to be called with the queue lock (namely the s390_irq_lock) acquired
  1125.  */
  1126. inline void
  1127. dasd_chanq_enq_head (dasd_chanq_t * q, ccw_req_t * cqr)
  1128. {
  1129. cqr->next = q->head;
  1130. q->head = cqr;
  1131. if (q->tail == NULL)
  1132. q->tail = cqr;
  1133. check_then_set (&cqr->status, CQR_STATUS_FILLED, CQR_STATUS_QUEUED);
  1134. }
  1135. /*
  1136.  * function dasd_chanq_deq
  1137.  * dechains the cqr given as argument from the queue
  1138.  * has to be called with the queue lock (namely the s390_irq_lock) acquired
  1139.  */
  1140. inline void
  1141. dasd_chanq_deq (dasd_chanq_t * q, ccw_req_t * cqr)
  1142. {
  1143. ccw_req_t *prev;
  1144. if (cqr == NULL)
  1145. BUG ();
  1146. if (cqr == q->head) {
  1147. q->head = cqr->next;
  1148. if (q->head == NULL)
  1149. q->tail = NULL;
  1150. } else {
  1151. prev = q->head;
  1152. while (prev && prev->next != cqr)
  1153. prev = prev->next;
  1154. if (prev == NULL)
  1155. return;
  1156. prev->next = cqr->next;
  1157. if (prev->next == NULL)
  1158. q->tail = prev;
  1159. }
  1160. cqr->next = NULL;
  1161. }
  1162. /* SECTION: Managing the device queues etc. */
  1163. /*
  1164.  * DASD_TERM_IO
  1165.  *
  1166.  * attempts to terminate the the current IO and set it to failed if termination
  1167.  * was successful.
  1168.  * returns an appropriate return code
  1169.  */
  1170. int
  1171. dasd_term_IO (ccw_req_t * cqr)
  1172. {
  1173. int rc = 0;
  1174. dasd_device_t *device = cqr->device;
  1175. int irq;
  1176.         int retries = 0;
  1177. if (!cqr) {
  1178. BUG ();
  1179. }
  1180. irq = device->devinfo.irq;
  1181. if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) {
  1182. DASD_MESSAGE (KERN_WARNING, device,
  1183.       " ccw_req_t 0x%08x magic doesn't match"
  1184.       " discipline 0x%08xn",
  1185.       cqr->magic,
  1186.       *(unsigned int *) device->discipline->name);
  1187. return -EINVAL;
  1188. }
  1189.         
  1190.         while ((retries < 5                    ) &&
  1191.                (cqr->status == CQR_STATUS_IN_IO)   ) {
  1192.                 if ( retries < 2 )
  1193.                         rc = halt_IO(irq, (long)cqr, 
  1194.                                      cqr->options | DOIO_WAIT_FOR_INTERRUPT);
  1195.                 else
  1196.                         rc = clear_IO(irq, (long)cqr, 
  1197.                                       cqr->options | DOIO_WAIT_FOR_INTERRUPT);
  1198.                 switch (rc) {
  1199.                 case 0:         /* termination successful */
  1200.                         check_then_set (&cqr->status,
  1201.                                         CQR_STATUS_IN_IO, 
  1202.                                         CQR_STATUS_FAILED);
  1203.                         
  1204.                         asm volatile ("STCK %0":"=m" (cqr->stopclk));
  1205.                         break;
  1206.                 case -ENODEV:
  1207.                         DASD_MESSAGE (KERN_WARNING, device, "%s",
  1208.                                       "device gone, retryn");
  1209.                         break;
  1210.                 case -EIO:
  1211.                         DASD_MESSAGE (KERN_WARNING, device, "%s",
  1212.                                       "I/O error, retryn");
  1213.                         break;
  1214.                 case -EBUSY:
  1215.                         DASD_MESSAGE (KERN_WARNING, device, "%s",
  1216.                                       "device busy, retry latern");
  1217.                         break;
  1218.                 default:
  1219.                         DASD_MESSAGE (KERN_ERR, device,
  1220.                                       "line %d unknown RC=%d, please report"
  1221.                                       " to linux390@de.ibm.comn", 
  1222.                                       __LINE__, 
  1223.                                       rc);
  1224.                         BUG ();
  1225.                         break;
  1226.                 }
  1227.                 retries ++;
  1228.         }
  1229. return rc;
  1230. }
  1231. /*
  1232.  * function dasd_start_IO
  1233.  * attempts to start the IO and returns an appropriate return code
  1234.  */
  1235. int
  1236. dasd_start_IO (ccw_req_t * cqr)
  1237. {
  1238. int rc = 0;
  1239. dasd_device_t *device = cqr->device;
  1240. int irq;
  1241. unsigned long long now;
  1242. if (!cqr) {
  1243. BUG ();
  1244. }
  1245. irq = device->devinfo.irq;
  1246. if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) {
  1247. DASD_MESSAGE (KERN_WARNING, device,
  1248.       " ccw_req_t 0x%08x magic doesn't match"
  1249.       " discipline 0x%08xn",
  1250.       cqr->magic,
  1251.       *(unsigned int *) device->discipline->name);
  1252. return -EINVAL;
  1253. }
  1254. asm volatile ("STCK %0":"=m" (now));
  1255.         cqr->startclk = now;
  1256. rc = do_IO (irq, cqr->cpaddr, (long) cqr, cqr->lpm, cqr->options);
  1257. switch (rc) {
  1258. case 0:
  1259.                 if (cqr->options & DOIO_WAIT_FOR_INTERRUPT) {
  1260.                         /* request already finished (synchronous IO) */
  1261.                         DASD_MESSAGE (KERN_ERR, device, "%s",
  1262.                                       " do_IO finished request... "
  1263.                                       "DOIO_WAIT_FOR_INTERRUPT was set");
  1264.                         check_then_set (&cqr->status,
  1265.                                         CQR_STATUS_QUEUED, 
  1266.                                         CQR_STATUS_DONE);
  1267.                         cqr->stopclk = now;
  1268.                         dasd_schedule_bh (device);
  1269.                         
  1270.                 } else {
  1271.                         check_then_set (&cqr->status,
  1272.                                         CQR_STATUS_QUEUED, 
  1273.                                         CQR_STATUS_IN_IO);
  1274.                 }
  1275. break;
  1276. case -EBUSY:
  1277. DASD_MESSAGE (KERN_WARNING, device, "%s",
  1278.       "device busy, retry latern");
  1279. break;
  1280. case -ETIMEDOUT: 
  1281. DASD_MESSAGE (KERN_WARNING, device, "%s",
  1282.       "request timeout - terminatedn");
  1283. case -ENODEV:
  1284. case -EIO:
  1285. check_then_set (&cqr->status,
  1286. CQR_STATUS_QUEUED, 
  1287.                                 CQR_STATUS_FAILED);
  1288.                 cqr->stopclk = now;
  1289.                 dasd_schedule_bh (device);
  1290. break;
  1291. default:
  1292. DASD_MESSAGE (KERN_ERR, device,
  1293.       "line %d unknown RC=%d, please report"
  1294.       " to linux390@de.ibm.comn", __LINE__, rc);
  1295. BUG ();
  1296. break;
  1297. }
  1298. return rc;
  1299. }
  1300. /*
  1301.  * function dasd_sleep_on_req
  1302.  * attempts to start the IO and waits for completion
  1303.  * FIXME: replace handmade sleeping by wait_event
  1304.  */
  1305. int
  1306. dasd_sleep_on_req (ccw_req_t * req)
  1307. {
  1308. unsigned long flags;
  1309. int cs;
  1310. int rc = 0;
  1311. dasd_device_t *device = (dasd_device_t *) req->device;
  1312.         if ( signal_pending(current) ) {
  1313.                 return -ERESTARTSYS;
  1314.         }
  1315. s390irq_spin_lock_irqsave (device->devinfo.irq, flags);
  1316. dasd_chanq_enq (&device->queue, req);
  1317. /* let the bh start the request to keep them in order */
  1318. dasd_schedule_bh (device);
  1319. do {
  1320. s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags);
  1321. wait_event ( device->wait_q,
  1322.      (((cs = req->status) == CQR_STATUS_DONE) ||
  1323.      (cs == CQR_STATUS_FAILED) ||
  1324.                              signal_pending(current)));
  1325. s390irq_spin_lock_irqsave (device->devinfo.irq, flags);
  1326.                 if ( signal_pending(current) ) {
  1327.                         rc = -ERESTARTSYS;
  1328.       if (req->status == CQR_STATUS_IN_IO ) 
  1329.                          device->discipline->term_IO(req);
  1330.                         break;
  1331.                 } else if ( req->status == CQR_STATUS_FAILED) {
  1332.                         rc = -EIO;
  1333.                         break;
  1334.                 }
  1335. } while (cs != CQR_STATUS_DONE && cs != CQR_STATUS_FAILED);
  1336. s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags);
  1337. return rc;
  1338. } /* end dasd_sleep_on_req */
  1339. /*
  1340.  * function dasd_end_request
  1341.  * posts the buffer_cache about a finalized request
  1342.  * FIXME: for requests splitted to serveral cqrs
  1343.  */
  1344. static inline void
  1345. dasd_end_request (struct request *req, int uptodate)
  1346. {
  1347. while (end_that_request_first (req, uptodate, DASD_NAME)) {
  1348. }
  1349. #ifndef DEVICE_NO_RANDOM
  1350. add_blkdev_randomness (MAJOR (req->rq_dev));
  1351. #endif
  1352. end_that_request_last (req);
  1353. return;
  1354. }
  1355. /*
  1356.  * function dasd_get_queue
  1357.  * returns the queue corresponding to a device behind a kdev
  1358.  */
  1359. static request_queue_t *
  1360. dasd_get_queue (kdev_t kdev)
  1361. {
  1362. dasd_device_t *device = dasd_device_from_kdev (kdev);
  1363. if (!device) {
  1364. return NULL;
  1365. }
  1366. return device->request_queue;
  1367. }
  1368. /*
  1369.  * function dasd_check_expire_time
  1370.  * check the request given as argument for expiration
  1371.  * and returns 0 if not yet expired, EIO else
  1372.  */
  1373. static inline int
  1374. dasd_check_expire_time (ccw_req_t * cqr)
  1375. {
  1376. unsigned long long now;
  1377. int rc = 0;
  1378. asm volatile ("STCK %0":"=m" (now));
  1379. if (cqr->expires && cqr->expires + cqr->startclk < now) {
  1380. DASD_MESSAGE (KERN_ERR, ((dasd_device_t *) cqr->device),
  1381.       "IO timeout 0x%08lx%08lx usecs in req %pn",
  1382.       (long) (cqr->expires >> 44),
  1383.       (long) (cqr->expires >> 12), cqr);
  1384. cqr->expires <<= 1;
  1385.                 rc = -EIO;
  1386. }
  1387. return rc;
  1388. }
  1389. /*
  1390.  * function dasd_finalize_request
  1391.  * implemets the actions to perform, when a request is finally finished
  1392.  * namely in status CQR_STATUS_DONE || CQR_STATUS_FAILED
  1393.  */
  1394. static inline void
  1395. dasd_finalize_request (ccw_req_t * cqr)
  1396. {
  1397. dasd_device_t *device = cqr->device;
  1398. asm volatile ("STCK %0":"=m" (cqr->endclk));
  1399. if (cqr->req) {
  1400. #ifdef DASD_PROFILE
  1401. dasd_profile_add (cqr);
  1402. #endif
  1403. dasd_end_request (cqr->req, (cqr->status == CQR_STATUS_DONE));
  1404. /* free request if nobody is waiting on it */
  1405. dasd_free_request (cqr, cqr->device);
  1406. } else {
  1407.                 if ( cqr == device->init_cqr && /* bring late devices online */
  1408.                      device->level <= DASD_STATE_ONLINE ) { 
  1409.                         device->timer.function = dasd_enable_single_device; 
  1410.                         device->timer.data     = (unsigned long) device;
  1411.                         device->timer.expires  = jiffies;
  1412.                         add_timer(&device->timer);
  1413.                 }
  1414. /* notify sleeping task about finished postprocessing */
  1415. wake_up (&device->wait_q);
  1416.                 
  1417. }
  1418. return;
  1419. }
  1420. /*
  1421.  * function dasd_process_queues
  1422.  * transfers the requests on the queue given as argument to the chanq
  1423.  * if possible, the request ist started on a fastpath
  1424.  */
  1425. static void
  1426. dasd_process_queues (dasd_device_t * device)
  1427. {
  1428. unsigned long flags;
  1429. struct request *req;
  1430. request_queue_t *queue = device->request_queue;
  1431. dasd_chanq_t *qp = &device->queue;
  1432. int irq = device->devinfo.irq;
  1433. ccw_req_t *final_requests = NULL;
  1434. static int chanq_min_size = DASD_MIN_SIZE_FOR_QUEUE;
  1435. int chanq_max_size = DASD_CHANQ_MAX_SIZE;
  1436. ccw_req_t *cqr = NULL, *temp;
  1437. dasd_erp_postaction_fn_t erp_postaction;
  1438. s390irq_spin_lock_irqsave (irq, flags);
  1439. /* First we dechain the requests, processed with completed status */
  1440. while (qp->head &&
  1441.        ((qp->head->status == CQR_STATUS_DONE  ) ||
  1442. (qp->head->status == CQR_STATUS_FAILED) ||
  1443. (qp->head->status == CQR_STATUS_ERROR )   )) {
  1444. dasd_erp_action_fn_t erp_action;
  1445. ccw_req_t            *erp_cqr = NULL;
  1446. /*  preprocess requests with CQR_STATUS_ERROR */
  1447. if (qp->head->status == CQR_STATUS_ERROR) {
  1448.                         qp->head->retries--; 
  1449. if (qp->head->dstat->flag & DEVSTAT_HALT_FUNCTION) {
  1450.                                 check_then_set (&qp->head->status,
  1451.                                                 CQR_STATUS_ERROR,
  1452.                                                 CQR_STATUS_FAILED);
  1453.                                 asm volatile ("STCK %0":"=m" (qp->head->stopclk));
  1454.                         } else if ((device->discipline->erp_action == NULL                          ) ||
  1455.                                    ((erp_action = device->discipline->erp_action (qp->head)) == NULL)   ) {
  1456.                                 
  1457. erp_cqr = dasd_default_erp_action (qp->head);
  1458. } else { /* call discipline ERP action */
  1459.                                 erp_cqr = erp_action (qp->head);
  1460.                         }
  1461.                         continue;
  1462. } else if (qp->head->refers) { /* we deal with a finished ERP */
  1463. if (qp->head->status == CQR_STATUS_DONE) {
  1464.                                 DASD_MESSAGE (KERN_DEBUG, device, "%s",
  1465.                                               "ERP successful");
  1466. } else {
  1467.                                 DASD_MESSAGE (KERN_ERR, device, "%s",
  1468.                                               "ERP unsuccessful");
  1469. }
  1470. if ((device->discipline->erp_postaction == NULL                              )||
  1471.     ((erp_postaction = device->discipline->erp_postaction (qp->head)) == NULL)  ) {
  1472.                                 dasd_default_erp_postaction (qp->head);
  1473. } else {  /* call ERP postaction of discipline */
  1474.                                 erp_postaction (qp->head);
  1475.                         }
  1476. continue;
  1477. }
  1478. /* dechain request now */
  1479. if (final_requests == NULL)
  1480. final_requests = qp->head;
  1481. cqr      = qp->head;
  1482. qp->head = qp->head->next;
  1483. if (qp->head == NULL)
  1484. qp->tail = NULL;
  1485. } /* end while over completed requests */
  1486. if (cqr)
  1487. cqr->next = NULL;
  1488. /* Now clean the requests with final status */
  1489. while (final_requests) { 
  1490. temp = final_requests;
  1491. final_requests = temp->next;
  1492. dasd_finalize_request (temp);
  1493. }
  1494. /* Now we try to fetch requests from the request queue */
  1495. for (temp = cqr; temp != NULL; temp = temp->next)
  1496. if (temp->status == CQR_STATUS_QUEUED)
  1497. chanq_max_size--;
  1498. while ((atomic_read(&device->plugged) == 0) &&
  1499.                (!queue->plugged) &&
  1500.        (!list_empty (&queue->queue_head)) &&
  1501.        (req = dasd_next_request (queue)) != NULL) {
  1502. /* queue empty or certain critera fulfilled -> transfer */
  1503. if (qp->head == NULL ||
  1504.     chanq_max_size > 0 || (req->nr_sectors >= chanq_min_size)) {
  1505. ccw_req_t *cqr = NULL;
  1506.                         if (is_read_only(device->kdev) && req->cmd == WRITE) {
  1507.                                 DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler,
  1508.                                                          "(%04x) Rejecting write request %pn",
  1509.                                                          device->devinfo.devno,
  1510.                                                          req);
  1511.                                 dasd_end_request (req, 0);
  1512.                                 dasd_dequeue_request (queue,req);
  1513.                         } else {
  1514.                             /* relocate request according to partition table */
  1515.                             req->sector +=
  1516.                                 device->major_info->gendisk.
  1517.                                 part[MINOR (req->rq_dev)].start_sect;
  1518.                             cqr = device->discipline->build_cp_from_req (device, req);
  1519.                             if (cqr == NULL) {
  1520.                                     DASD_DRIVER_DEBUG_EVENT (3, dasd_int_handler,
  1521.                                                              "(%04x) CCW creation failed "
  1522.                                                              "on request %pn",
  1523.                                                              device->devinfo.devno,
  1524.                                                              req);
  1525.                                     /* revert relocation of request */
  1526.                                     req->sector -=
  1527.                                         device->major_info->gendisk.
  1528.                                         part[MINOR (req->rq_dev)].start_sect;
  1529.                                     break; /* terminate request queue loop */
  1530.                                     
  1531.                             }
  1532. #ifdef CONFIG_DYNAMIC_QUEUE_MIN_SIZE
  1533.                             chanq_min_size =
  1534.                                 (chanq_min_size + req->nr_sectors) >> 1;
  1535. #endif /* CONFIG_DYNAMIC_QUEUE_MIN_SIZE */
  1536.                             dasd_dequeue_request (queue, req);
  1537.                             dasd_chanq_enq (qp, cqr);
  1538.                         }
  1539. } else { /* queue not empty OR criteria not met */
  1540. break; /* terminate request queue loop */
  1541. }
  1542. }
  1543. /* we process the requests with non-final status */
  1544. if (qp->head) {
  1545. switch (qp->head->status) {
  1546. case CQR_STATUS_QUEUED:
  1547. /* try to start the first I/O that can be started */
  1548. if (device->discipline->start_IO == NULL)
  1549. BUG ();
  1550.                         device->discipline->start_IO(qp->head);
  1551. break;
  1552. case CQR_STATUS_IN_IO:
  1553. /* Check, if to invoke the missing interrupt handler */
  1554. if (dasd_check_expire_time (qp->head)) {
  1555. /* to be filled with MIH */
  1556. }
  1557. break;
  1558. case CQR_STATUS_PENDING:
  1559. /* just wait */
  1560. break;
  1561. default:
  1562. BUG ();
  1563. }
  1564. }
  1565. s390irq_spin_unlock_irqrestore (irq, flags);
  1566. } /* end dasd_process_queues */
  1567. /*
  1568.  * function dasd_run_bh
  1569.  * acquires the locks needed and then runs the bh
  1570.  */
  1571. static void
  1572. dasd_run_bh (dasd_device_t * device)
  1573. {
  1574. long flags;
  1575. spin_lock_irqsave (&io_request_lock, flags);
  1576. atomic_set (&device->bh_scheduled, 0);
  1577. dasd_process_queues (device);
  1578. spin_unlock_irqrestore (&io_request_lock, flags);
  1579. }
  1580. /*
  1581.  * function dasd_schedule_bh
  1582.  * schedules the request_fn to run with next run_bh cycle
  1583.  */
  1584. void
  1585. dasd_schedule_bh (dasd_device_t * device)
  1586. {
  1587. /* Protect against rescheduling, when already running */
  1588. if (atomic_compare_and_swap (0, 1, &device->bh_scheduled)) {
  1589. return;
  1590. }
  1591. INIT_LIST_HEAD (&device->bh_tq.list);
  1592. device->bh_tq.sync = 0;
  1593. device->bh_tq.routine = (void *) (void *) dasd_run_bh;
  1594. device->bh_tq.data = device;
  1595. queue_task (&device->bh_tq, &tq_immediate);
  1596. mark_bh (IMMEDIATE_BH);
  1597. return;
  1598. }
  1599. /*
  1600.  * function do_dasd_request
  1601.  * is called from ll_rw_blk.c and provides the caller of
  1602.  * dasd_process_queues
  1603.  */
  1604. static void
  1605. do_dasd_request (request_queue_t * queue)
  1606. {
  1607.         dasd_device_t *device = (dasd_device_t *)queue->queuedata;
  1608. dasd_process_queues (device);
  1609. }
  1610. /*
  1611.  * DASD_HANDLE_STATE_CHANGE_PENDING
  1612.  *
  1613.  * DESCRIPTION
  1614.  *   Handles the state change pending interrupt.
  1615.  *   Search for the device related request queue and check if the first
  1616.  *   cqr in queue in in status 'CQR_STATUE_PENDING'.
  1617.  *   If so the status is set to 'CQR_STATUS_QUEUED' to reactivate
  1618.  *   the device.
  1619.  *
  1620.  *  PARAMETER
  1621.  *   stat               device status of state change pending interrupt.
  1622.  */
  1623. void
  1624. dasd_handle_state_change_pending (devstat_t * stat)
  1625. {
  1626. dasd_device_t **device_addr;
  1627. ccw_req_t *cqr;
  1628. device_addr = dasd_device_from_devno (stat->devno);
  1629. if (device_addr == NULL) {
  1630. printk (KERN_DEBUG PRINTK_HEADER
  1631. "unable to find device for state change pending "
  1632. "interrupt: devno%04xn", 
  1633.                         stat->devno);
  1634.                 return;
  1635.         /* re-activate first request in queue */
  1636.         cqr = (*device_addr)->queue.head;
  1637.         
  1638.         if (cqr->status == CQR_STATUS_PENDING) {
  1639.                 
  1640.                 DASD_MESSAGE (KERN_DEBUG, (*device_addr), "%s",
  1641.                               "device request queue restarted by "
  1642.                               "state change pending interruptn");
  1643.                 
  1644.                 del_timer (&(*device_addr)->timer);
  1645.                 
  1646.                 check_then_set (&cqr->status,
  1647.                                 CQR_STATUS_PENDING, CQR_STATUS_QUEUED);
  1648.                 
  1649.                 dasd_schedule_bh (*device_addr);
  1650.                 
  1651.         }
  1652. } /* end dasd_handle_state_change_pending */
  1653. /*
  1654.  * function dasd_int_handler
  1655.  * is the DASD driver's default interrupt handler for SSCH-IO
  1656.  */
  1657. void
  1658. dasd_int_handler (int irq, void *ds, struct pt_regs *regs)
  1659. {
  1660. int ip;
  1661. ccw_req_t *cqr;
  1662. dasd_device_t *device;
  1663.         unsigned long long now;
  1664. dasd_era_t era = dasd_era_none; /* default is everything is okay */
  1665. devstat_t *stat = (devstat_t *)ds;
  1666.         if (stat == NULL) {
  1667.                 BUG();
  1668. }
  1669.         DASD_DRIVER_DEBUG_EVENT (6, dasd_int_handler,
  1670.                                  "Interrupt: IRQ %02x, stat %02x, devno %04x",
  1671.                                  irq,
  1672.                                  stat->dstat,
  1673.                                  stat->devno);
  1674.         asm volatile ("STCK %0":"=m" (now));
  1675.         /* first of all check for state change pending interrupt */
  1676.         if ((stat->dstat & DEV_STAT_ATTENTION ) && 
  1677.             (stat->dstat & DEV_STAT_DEV_END   ) &&
  1678.             (stat->dstat & DEV_STAT_UNIT_EXCEP)   ) {
  1679.                 DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
  1680.                                          "State change Interrupt: %04x",
  1681.                                          stat->devno);
  1682.                 dasd_handle_state_change_pending (stat);
  1683.                 return;
  1684.         }
  1685. ip = stat->intparm;
  1686. if (!ip) { /* no intparm: unsolicited interrupt */
  1687.                 DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
  1688.                                          "Unsolicited Interrupt: %04x",
  1689.                                          stat->devno);
  1690. printk (KERN_DEBUG PRINTK_HEADER
  1691.                         "unsolicited interrupt: irq 0x%x devno %04xn",
  1692.                         irq,
  1693.                         stat->devno);
  1694. return;
  1695. }
  1696. if (ip & 0x80000001) {
  1697.                 DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
  1698.                                          "spurious Interrupt: %04x",
  1699.                                          stat->devno);
  1700. printk (KERN_DEBUG PRINTK_HEADER
  1701.                         "spurious interrupt: irq 0x%x devno %04x, parm %08xn",
  1702.                         irq,
  1703.                         stat->devno,ip);
  1704. return;
  1705. }
  1706. cqr = (ccw_req_t *)(long)ip;
  1707.         /* check status - the request might have been killed because of dyn dettach */
  1708. if (cqr->status != CQR_STATUS_IN_IO) {
  1709.                 DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,
  1710.                                          "invalid status %02x on device %04x",
  1711.                                          cqr->status,
  1712.                                          stat->devno);
  1713. printk (KERN_DEBUG PRINTK_HEADER
  1714.                         "invalid status: irq 0x%x devno %04x, status %02xn",
  1715.                         irq,
  1716.                         stat->devno,
  1717.                         cqr->status);
  1718. return;
  1719. }
  1720. device = (dasd_device_t *) cqr->device;
  1721. if (device == NULL || 
  1722.             device != ds-offsetof(dasd_device_t,dev_status)) {
  1723.                 BUG();
  1724. }
  1725. if (device->devinfo.irq != irq) {
  1726.                 BUG();
  1727. }
  1728. if (strncmp (device->discipline->ebcname, (char *) &cqr->magic, 4)) {
  1729.                 BUG();
  1730. }
  1731.         /* first of all lets try to find out the appropriate era_action */
  1732.         DASD_DEVICE_DEBUG_EVENT (4, device," Int: CS/DS 0x%04x",
  1733.                                  ((stat->cstat<<8)|stat->dstat));
  1734. /* first of all lets try to find out the appropriate era_action */
  1735. if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL ||
  1736.     stat->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) {
  1737. /* anything abnormal ? */
  1738. if (device->discipline->examine_error == NULL ||
  1739.     stat->flag & DEVSTAT_HALT_FUNCTION) {
  1740. era = dasd_era_fatal;
  1741. } else {
  1742. era = device->discipline->examine_error (cqr, stat);
  1743. }
  1744.                 DASD_DRIVER_DEBUG_EVENT (1, dasd_int_handler," era_code %d",
  1745.                                          era);
  1746. }
  1747.         if ( era == dasd_era_none ) {
  1748.                 check_then_set(&cqr->status, 
  1749.                                CQR_STATUS_IN_IO, 
  1750.                                CQR_STATUS_DONE);
  1751.                 cqr->stopclk=now;
  1752. /* start the next queued request if possible -> fast_io */
  1753.                 if (cqr->next &&
  1754.                     cqr->next->status == CQR_STATUS_QUEUED) {
  1755.                         if (device->discipline->start_IO (cqr->next) != 0) {
  1756.                                 printk (KERN_WARNING PRINTK_HEADER
  1757.                                         "Interrupt fastpath failed!n");
  1758.                         } 
  1759.                 }
  1760.         } else { /* error */
  1761. if (cqr->dstat == NULL)
  1762. cqr->dstat = kmalloc (sizeof (devstat_t), GFP_ATOMIC);
  1763. if (cqr->dstat) {
  1764. memcpy (cqr->dstat, stat, sizeof (devstat_t));
  1765. } else {
  1766. PRINT_ERR ("no memory for dstat...ignoringn");
  1767. }
  1768. #ifdef ERP_DEBUG
  1769. /* dump sense data */
  1770. if (device->discipline            && 
  1771.                     device->discipline->dump_sense  ) {
  1772.                         device->discipline->dump_sense (device, 
  1773.                                                         cqr);
  1774. }
  1775. #endif
  1776. switch (era) {
  1777. case dasd_era_fatal:
  1778. check_then_set (&cqr->status, 
  1779.                                         CQR_STATUS_IN_IO,
  1780. CQR_STATUS_FAILED);
  1781.                         cqr->stopclk = now;
  1782. break;
  1783. case dasd_era_recover:
  1784. check_then_set (&cqr->status, 
  1785.                                         CQR_STATUS_IN_IO,
  1786. CQR_STATUS_ERROR);
  1787. break;
  1788. default:
  1789. BUG ();
  1790. }
  1791. }
  1792.         if ( cqr == device->init_cqr &&
  1793.              ( cqr->status == CQR_STATUS_DONE ||
  1794.                cqr->status == CQR_STATUS_FAILED )){
  1795.                 dasd_state_init_to_ready(device);
  1796.                 if ( atomic_read(&dasd_init_pending) == 0)
  1797.                         wake_up (&dasd_init_waitq);
  1798.         }
  1799. dasd_schedule_bh (device);
  1800. } /* end dasd_int_handler */
  1801. /* SECTION: Some stuff related to error recovery */
  1802. /*
  1803.  * DEFAULT_ERP_ACTION
  1804.  *
  1805.  * DESCRIPTION
  1806.  *   sets up the default-ERP ccw_req_t, namely one, which performs a TIC
  1807.  *   to the original channel program with a retry counter of 16
  1808.  *
  1809.  * PARAMETER
  1810.  *   cqr                failed CQR
  1811.  *
  1812.  * RETURN VALUES
  1813.  *   erp                CQR performing the ERP
  1814.  */
  1815. ccw_req_t *
  1816. dasd_default_erp_action (ccw_req_t * cqr)
  1817. {
  1818.         dasd_device_t *device = cqr->device;
  1819. ccw_req_t     *erp    = dasd_alloc_request ((char *) &cqr->magic, 1, 0, cqr->device);
  1820. printk (KERN_DEBUG PRINTK_HEADER "Default ERP called... n");
  1821. if (!erp) {
  1822.                 DASD_MESSAGE (KERN_ERR, device, "%s",
  1823.                               "Unable to allocate ERP request");
  1824.                 
  1825.                 check_then_set (&cqr->status,
  1826.                                 CQR_STATUS_ERROR,
  1827.                                 CQR_STATUS_FAILED);
  1828.                 asm volatile ("STCK %0":"=m" (cqr->stopclk));
  1829.                 return cqr;
  1830. }
  1831. erp->cpaddr->cmd_code = CCW_CMD_TIC;
  1832. erp->cpaddr->cda = (__u32) (addr_t) cqr->cpaddr;
  1833. erp->function = dasd_default_erp_action;
  1834. erp->refers = cqr;
  1835. erp->device = cqr->device;
  1836. erp->magic = cqr->magic;
  1837. erp->retries = 16;
  1838. erp->status = CQR_STATUS_FILLED;
  1839.         dasd_chanq_enq_head (&device->queue,
  1840.                              erp);
  1841. return erp;
  1842. } /* end dasd_default_erp_action */
  1843. /*
  1844.  * DEFAULT_ERP_POSTACTION
  1845.  *
  1846.  * DESCRIPTION
  1847.  *   Frees all ERPs of the current ERP Chain and set the status
  1848.  *   of the original CQR either to CQR_STATUS_DONE if ERP was successful
  1849.  *   or to CQR_STATUS_FAILED if ERP was NOT successful.
  1850.  *   NOTE: This function is only called if no discipline postaction
  1851.  *         is available
  1852.  *
  1853.  * PARAMETER
  1854.  *   erp                current erp_head
  1855.  *
  1856.  * RETURN VALUES
  1857.  *   cqr                pointer to the original CQR
  1858.  */
  1859. ccw_req_t *
  1860. dasd_default_erp_postaction (ccw_req_t *erp)
  1861. {
  1862. ccw_req_t     *cqr      = NULL, 
  1863.                       *free_erp = NULL;
  1864. dasd_device_t *device   = erp->device;
  1865. int           success;
  1866. if (erp->refers   == NULL || 
  1867.             erp->function == NULL   ) {
  1868. BUG ();
  1869. }
  1870. if (erp->status == CQR_STATUS_DONE)
  1871. success = 1;
  1872. else
  1873. success = 0;
  1874. /* free all ERPs - but NOT the original cqr */
  1875. while (erp->refers != NULL) {
  1876. free_erp = erp;
  1877. erp      = erp->refers;
  1878. /* remove the request from the device queue */
  1879. dasd_chanq_deq (&device->queue,
  1880.                                 free_erp);
  1881. /* free the finished erp request */
  1882. dasd_free_request (free_erp, free_erp->device);
  1883. }
  1884. /* save ptr to original cqr */
  1885. cqr = erp;
  1886. /* set corresponding status to original cqr */
  1887. if (success) {
  1888. check_then_set (&cqr->status, 
  1889.                                 CQR_STATUS_ERROR,
  1890. CQR_STATUS_DONE);
  1891. } else {
  1892. check_then_set (&cqr->status,
  1893. CQR_STATUS_ERROR, 
  1894.                                 CQR_STATUS_FAILED);
  1895.                 asm volatile ("STCK %0":"=m" (cqr->stopclk));
  1896. }
  1897. return cqr;
  1898. } /* end default_erp_postaction */
  1899. /* SECTION: The helpers of the struct file_operations */
  1900. /*
  1901.  * function dasd_format
  1902.  * performs formatting of _device_ according to _fdata_
  1903.  * Note: The discipline's format_function is assumed to deliver formatting
  1904.  * commands to format a single unit of the device. In terms of the ECKD
  1905.  * devices this means CCWs are generated to format a single track.
  1906.  */
  1907. static int
  1908. dasd_format (dasd_device_t * device, format_data_t * fdata)
  1909. {
  1910. int rc = 0;
  1911. int openct = atomic_read (&device->open_count);
  1912. if (openct > 1) {
  1913. DASD_MESSAGE (KERN_WARNING, device, "%s",
  1914.       "dasd_format: device is open! expect errors.");
  1915. }
  1916. DASD_MESSAGE (KERN_INFO, device,
  1917.       "formatting units %d to %d (%d B blocks) flags %d",
  1918.       fdata->start_unit, 
  1919.                       fdata->stop_unit,
  1920.       fdata->blksize, 
  1921.                       fdata->intensity);
  1922. while ((!rc) && (fdata->start_unit <= fdata->stop_unit)) {
  1923.                 ccw_req_t *req;
  1924.                 dasd_format_fn_t ffn = device->discipline->format_device;
  1925. ffn = device->discipline->format_device;
  1926. if (ffn == NULL)
  1927. break;
  1928. req = ffn (device, fdata);
  1929. if (req == NULL) {
  1930. rc = -ENOMEM;
  1931. break;
  1932. }
  1933. if ((rc = dasd_sleep_on_req (req)) != 0) {
  1934. DASD_MESSAGE (KERN_WARNING, device,
  1935.       " Formatting of unit %d failed with rc = %dn",