Merge branches 'release', 'misc' and 'misc-2.6.25' into release
[linux-2.6] / drivers / s390 / block / dasd_alias.c
1 /*
2  * PAV alias management for the DASD ECKD discipline
3  *
4  * Copyright IBM Corporation, 2007
5  * Author(s): Stefan Weinhuber <wein@de.ibm.com>
6  */
7
8 #include <linux/list.h>
9 #include <asm/ebcdic.h>
10 #include "dasd_int.h"
11 #include "dasd_eckd.h"
12
13 #ifdef PRINTK_HEADER
14 #undef PRINTK_HEADER
15 #endif                          /* PRINTK_HEADER */
16 #define PRINTK_HEADER "dasd(eckd):"
17
18
19 /*
20  * General concept of alias management:
21  * - PAV and DASD alias management is specific to the eckd discipline.
22  * - A device is connected to an lcu as long as the device exists.
23  *   dasd_alias_make_device_known_to_lcu will be called wenn the
24  *   device is checked by the eckd discipline and
25  *   dasd_alias_disconnect_device_from_lcu will be called
26  *   before the device is deleted.
27  * - The dasd_alias_add_device / dasd_alias_remove_device
28  *   functions mark the point when a device is 'ready for service'.
29  * - A summary unit check is a rare occasion, but it is mandatory to
30  *   support it. It requires some complex recovery actions before the
31  *   devices can be used again (see dasd_alias_handle_summary_unit_check).
32  * - dasd_alias_get_start_dev will find an alias device that can be used
33  *   instead of the base device and does some (very simple) load balancing.
34  *   This is the function that gets called for each I/O, so when improving
35  *   something, this function should get faster or better, the rest has just
36  *   to be correct.
37  */
38
39
40 static void summary_unit_check_handling_work(struct work_struct *);
41 static void lcu_update_work(struct work_struct *);
42 static int _schedule_lcu_update(struct alias_lcu *, struct dasd_device *);
43
44 static struct alias_root aliastree = {
45         .serverlist = LIST_HEAD_INIT(aliastree.serverlist),
46         .lock = __SPIN_LOCK_UNLOCKED(aliastree.lock),
47 };
48
49 static struct alias_server *_find_server(struct dasd_uid *uid)
50 {
51         struct alias_server *pos;
52         list_for_each_entry(pos, &aliastree.serverlist, server) {
53                 if (!strncmp(pos->uid.vendor, uid->vendor,
54                              sizeof(uid->vendor))
55                     && !strncmp(pos->uid.serial, uid->serial,
56                                 sizeof(uid->serial)))
57                         return pos;
58         };
59         return NULL;
60 }
61
62 static struct alias_lcu *_find_lcu(struct alias_server *server,
63                                    struct dasd_uid *uid)
64 {
65         struct alias_lcu *pos;
66         list_for_each_entry(pos, &server->lculist, lcu) {
67                 if (pos->uid.ssid == uid->ssid)
68                         return pos;
69         };
70         return NULL;
71 }
72
73 static struct alias_pav_group *_find_group(struct alias_lcu *lcu,
74                                            struct dasd_uid *uid)
75 {
76         struct alias_pav_group *pos;
77         __u8 search_unit_addr;
78
79         /* for hyper pav there is only one group */
80         if (lcu->pav == HYPER_PAV) {
81                 if (list_empty(&lcu->grouplist))
82                         return NULL;
83                 else
84                         return list_first_entry(&lcu->grouplist,
85                                                 struct alias_pav_group, group);
86         }
87
88         /* for base pav we have to find the group that matches the base */
89         if (uid->type == UA_BASE_DEVICE)
90                 search_unit_addr = uid->real_unit_addr;
91         else
92                 search_unit_addr = uid->base_unit_addr;
93         list_for_each_entry(pos, &lcu->grouplist, group) {
94                 if (pos->uid.base_unit_addr == search_unit_addr)
95                         return pos;
96         };
97         return NULL;
98 }
99
100 static struct alias_server *_allocate_server(struct dasd_uid *uid)
101 {
102         struct alias_server *server;
103
104         server = kzalloc(sizeof(*server), GFP_KERNEL);
105         if (!server)
106                 return ERR_PTR(-ENOMEM);
107         memcpy(server->uid.vendor, uid->vendor, sizeof(uid->vendor));
108         memcpy(server->uid.serial, uid->serial, sizeof(uid->serial));
109         INIT_LIST_HEAD(&server->server);
110         INIT_LIST_HEAD(&server->lculist);
111         return server;
112 }
113
114 static void _free_server(struct alias_server *server)
115 {
116         kfree(server);
117 }
118
119 static struct alias_lcu *_allocate_lcu(struct dasd_uid *uid)
120 {
121         struct alias_lcu *lcu;
122
123         lcu = kzalloc(sizeof(*lcu), GFP_KERNEL);
124         if (!lcu)
125                 return ERR_PTR(-ENOMEM);
126         lcu->uac = kzalloc(sizeof(*(lcu->uac)), GFP_KERNEL | GFP_DMA);
127         if (!lcu->uac)
128                 goto out_err1;
129         lcu->rsu_cqr = kzalloc(sizeof(*lcu->rsu_cqr), GFP_KERNEL | GFP_DMA);
130         if (!lcu->rsu_cqr)
131                 goto out_err2;
132         lcu->rsu_cqr->cpaddr = kzalloc(sizeof(struct ccw1),
133                                        GFP_KERNEL | GFP_DMA);
134         if (!lcu->rsu_cqr->cpaddr)
135                 goto out_err3;
136         lcu->rsu_cqr->data = kzalloc(16, GFP_KERNEL | GFP_DMA);
137         if (!lcu->rsu_cqr->data)
138                 goto out_err4;
139
140         memcpy(lcu->uid.vendor, uid->vendor, sizeof(uid->vendor));
141         memcpy(lcu->uid.serial, uid->serial, sizeof(uid->serial));
142         lcu->uid.ssid = uid->ssid;
143         lcu->pav = NO_PAV;
144         lcu->flags = NEED_UAC_UPDATE | UPDATE_PENDING;
145         INIT_LIST_HEAD(&lcu->lcu);
146         INIT_LIST_HEAD(&lcu->inactive_devices);
147         INIT_LIST_HEAD(&lcu->active_devices);
148         INIT_LIST_HEAD(&lcu->grouplist);
149         INIT_WORK(&lcu->suc_data.worker, summary_unit_check_handling_work);
150         INIT_DELAYED_WORK(&lcu->ruac_data.dwork, lcu_update_work);
151         spin_lock_init(&lcu->lock);
152         return lcu;
153
154 out_err4:
155         kfree(lcu->rsu_cqr->cpaddr);
156 out_err3:
157         kfree(lcu->rsu_cqr);
158 out_err2:
159         kfree(lcu->uac);
160 out_err1:
161         kfree(lcu);
162         return ERR_PTR(-ENOMEM);
163 }
164
165 static void _free_lcu(struct alias_lcu *lcu)
166 {
167         kfree(lcu->rsu_cqr->data);
168         kfree(lcu->rsu_cqr->cpaddr);
169         kfree(lcu->rsu_cqr);
170         kfree(lcu->uac);
171         kfree(lcu);
172 }
173
174 /*
175  * This is the function that will allocate all the server and lcu data,
176  * so this function must be called first for a new device.
177  * If the return value is 1, the lcu was already known before, if it
178  * is 0, this is a new lcu.
179  * Negative return code indicates that something went wrong (e.g. -ENOMEM)
180  */
181 int dasd_alias_make_device_known_to_lcu(struct dasd_device *device)
182 {
183         struct dasd_eckd_private *private;
184         unsigned long flags;
185         struct alias_server *server, *newserver;
186         struct alias_lcu *lcu, *newlcu;
187         int is_lcu_known;
188         struct dasd_uid *uid;
189
190         private = (struct dasd_eckd_private *) device->private;
191         uid = &private->uid;
192         spin_lock_irqsave(&aliastree.lock, flags);
193         is_lcu_known = 1;
194         server = _find_server(uid);
195         if (!server) {
196                 spin_unlock_irqrestore(&aliastree.lock, flags);
197                 newserver = _allocate_server(uid);
198                 if (IS_ERR(newserver))
199                         return PTR_ERR(newserver);
200                 spin_lock_irqsave(&aliastree.lock, flags);
201                 server = _find_server(uid);
202                 if (!server) {
203                         list_add(&newserver->server, &aliastree.serverlist);
204                         server = newserver;
205                         is_lcu_known = 0;
206                 } else {
207                         /* someone was faster */
208                         _free_server(newserver);
209                 }
210         }
211
212         lcu = _find_lcu(server, uid);
213         if (!lcu) {
214                 spin_unlock_irqrestore(&aliastree.lock, flags);
215                 newlcu = _allocate_lcu(uid);
216                 if (IS_ERR(newlcu))
217                         return PTR_ERR(lcu);
218                 spin_lock_irqsave(&aliastree.lock, flags);
219                 lcu = _find_lcu(server, uid);
220                 if (!lcu) {
221                         list_add(&newlcu->lcu, &server->lculist);
222                         lcu = newlcu;
223                         is_lcu_known = 0;
224                 } else {
225                         /* someone was faster */
226                         _free_lcu(newlcu);
227                 }
228                 is_lcu_known = 0;
229         }
230         spin_lock(&lcu->lock);
231         list_add(&device->alias_list, &lcu->inactive_devices);
232         private->lcu = lcu;
233         spin_unlock(&lcu->lock);
234         spin_unlock_irqrestore(&aliastree.lock, flags);
235
236         return is_lcu_known;
237 }
238
239 /*
240  * This function removes a device from the scope of alias management.
241  * The complicated part is to make sure that it is not in use by
242  * any of the workers. If necessary cancel the work.
243  */
244 void dasd_alias_disconnect_device_from_lcu(struct dasd_device *device)
245 {
246         struct dasd_eckd_private *private;
247         unsigned long flags;
248         struct alias_lcu *lcu;
249         struct alias_server *server;
250         int was_pending;
251
252         private = (struct dasd_eckd_private *) device->private;
253         lcu = private->lcu;
254         spin_lock_irqsave(&lcu->lock, flags);
255         list_del_init(&device->alias_list);
256         /* make sure that the workers don't use this device */
257         if (device == lcu->suc_data.device) {
258                 spin_unlock_irqrestore(&lcu->lock, flags);
259                 cancel_work_sync(&lcu->suc_data.worker);
260                 spin_lock_irqsave(&lcu->lock, flags);
261                 if (device == lcu->suc_data.device)
262                         lcu->suc_data.device = NULL;
263         }
264         was_pending = 0;
265         if (device == lcu->ruac_data.device) {
266                 spin_unlock_irqrestore(&lcu->lock, flags);
267                 was_pending = 1;
268                 cancel_delayed_work_sync(&lcu->ruac_data.dwork);
269                 spin_lock_irqsave(&lcu->lock, flags);
270                 if (device == lcu->ruac_data.device)
271                         lcu->ruac_data.device = NULL;
272         }
273         private->lcu = NULL;
274         spin_unlock_irqrestore(&lcu->lock, flags);
275
276         spin_lock_irqsave(&aliastree.lock, flags);
277         spin_lock(&lcu->lock);
278         if (list_empty(&lcu->grouplist) &&
279             list_empty(&lcu->active_devices) &&
280             list_empty(&lcu->inactive_devices)) {
281                 list_del(&lcu->lcu);
282                 spin_unlock(&lcu->lock);
283                 _free_lcu(lcu);
284                 lcu = NULL;
285         } else {
286                 if (was_pending)
287                         _schedule_lcu_update(lcu, NULL);
288                 spin_unlock(&lcu->lock);
289         }
290         server = _find_server(&private->uid);
291         if (server && list_empty(&server->lculist)) {
292                 list_del(&server->server);
293                 _free_server(server);
294         }
295         spin_unlock_irqrestore(&aliastree.lock, flags);
296 }
297
298 /*
299  * This function assumes that the unit address configuration stored
300  * in the lcu is up to date and will update the device uid before
301  * adding it to a pav group.
302  */
303 static int _add_device_to_lcu(struct alias_lcu *lcu,
304                               struct dasd_device *device)
305 {
306
307         struct dasd_eckd_private *private;
308         struct alias_pav_group *group;
309         struct dasd_uid *uid;
310
311         private = (struct dasd_eckd_private *) device->private;
312         uid = &private->uid;
313         uid->type = lcu->uac->unit[uid->real_unit_addr].ua_type;
314         uid->base_unit_addr = lcu->uac->unit[uid->real_unit_addr].base_ua;
315         dasd_set_uid(device->cdev, &private->uid);
316
317         /* if we have no PAV anyway, we don't need to bother with PAV groups */
318         if (lcu->pav == NO_PAV) {
319                 list_move(&device->alias_list, &lcu->active_devices);
320                 return 0;
321         }
322
323         group = _find_group(lcu, uid);
324         if (!group) {
325                 group = kzalloc(sizeof(*group), GFP_ATOMIC);
326                 if (!group)
327                         return -ENOMEM;
328                 memcpy(group->uid.vendor, uid->vendor, sizeof(uid->vendor));
329                 memcpy(group->uid.serial, uid->serial, sizeof(uid->serial));
330                 group->uid.ssid = uid->ssid;
331                 if (uid->type == UA_BASE_DEVICE)
332                         group->uid.base_unit_addr = uid->real_unit_addr;
333                 else
334                         group->uid.base_unit_addr = uid->base_unit_addr;
335                 INIT_LIST_HEAD(&group->group);
336                 INIT_LIST_HEAD(&group->baselist);
337                 INIT_LIST_HEAD(&group->aliaslist);
338                 list_add(&group->group, &lcu->grouplist);
339         }
340         if (uid->type == UA_BASE_DEVICE)
341                 list_move(&device->alias_list, &group->baselist);
342         else
343                 list_move(&device->alias_list, &group->aliaslist);
344         private->pavgroup = group;
345         return 0;
346 };
347
348 static void _remove_device_from_lcu(struct alias_lcu *lcu,
349                                     struct dasd_device *device)
350 {
351         struct dasd_eckd_private *private;
352         struct alias_pav_group *group;
353
354         private = (struct dasd_eckd_private *) device->private;
355         list_move(&device->alias_list, &lcu->inactive_devices);
356         group = private->pavgroup;
357         if (!group)
358                 return;
359         private->pavgroup = NULL;
360         if (list_empty(&group->baselist) && list_empty(&group->aliaslist)) {
361                 list_del(&group->group);
362                 kfree(group);
363                 return;
364         }
365         if (group->next == device)
366                 group->next = NULL;
367 };
368
369 static int read_unit_address_configuration(struct dasd_device *device,
370                                            struct alias_lcu *lcu)
371 {
372         struct dasd_psf_prssd_data *prssdp;
373         struct dasd_ccw_req *cqr;
374         struct ccw1 *ccw;
375         int rc;
376         unsigned long flags;
377
378         cqr = dasd_kmalloc_request("ECKD",
379                                    1 /* PSF */  + 1 /* RSSD */ ,
380                                    (sizeof(struct dasd_psf_prssd_data)),
381                                    device);
382         if (IS_ERR(cqr))
383                 return PTR_ERR(cqr);
384         cqr->startdev = device;
385         cqr->memdev = device;
386         clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
387         cqr->retries = 10;
388         cqr->expires = 20 * HZ;
389
390         /* Prepare for Read Subsystem Data */
391         prssdp = (struct dasd_psf_prssd_data *) cqr->data;
392         memset(prssdp, 0, sizeof(struct dasd_psf_prssd_data));
393         prssdp->order = PSF_ORDER_PRSSD;
394         prssdp->suborder = 0x0e;        /* Read unit address configuration */
395         /* all other bytes of prssdp must be zero */
396
397         ccw = cqr->cpaddr;
398         ccw->cmd_code = DASD_ECKD_CCW_PSF;
399         ccw->count = sizeof(struct dasd_psf_prssd_data);
400         ccw->flags |= CCW_FLAG_CC;
401         ccw->cda = (__u32)(addr_t) prssdp;
402
403         /* Read Subsystem Data - feature codes */
404         memset(lcu->uac, 0, sizeof(*(lcu->uac)));
405
406         ccw++;
407         ccw->cmd_code = DASD_ECKD_CCW_RSSD;
408         ccw->count = sizeof(*(lcu->uac));
409         ccw->cda = (__u32)(addr_t) lcu->uac;
410
411         cqr->buildclk = get_clock();
412         cqr->status = DASD_CQR_FILLED;
413
414         /* need to unset flag here to detect race with summary unit check */
415         spin_lock_irqsave(&lcu->lock, flags);
416         lcu->flags &= ~NEED_UAC_UPDATE;
417         spin_unlock_irqrestore(&lcu->lock, flags);
418
419         do {
420                 rc = dasd_sleep_on(cqr);
421         } while (rc && (cqr->retries > 0));
422         if (rc) {
423                 spin_lock_irqsave(&lcu->lock, flags);
424                 lcu->flags |= NEED_UAC_UPDATE;
425                 spin_unlock_irqrestore(&lcu->lock, flags);
426         }
427         dasd_kfree_request(cqr, cqr->memdev);
428         return rc;
429 }
430
431 static int _lcu_update(struct dasd_device *refdev, struct alias_lcu *lcu)
432 {
433         unsigned long flags;
434         struct alias_pav_group *pavgroup, *tempgroup;
435         struct dasd_device *device, *tempdev;
436         int i, rc;
437         struct dasd_eckd_private *private;
438
439         spin_lock_irqsave(&lcu->lock, flags);
440         list_for_each_entry_safe(pavgroup, tempgroup, &lcu->grouplist, group) {
441                 list_for_each_entry_safe(device, tempdev, &pavgroup->baselist,
442                                          alias_list) {
443                         list_move(&device->alias_list, &lcu->active_devices);
444                         private = (struct dasd_eckd_private *) device->private;
445                         private->pavgroup = NULL;
446                 }
447                 list_for_each_entry_safe(device, tempdev, &pavgroup->aliaslist,
448                                          alias_list) {
449                         list_move(&device->alias_list, &lcu->active_devices);
450                         private = (struct dasd_eckd_private *) device->private;
451                         private->pavgroup = NULL;
452                 }
453                 list_del(&pavgroup->group);
454                 kfree(pavgroup);
455         }
456         spin_unlock_irqrestore(&lcu->lock, flags);
457
458         rc = read_unit_address_configuration(refdev, lcu);
459         if (rc)
460                 return rc;
461
462         spin_lock_irqsave(&lcu->lock, flags);
463         lcu->pav = NO_PAV;
464         for (i = 0; i < MAX_DEVICES_PER_LCU; ++i) {
465                 switch (lcu->uac->unit[i].ua_type) {
466                 case UA_BASE_PAV_ALIAS:
467                         lcu->pav = BASE_PAV;
468                         break;
469                 case UA_HYPER_PAV_ALIAS:
470                         lcu->pav = HYPER_PAV;
471                         break;
472                 }
473                 if (lcu->pav != NO_PAV)
474                         break;
475         }
476
477         list_for_each_entry_safe(device, tempdev, &lcu->active_devices,
478                                  alias_list) {
479                 _add_device_to_lcu(lcu, device);
480         }
481         spin_unlock_irqrestore(&lcu->lock, flags);
482         return 0;
483 }
484
485 static void lcu_update_work(struct work_struct *work)
486 {
487         struct alias_lcu *lcu;
488         struct read_uac_work_data *ruac_data;
489         struct dasd_device *device;
490         unsigned long flags;
491         int rc;
492
493         ruac_data = container_of(work, struct read_uac_work_data, dwork.work);
494         lcu = container_of(ruac_data, struct alias_lcu, ruac_data);
495         device = ruac_data->device;
496         rc = _lcu_update(device, lcu);
497         /*
498          * Need to check flags again, as there could have been another
499          * prepare_update or a new device a new device while we were still
500          * processing the data
501          */
502         spin_lock_irqsave(&lcu->lock, flags);
503         if (rc || (lcu->flags & NEED_UAC_UPDATE)) {
504                 DEV_MESSAGE(KERN_WARNING, device, "could not update"
505                             " alias data in lcu (rc = %d), retry later", rc);
506                 schedule_delayed_work(&lcu->ruac_data.dwork, 30*HZ);
507         } else {
508                 lcu->ruac_data.device = NULL;
509                 lcu->flags &= ~UPDATE_PENDING;
510         }
511         spin_unlock_irqrestore(&lcu->lock, flags);
512 }
513
514 static int _schedule_lcu_update(struct alias_lcu *lcu,
515                                 struct dasd_device *device)
516 {
517         struct dasd_device *usedev = NULL;
518         struct alias_pav_group *group;
519
520         lcu->flags |= NEED_UAC_UPDATE;
521         if (lcu->ruac_data.device) {
522                 /* already scheduled or running */
523                 return 0;
524         }
525         if (device && !list_empty(&device->alias_list))
526                 usedev = device;
527
528         if (!usedev && !list_empty(&lcu->grouplist)) {
529                 group = list_first_entry(&lcu->grouplist,
530                                          struct alias_pav_group, group);
531                 if (!list_empty(&group->baselist))
532                         usedev = list_first_entry(&group->baselist,
533                                                   struct dasd_device,
534                                                   alias_list);
535                 else if (!list_empty(&group->aliaslist))
536                         usedev = list_first_entry(&group->aliaslist,
537                                                   struct dasd_device,
538                                                   alias_list);
539         }
540         if (!usedev && !list_empty(&lcu->active_devices)) {
541                 usedev = list_first_entry(&lcu->active_devices,
542                                           struct dasd_device, alias_list);
543         }
544         /*
545          * if we haven't found a proper device yet, give up for now, the next
546          * device that will be set active will trigger an lcu update
547          */
548         if (!usedev)
549                 return -EINVAL;
550         lcu->ruac_data.device = usedev;
551         schedule_delayed_work(&lcu->ruac_data.dwork, 0);
552         return 0;
553 }
554
555 int dasd_alias_add_device(struct dasd_device *device)
556 {
557         struct dasd_eckd_private *private;
558         struct alias_lcu *lcu;
559         unsigned long flags;
560         int rc;
561
562         private = (struct dasd_eckd_private *) device->private;
563         lcu = private->lcu;
564         rc = 0;
565         spin_lock_irqsave(&lcu->lock, flags);
566         if (!(lcu->flags & UPDATE_PENDING)) {
567                 rc = _add_device_to_lcu(lcu, device);
568                 if (rc)
569                         lcu->flags |= UPDATE_PENDING;
570         }
571         if (lcu->flags & UPDATE_PENDING) {
572                 list_move(&device->alias_list, &lcu->active_devices);
573                 _schedule_lcu_update(lcu, device);
574         }
575         spin_unlock_irqrestore(&lcu->lock, flags);
576         return rc;
577 }
578
579 int dasd_alias_remove_device(struct dasd_device *device)
580 {
581         struct dasd_eckd_private *private;
582         struct alias_lcu *lcu;
583         unsigned long flags;
584
585         private = (struct dasd_eckd_private *) device->private;
586         lcu = private->lcu;
587         spin_lock_irqsave(&lcu->lock, flags);
588         _remove_device_from_lcu(lcu, device);
589         spin_unlock_irqrestore(&lcu->lock, flags);
590         return 0;
591 }
592
593 struct dasd_device *dasd_alias_get_start_dev(struct dasd_device *base_device)
594 {
595
596         struct dasd_device *alias_device;
597         struct alias_pav_group *group;
598         struct alias_lcu *lcu;
599         struct dasd_eckd_private *private, *alias_priv;
600         unsigned long flags;
601
602         private = (struct dasd_eckd_private *) base_device->private;
603         group = private->pavgroup;
604         lcu = private->lcu;
605         if (!group || !lcu)
606                 return NULL;
607         if (lcu->pav == NO_PAV ||
608             lcu->flags & (NEED_UAC_UPDATE | UPDATE_PENDING))
609                 return NULL;
610
611         spin_lock_irqsave(&lcu->lock, flags);
612         alias_device = group->next;
613         if (!alias_device) {
614                 if (list_empty(&group->aliaslist)) {
615                         spin_unlock_irqrestore(&lcu->lock, flags);
616                         return NULL;
617                 } else {
618                         alias_device = list_first_entry(&group->aliaslist,
619                                                         struct dasd_device,
620                                                         alias_list);
621                 }
622         }
623         if (list_is_last(&alias_device->alias_list, &group->aliaslist))
624                 group->next = list_first_entry(&group->aliaslist,
625                                                struct dasd_device, alias_list);
626         else
627                 group->next = list_first_entry(&alias_device->alias_list,
628                                                struct dasd_device, alias_list);
629         spin_unlock_irqrestore(&lcu->lock, flags);
630         alias_priv = (struct dasd_eckd_private *) alias_device->private;
631         if ((alias_priv->count < private->count) && !alias_device->stopped)
632                 return alias_device;
633         else
634                 return NULL;
635 }
636
637 /*
638  * Summary unit check handling depends on the way alias devices
639  * are handled so it is done here rather then in dasd_eckd.c
640  */
641 static int reset_summary_unit_check(struct alias_lcu *lcu,
642                                     struct dasd_device *device,
643                                     char reason)
644 {
645         struct dasd_ccw_req *cqr;
646         int rc = 0;
647
648         cqr = lcu->rsu_cqr;
649         strncpy((char *) &cqr->magic, "ECKD", 4);
650         ASCEBC((char *) &cqr->magic, 4);
651         cqr->cpaddr->cmd_code = DASD_ECKD_CCW_RSCK;
652         cqr->cpaddr->flags = 0 ;
653         cqr->cpaddr->count = 16;
654         cqr->cpaddr->cda = (__u32)(addr_t) cqr->data;
655         ((char *)cqr->data)[0] = reason;
656
657         clear_bit(DASD_CQR_FLAGS_USE_ERP, &cqr->flags);
658         cqr->retries = 255;     /* set retry counter to enable basic ERP */
659         cqr->startdev = device;
660         cqr->memdev = device;
661         cqr->block = NULL;
662         cqr->expires = 5 * HZ;
663         cqr->buildclk = get_clock();
664         cqr->status = DASD_CQR_FILLED;
665
666         rc = dasd_sleep_on_immediatly(cqr);
667         return rc;
668 }
669
670 static void _restart_all_base_devices_on_lcu(struct alias_lcu *lcu)
671 {
672         struct alias_pav_group *pavgroup;
673         struct dasd_device *device;
674         struct dasd_eckd_private *private;
675
676         /* active and inactive list can contain alias as well as base devices */
677         list_for_each_entry(device, &lcu->active_devices, alias_list) {
678                 private = (struct dasd_eckd_private *) device->private;
679                 if (private->uid.type != UA_BASE_DEVICE)
680                         continue;
681                 dasd_schedule_block_bh(device->block);
682                 dasd_schedule_device_bh(device);
683         }
684         list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
685                 private = (struct dasd_eckd_private *) device->private;
686                 if (private->uid.type != UA_BASE_DEVICE)
687                         continue;
688                 dasd_schedule_block_bh(device->block);
689                 dasd_schedule_device_bh(device);
690         }
691         list_for_each_entry(pavgroup, &lcu->grouplist, group) {
692                 list_for_each_entry(device, &pavgroup->baselist, alias_list) {
693                         dasd_schedule_block_bh(device->block);
694                         dasd_schedule_device_bh(device);
695                 }
696         }
697 }
698
699 static void flush_all_alias_devices_on_lcu(struct alias_lcu *lcu)
700 {
701         struct alias_pav_group *pavgroup;
702         struct dasd_device *device, *temp;
703         struct dasd_eckd_private *private;
704         int rc;
705         unsigned long flags;
706         LIST_HEAD(active);
707
708         /*
709          * Problem here ist that dasd_flush_device_queue may wait
710          * for termination of a request to complete. We can't keep
711          * the lcu lock during that time, so we must assume that
712          * the lists may have changed.
713          * Idea: first gather all active alias devices in a separate list,
714          * then flush the first element of this list unlocked, and afterwards
715          * check if it is still on the list before moving it to the
716          * active_devices list.
717          */
718
719         spin_lock_irqsave(&lcu->lock, flags);
720         list_for_each_entry_safe(device, temp, &lcu->active_devices,
721                                  alias_list) {
722                 private = (struct dasd_eckd_private *) device->private;
723                 if (private->uid.type == UA_BASE_DEVICE)
724                         continue;
725                 list_move(&device->alias_list, &active);
726         }
727
728         list_for_each_entry(pavgroup, &lcu->grouplist, group) {
729                 list_splice_init(&pavgroup->aliaslist, &active);
730         }
731         while (!list_empty(&active)) {
732                 device = list_first_entry(&active, struct dasd_device,
733                                           alias_list);
734                 spin_unlock_irqrestore(&lcu->lock, flags);
735                 rc = dasd_flush_device_queue(device);
736                 spin_lock_irqsave(&lcu->lock, flags);
737                 /*
738                  * only move device around if it wasn't moved away while we
739                  * were waiting for the flush
740                  */
741                 if (device == list_first_entry(&active,
742                                                struct dasd_device, alias_list))
743                         list_move(&device->alias_list, &lcu->active_devices);
744         }
745         spin_unlock_irqrestore(&lcu->lock, flags);
746 }
747
748 /*
749  * This function is called in interrupt context, so the
750  * cdev lock for device is already locked!
751  */
752 static void _stop_all_devices_on_lcu(struct alias_lcu *lcu,
753                                      struct dasd_device *device)
754 {
755         struct alias_pav_group *pavgroup;
756         struct dasd_device *pos;
757
758         list_for_each_entry(pos, &lcu->active_devices, alias_list) {
759                 if (pos != device)
760                         spin_lock(get_ccwdev_lock(pos->cdev));
761                 pos->stopped |= DASD_STOPPED_SU;
762                 if (pos != device)
763                         spin_unlock(get_ccwdev_lock(pos->cdev));
764         }
765         list_for_each_entry(pos, &lcu->inactive_devices, alias_list) {
766                 if (pos != device)
767                         spin_lock(get_ccwdev_lock(pos->cdev));
768                 pos->stopped |= DASD_STOPPED_SU;
769                 if (pos != device)
770                         spin_unlock(get_ccwdev_lock(pos->cdev));
771         }
772         list_for_each_entry(pavgroup, &lcu->grouplist, group) {
773                 list_for_each_entry(pos, &pavgroup->baselist, alias_list) {
774                         if (pos != device)
775                                 spin_lock(get_ccwdev_lock(pos->cdev));
776                         pos->stopped |= DASD_STOPPED_SU;
777                         if (pos != device)
778                                 spin_unlock(get_ccwdev_lock(pos->cdev));
779                 }
780                 list_for_each_entry(pos, &pavgroup->aliaslist, alias_list) {
781                         if (pos != device)
782                                 spin_lock(get_ccwdev_lock(pos->cdev));
783                         pos->stopped |= DASD_STOPPED_SU;
784                         if (pos != device)
785                                 spin_unlock(get_ccwdev_lock(pos->cdev));
786                 }
787         }
788 }
789
790 static void _unstop_all_devices_on_lcu(struct alias_lcu *lcu)
791 {
792         struct alias_pav_group *pavgroup;
793         struct dasd_device *device;
794         unsigned long flags;
795
796         list_for_each_entry(device, &lcu->active_devices, alias_list) {
797                 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
798                 device->stopped &= ~DASD_STOPPED_SU;
799                 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
800         }
801
802         list_for_each_entry(device, &lcu->inactive_devices, alias_list) {
803                 spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
804                 device->stopped &= ~DASD_STOPPED_SU;
805                 spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
806         }
807
808         list_for_each_entry(pavgroup, &lcu->grouplist, group) {
809                 list_for_each_entry(device, &pavgroup->baselist, alias_list) {
810                         spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
811                         device->stopped &= ~DASD_STOPPED_SU;
812                         spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
813                                                flags);
814                 }
815                 list_for_each_entry(device, &pavgroup->aliaslist, alias_list) {
816                         spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
817                         device->stopped &= ~DASD_STOPPED_SU;
818                         spin_unlock_irqrestore(get_ccwdev_lock(device->cdev),
819                                                flags);
820                 }
821         }
822 }
823
824 static void summary_unit_check_handling_work(struct work_struct *work)
825 {
826         struct alias_lcu *lcu;
827         struct summary_unit_check_work_data *suc_data;
828         unsigned long flags;
829         struct dasd_device *device;
830
831         suc_data = container_of(work, struct summary_unit_check_work_data,
832                                 worker);
833         lcu = container_of(suc_data, struct alias_lcu, suc_data);
834         device = suc_data->device;
835
836         /* 1. flush alias devices */
837         flush_all_alias_devices_on_lcu(lcu);
838
839         /* 2. reset summary unit check */
840         spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags);
841         device->stopped &= ~(DASD_STOPPED_SU | DASD_STOPPED_PENDING);
842         spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags);
843         reset_summary_unit_check(lcu, device, suc_data->reason);
844
845         spin_lock_irqsave(&lcu->lock, flags);
846         _unstop_all_devices_on_lcu(lcu);
847         _restart_all_base_devices_on_lcu(lcu);
848         /* 3. read new alias configuration */
849         _schedule_lcu_update(lcu, device);
850         lcu->suc_data.device = NULL;
851         spin_unlock_irqrestore(&lcu->lock, flags);
852 }
853
854 /*
855  * note: this will be called from int handler context (cdev locked)
856  */
857 void dasd_alias_handle_summary_unit_check(struct dasd_device *device,
858                                           struct irb *irb)
859 {
860         struct alias_lcu *lcu;
861         char reason;
862         struct dasd_eckd_private *private;
863
864         private = (struct dasd_eckd_private *) device->private;
865
866         reason = irb->ecw[8];
867         DEV_MESSAGE(KERN_WARNING, device, "%s %x",
868                     "eckd handle summary unit check: reason", reason);
869
870         lcu = private->lcu;
871         if (!lcu) {
872                 DEV_MESSAGE(KERN_WARNING, device, "%s",
873                             "device not ready to handle summary"
874                             " unit check (no lcu structure)");
875                 return;
876         }
877         spin_lock(&lcu->lock);
878         _stop_all_devices_on_lcu(lcu, device);
879         /* prepare for lcu_update */
880         private->lcu->flags |= NEED_UAC_UPDATE | UPDATE_PENDING;
881         /* If this device is about to be removed just return and wait for
882          * the next interrupt on a different device
883          */
884         if (list_empty(&device->alias_list)) {
885                 DEV_MESSAGE(KERN_WARNING, device, "%s",
886                             "device is in offline processing,"
887                             " don't do summary unit check handling");
888                 spin_unlock(&lcu->lock);
889                 return;
890         }
891         if (lcu->suc_data.device) {
892                 /* already scheduled or running */
893                 DEV_MESSAGE(KERN_WARNING, device, "%s",
894                             "previous instance of summary unit check worker"
895                             " still pending");
896                 spin_unlock(&lcu->lock);
897                 return ;
898         }
899         lcu->suc_data.reason = reason;
900         lcu->suc_data.device = device;
901         spin_unlock(&lcu->lock);
902         schedule_work(&lcu->suc_data.worker);
903 };