cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dasd_alias.c (28381B)


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