Commit 4f2fcccd authored by Harald Freudenberger's avatar Harald Freudenberger Committed by Vasily Gorbik
Browse files

s390/ap: add card/queue deconfig state



This patch adds a new config state to the ap card and queue
devices. This state reflects the response code
0x03 "AP deconfigured" on TQAP invocation and is tracked with
every ap bus scan.

Together with this new state now a card/queue device which
is 'deconfigured' is not disposed any more. However, for backward
compatibility the online state now needs to take this state into
account. So a card/queue is offline when the device is not configured.
Furthermore a device can't get switched from offline to online state
when not configured.

The config state is shown in sysfs at
  /sys/devices/ap/cardxx/config
for the card and
  /sys/devices/ap/cardxx/xx.yyyy/config
for each queue within each card.
It is a read-only attribute reflecting the negation of the
'AP deconfig' state as it is noted in the AP documents.

Signed-off-by: default avatarHarald Freudenberger <freude@linux.ibm.com>
Signed-off-by: default avatarVasily Gorbik <gor@linux.ibm.com>
parent 2ea2a609
Loading
Loading
Loading
Loading
+246 −118
Original line number Diff line number Diff line
@@ -307,7 +307,7 @@ EXPORT_SYMBOL(ap_test_config_ctrl_domain);
 * false otherwise.
 */
static bool ap_queue_info(ap_qid_t qid, int *q_type,
			  unsigned int *q_fac, int *q_depth)
			  unsigned int *q_fac, int *q_depth, bool *q_decfg)
{
	struct ap_queue_status status;
	unsigned long info = 0;
@@ -322,6 +322,9 @@ static bool ap_queue_info(ap_qid_t qid, int *q_type,
	switch (status.response_code) {
	case AP_RESPONSE_NORMAL:
	case AP_RESPONSE_RESET_IN_PROGRESS:
	case AP_RESPONSE_DECONFIGURED:
	case AP_RESPONSE_CHECKSTOPPED:
	case AP_RESPONSE_BUSY:
		/*
		 * According to the architecture in all these cases the
		 * info should be filled. All bits 0 is not possible as
@@ -332,6 +335,7 @@ static bool ap_queue_info(ap_qid_t qid, int *q_type,
		*q_type = (int)((info >> 24) & 0xff);
		*q_fac = (unsigned int)(info >> 32);
		*q_depth = (int)(info & 0xff);
		*q_decfg = status.response_code == AP_RESPONSE_DECONFIGURED;
		switch (*q_type) {
			/* For CEX2 and CEX3 the available functions
			 * are not reflected by the facilities bits.
@@ -1290,153 +1294,277 @@ static int __match_queue_device_with_queue_id(struct device *dev, const void *da

/*
 * Helper function for ap_scan_bus().
 * Does the scan bus job for the given adapter id.
 * Remove card device and associated queue devices.
 */
static inline void ap_scan_rm_card_dev_and_queue_devs(struct ap_card *ac)
{
	bus_for_each_dev(&ap_bus_type, NULL,
			 (void *)(long) ac->id,
			 __ap_queue_devices_with_id_unregister);
	device_unregister(&ac->ap_dev.device);
}

/*
 * Helper function for ap_scan_bus().
 * Does the scan bus job for all the domains within
 * a valid adapter given by an ap_card ptr.
 */
static void _ap_scan_bus_adapter(int id)
static inline void ap_scan_domains(struct ap_card *ac)
{
	bool broken;
	bool decfg;
	ap_qid_t qid;
	unsigned int func;
	struct ap_card *ac;
	struct device *dev;
	struct ap_queue *aq;
	int rc, dom, depth, type, comp_type;
	int rc, dom, depth, type;

	/*
	 * Go through the configuration for the domains and compare them
	 * to the existing queue devices. Also take care of the config
	 * and error state for the queue devices.
	 */

	/* check if there is a card device registered with this id */
	for (dom = 0; dom <= ap_max_domain_id; dom++) {
		qid = AP_MKQID(ac->id, dom);
		dev = bus_find_device(&ap_bus_type, NULL,
			      (void *)(long) id,
			      __match_card_device_with_id);
	ac = dev ? to_ap_card(dev) : NULL;
	if (!ap_test_config_card_id(id)) {
				      (void *)(long) qid,
				      __match_queue_device_with_qid);
		aq = dev ? to_ap_queue(dev) : NULL;
		if (!ap_test_config_usage_domain(dom)) {
			if (dev) {
			/* Card device has been removed from configuration */
			bus_for_each_dev(&ap_bus_type, NULL,
					 (void *)(long) id,
					 __ap_queue_devices_with_id_unregister);
				AP_DBF_INFO("%s(%d,%d) not in config any more, rm queue device\n",
					    __func__, ac->id, dom);
				device_unregister(dev);
				put_device(dev);
			}
		return;
			continue;
		}

	/*
	 * This card id is enabled in the configuration. If we already have
	 * a card device with this id, check if type and functions are still
	 * the very same. Also verify that at least one queue is available.
	 */
	if (ac) {
		/* find the first valid queue */
		for (dom = 0; dom < AP_DOMAINS; dom++) {
			qid = AP_MKQID(id, dom);
			if (ap_queue_info(qid, &type, &func, &depth))
				break;
		/* domain is valid, get info from this APQN */
		if (!ap_queue_info(qid, &type, &func, &depth, &decfg)) {
			if (aq) {
				AP_DBF_INFO(
					"%s(%d,%d) ap_queue_info() not successful, rm queue device\n",
					__func__, ac->id, dom);
				device_unregister(dev);
				put_device(dev);
			}
		broken = false;
		if (dom >= AP_DOMAINS) {
			/* no accessible queue on this card */
			broken = true;
		} else if (ac->raw_hwtype != type) {
			/* card type has changed */
			AP_DBF_INFO("card=%02x type changed.\n", id);
			broken = true;
		} else if (ac->functions != func) {
			/* card functions have changed */
			AP_DBF_INFO("card=%02x functions changed.\n", id);
			broken = true;
			continue;
		}
		if (broken) {
			/* unregister card device and associated queues */
			bus_for_each_dev(&ap_bus_type, NULL,
					 (void *)(long) id,
					 __ap_queue_devices_with_id_unregister);
			device_unregister(dev);
		/* if no queue device exists, create a new one */
		if (!aq) {
			aq = ap_queue_create(qid, ac->ap_dev.device_type);
			if (!aq) {
				AP_DBF_WARN("%s(%d,%d) ap_queue_create() failed\n",
					    __func__, ac->id, dom);
				continue;
			}
			aq->card = ac;
			aq->config = !decfg;
			dev = &aq->ap_dev.device;
			dev->bus = &ap_bus_type;
			dev->parent = &ac->ap_dev.device;
			dev_set_name(dev, "%02x.%04x", ac->id, dom);
			/* register queue device */
			rc = device_register(dev);
			if (rc) {
				AP_DBF_WARN("%s(%d,%d) device_register() failed\n",
					    __func__, ac->id, dom);
				goto put_dev_and_continue;
			}
			if (decfg)
				AP_DBF_INFO("%s(%d,%d) new (decfg) queue device created\n",
					    __func__, ac->id, dom);
			else
				AP_DBF_INFO("%s(%d,%d) new queue device created\n",
					    __func__, ac->id, dom);
			goto put_dev_and_continue;
		}
		/* Check config state on the already existing queue device */
		spin_lock_bh(&aq->lock);
		if (decfg && aq->config) {
			/* config off this queue device */
			aq->config = false;
			if (aq->dev_state > AP_DEV_STATE_UNINITIATED) {
				aq->dev_state = AP_DEV_STATE_ERROR;
				aq->last_err_rc = AP_RESPONSE_DECONFIGURED;
			}
			spin_unlock_bh(&aq->lock);
			AP_DBF_INFO("%s(%d,%d) queue device config off\n",
				    __func__, ac->id, dom);
			/* 'receive' pending messages with -EAGAIN */
			ap_flush_queue(aq);
			goto put_dev_and_continue;
		}
		if (!decfg && !aq->config) {
			/* config on this queue device */
			aq->config = true;
			if (aq->dev_state > AP_DEV_STATE_UNINITIATED) {
				aq->dev_state = AP_DEV_STATE_OPERATING;
				aq->sm_state = AP_SM_STATE_RESET_START;
			}
			spin_unlock_bh(&aq->lock);
			AP_DBF_INFO("%s(%d,%d) queue device config on\n",
				    __func__, ac->id, dom);
			goto put_dev_and_continue;
		}
		/* handle other error states */
		if (!decfg && aq->dev_state == AP_DEV_STATE_ERROR) {
			spin_unlock_bh(&aq->lock);
			/* 'receive' pending messages with -EAGAIN */
			ap_flush_queue(aq);
			/* re-init (with reset) the queue device */
			ap_queue_init_state(aq);
			AP_DBF_INFO("%s(%d,%d) queue device reinit enforced\n",
				    __func__, ac->id, dom);
			goto put_dev_and_continue;
		}
		spin_unlock_bh(&aq->lock);
put_dev_and_continue:
		put_device(dev);
			/* go back if there is no valid queue on this card */
			if (dom >= AP_DOMAINS)
				return;
			ac = NULL;
	}
}

/*
	 * Go through all possible queue ids. Check and maybe create or release
	 * queue devices for this card. If there exists no card device yet,
	 * create a card device also.
 * Helper function for ap_scan_bus().
 * Does the scan bus job for the given adapter id.
 */
	for (dom = 0; dom < AP_DOMAINS; dom++) {
		qid = AP_MKQID(id, dom);
static inline void ap_scan_adapter(int ap)
{
	bool decfg;
	ap_qid_t qid;
	unsigned int func;
	struct device *dev;
	struct ap_card *ac;
	int rc, dom, depth, type, comp_type;

	/* Is there currently a card device for this adapter ? */
	dev = bus_find_device(&ap_bus_type, NULL,
				      (void *)(long) qid,
				      __match_queue_device_with_qid);
		aq = dev ? to_ap_queue(dev) : NULL;
		if (!ap_test_config_usage_domain(dom)) {
			if (dev) {
				/* Queue device exists but has been
				 * removed from configuration.
			      (void *)(long) ap,
			      __match_card_device_with_id);
	ac = dev ? to_ap_card(dev) : NULL;

	/* Adapter not in configuration ? */
	if (!ap_test_config_card_id(ap)) {
		if (ac) {
			AP_DBF_INFO("%s(%d) ap not in config any more, rm card and queue devices\n",
				    __func__, ap);
			ap_scan_rm_card_dev_and_queue_devs(ac);
			put_device(dev);
		}
		return;
	}

	/*
	 * Adapter ap is valid in the current configuration. So do some checks:
	 * If no card device exists, build one. If a card device exists, check
	 * for type and functions changed. For all this we need to find a valid
	 * APQN first.
	 */
				device_unregister(dev);

	for (dom = 0; dom <= ap_max_domain_id; dom++)
		if (ap_test_config_usage_domain(dom)) {
			qid = AP_MKQID(ap, dom);
			if (ap_queue_info(qid, &type, &func, &depth, &decfg))
				break;
		}
	if (dom > ap_max_domain_id) {
		/* Could not find a valid APQN for this adapter */
		if (ac) {
			AP_DBF_INFO(
				"%s(%d) no type info (no APQN found), rm card and queue devices\n",
				__func__, ap);
			ap_scan_rm_card_dev_and_queue_devs(ac);
			put_device(dev);
		} else {
			AP_DBF_DBG("%s(%d) no type info (no APQN found), ignored\n",
				   __func__, ap);
		}
			continue;
		return;
	}
		/* try to fetch infos about this queue */
		broken = !ap_queue_info(qid, &type, &func, &depth);
		if (dev) {
			if (!broken) {
				spin_lock_bh(&aq->lock);
				broken = aq->dev_state == AP_DEV_STATE_ERROR;
				spin_unlock_bh(&aq->lock);
	if (!type) {
		/* No apdater type info available, an unusable adapter */
		if (ac) {
			AP_DBF_INFO("%s(%d) no valid type (0) info, rm card and queue devices\n",
				    __func__, ap);
			ap_scan_rm_card_dev_and_queue_devs(ac);
			put_device(dev);
		} else {
			AP_DBF_DBG("%s(%d) no valid type (0) info, ignored\n",
				   __func__, ap);
		}
			if (broken) {
				/* Remove broken device */
				AP_DBF_DBG("removing broken queue=%02x.%04x\n",
					   id, dom);
				device_unregister(dev);
		return;
	}

	if (ac) {
		/* Check APQN against existing card device for changes */
		if (ac->raw_hwtype != type) {
			AP_DBF_INFO("%s(%d) hwtype %d changed, rm card and queue devices\n",
				    __func__, ap, type);
			ap_scan_rm_card_dev_and_queue_devs(ac);
			put_device(dev);
			continue;
			ac = NULL;
		} else if (ac->functions != func) {
			AP_DBF_INFO("%s(%d) functions 0x%08x changed, rm card and queue devices\n",
				    __func__, ap, type);
			ap_scan_rm_card_dev_and_queue_devs(ac);
			put_device(dev);
			ac = NULL;
		} else {
			if (decfg && ac->config) {
				ac->config = false;
				AP_DBF_INFO("%s(%d) card device config off\n",
					    __func__, ap);

			}
		if (broken)
			continue;
		/* a new queue device is needed, check out comp type */
			if (!decfg && !ac->config) {
				ac->config = true;
				AP_DBF_INFO("%s(%d) card device config on\n",
					    __func__, ap);
			}
		}
	}

	if (!ac) {
		/* Build a new card device */
		comp_type = ap_get_compatible_type(qid, type, func);
		if (!comp_type)
			continue;
		/* maybe a card device needs to be created first */
		if (!comp_type) {
			AP_DBF_WARN("%s(%d) type %d, can't get compatibility type\n",
				    __func__, ap, type);
			return;
		}
		ac = ap_card_create(ap, depth, type, comp_type, func);
		if (!ac) {
			ac = ap_card_create(id, depth, type, comp_type, func);
			if (!ac)
				continue;
			ac->ap_dev.device.bus = &ap_bus_type;
			ac->ap_dev.device.parent = ap_root_device;
			dev_set_name(&ac->ap_dev.device, "card%02x", id);
			/* Register card device with AP bus */
			rc = device_register(&ac->ap_dev.device);
			AP_DBF_WARN("%s(%d) ap_card_create() failed\n",
				    __func__, ap);
			return;
		}
		ac->config = !decfg;
		dev = &ac->ap_dev.device;
		dev->bus = &ap_bus_type;
		dev->parent = ap_root_device;
		dev_set_name(dev, "card%02x", ap);
		/* Register the new card device with AP bus */
		rc = device_register(dev);
		if (rc) {
				put_device(&ac->ap_dev.device);
				ac = NULL;
				break;
			AP_DBF_WARN("%s(%d) device_register() failed\n",
				    __func__, ap);
			put_device(dev);
			return;
		}
		/* get it and thus adjust reference counter */
			get_device(&ac->ap_dev.device);
		}
		/* now create the new queue device */
		aq = ap_queue_create(qid, comp_type);
		if (!aq)
			continue;
		aq->card = ac;
		aq->ap_dev.device.bus = &ap_bus_type;
		aq->ap_dev.device.parent = &ac->ap_dev.device;
		dev_set_name(&aq->ap_dev.device, "%02x.%04x", id, dom);
		/* Register queue device */
		rc = device_register(&aq->ap_dev.device);
		if (rc) {
			put_device(&aq->ap_dev.device);
			continue;
		get_device(dev);
		if (decfg)
			AP_DBF_INFO("%s(%d) new (decfg) card device type=%d func=0x%08x created\n",
				    __func__, ap, type, func);
		else
			AP_DBF_INFO("%s(%d) new card device type=%d func=0x%08x created\n",
				    __func__, ap, type, func);
	}
	} /* end domain loop */

	if (ac)
	/* Verify the domains and the queue devices for this card */
	ap_scan_domains(ac);

	/* release the card device */
	put_device(&ac->ap_dev.device);
}

@@ -1446,7 +1574,7 @@ static void _ap_scan_bus_adapter(int id)
 */
static void ap_scan_bus(struct work_struct *unused)
{
	int id;
	int ap;

	ap_fetch_qci_info(ap_qci_info);
	ap_select_domain();
@@ -1454,8 +1582,8 @@ static void ap_scan_bus(struct work_struct *unused)
	AP_DBF_DBG("%s running\n", __func__);

	/* loop over all possible adapters */
	for (id = 0; id < AP_DEVICES; id++)
		_ap_scan_bus_adapter(id);
	for (ap = 0; ap <= ap_max_adapter_id; ap++)
		ap_scan_adapter(ap);

	/* check if there is at least one queue available with default domain */
	if (ap_domain_index >= 0) {
+2 −0
Original line number Diff line number Diff line
@@ -166,6 +166,7 @@ struct ap_card {
	unsigned int functions;		/* AP device function bitfield. */
	int queue_depth;		/* AP queue depth.*/
	int id;				/* AP card number. */
	bool config;			/* configured state */
	atomic64_t total_request_count;	/* # requests ever for this AP device.*/
};

@@ -178,6 +179,7 @@ struct ap_queue {
	spinlock_t lock;		/* Per device lock. */
	void *private;			/* ap driver private pointer. */
	enum ap_dev_state dev_state;	/* queue device state */
	bool config;			/* configured state */
	ap_qid_t qid;			/* AP queue id. */
	int interrupt;			/* indicate if interrupts are enabled */
	int queue_count;		/* # messages currently on AP queue. */
+11 −0
Original line number Diff line number Diff line
@@ -139,6 +139,16 @@ static ssize_t modalias_show(struct device *dev,

static DEVICE_ATTR_RO(modalias);

static ssize_t config_show(struct device *dev,
			   struct device_attribute *attr, char *buf)
{
	struct ap_card *ac = to_ap_card(dev);

	return scnprintf(buf, PAGE_SIZE, "%d\n", ac->config ? 1 : 0);
}

static DEVICE_ATTR_RO(config);

static struct attribute *ap_card_dev_attrs[] = {
	&dev_attr_hwtype.attr,
	&dev_attr_raw_hwtype.attr,
@@ -148,6 +158,7 @@ static struct attribute *ap_card_dev_attrs[] = {
	&dev_attr_requestq_count.attr,
	&dev_attr_pendingq_count.attr,
	&dev_attr_modalias.attr,
	&dev_attr_config.attr,
	NULL
};

+15 −0
Original line number Diff line number Diff line
@@ -563,6 +563,20 @@ static ssize_t interrupt_show(struct device *dev,

static DEVICE_ATTR_RO(interrupt);

static ssize_t config_show(struct device *dev,
			     struct device_attribute *attr, char *buf)
{
	struct ap_queue *aq = to_ap_queue(dev);
	int rc;

	spin_lock_bh(&aq->lock);
	rc = scnprintf(buf, PAGE_SIZE, "%d\n", aq->config ? 1 : 0);
	spin_unlock_bh(&aq->lock);
	return rc;
}

static DEVICE_ATTR_RO(config);

#ifdef CONFIG_ZCRYPT_DEBUG
static ssize_t states_show(struct device *dev,
			   struct device_attribute *attr, char *buf)
@@ -676,6 +690,7 @@ static struct attribute *ap_queue_dev_attrs[] = {
	&dev_attr_pendingq_count.attr,
	&dev_attr_reset.attr,
	&dev_attr_interrupt.attr,
	&dev_attr_config.attr,
#ifdef CONFIG_ZCRYPT_DEBUG
	&dev_attr_states.attr,
	&dev_attr_last_err_rc.attr,
+28 −18
Original line number Diff line number Diff line
@@ -663,8 +663,9 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,
	pref_zq = NULL;
	spin_lock(&zcrypt_list_lock);
	for_each_zcrypt_card(zc) {
		/* Check for online accelarator and CCA cards */
		if (!zc->online || !(zc->card->functions & 0x18000000))
		/* Check for useable accelarator or CCA card */
		if (!zc->online || !zc->card->config ||
		    !(zc->card->functions & 0x18000000))
			continue;
		/* Check for size limits */
		if (zc->min_mod_size > mex->inputdatalength ||
@@ -682,8 +683,9 @@ static long zcrypt_rsa_modexpo(struct ap_perms *perms,
		if (!zcrypt_card_compare(zc, pref_zc, wgt + cpen, pref_wgt))
			continue;
		for_each_zcrypt_queue(zq, zc) {
			/* check if device is online and eligible */
			if (!zq->online || !zq->ops->rsa_modexpo)
			/* check if device is useable and eligible */
			if (!zq->online || !zq->ops->rsa_modexpo ||
			    !zq->queue->config)
				continue;
			/* check if device node has admission for this queue */
			if (!zcrypt_check_queue(perms,
@@ -760,8 +762,9 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,
	pref_zq = NULL;
	spin_lock(&zcrypt_list_lock);
	for_each_zcrypt_card(zc) {
		/* Check for online accelarator and CCA cards */
		if (!zc->online || !(zc->card->functions & 0x18000000))
		/* Check for useable accelarator or CCA card */
		if (!zc->online || !zc->card->config ||
		    !(zc->card->functions & 0x18000000))
			continue;
		/* Check for size limits */
		if (zc->min_mod_size > crt->inputdatalength ||
@@ -779,8 +782,9 @@ static long zcrypt_rsa_crt(struct ap_perms *perms,
		if (!zcrypt_card_compare(zc, pref_zc, wgt + cpen, pref_wgt))
			continue;
		for_each_zcrypt_queue(zq, zc) {
			/* check if device is online and eligible */
			if (!zq->online || !zq->ops->rsa_modexpo_crt)
			/* check if device is useable and eligible */
			if (!zq->online || !zq->ops->rsa_modexpo_crt ||
			    !zq->queue->config)
				continue;
			/* check if device node has admission for this queue */
			if (!zcrypt_check_queue(perms,
@@ -859,8 +863,9 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
	pref_zq = NULL;
	spin_lock(&zcrypt_list_lock);
	for_each_zcrypt_card(zc) {
		/* Check for online CCA cards */
		if (!zc->online || !(zc->card->functions & 0x10000000))
		/* Check for useable CCA card */
		if (!zc->online || !zc->card->config ||
		    !(zc->card->functions & 0x10000000))
			continue;
		/* Check for user selected CCA card */
		if (xcRB->user_defined != AUTOSELECT &&
@@ -878,9 +883,10 @@ static long _zcrypt_send_cprb(bool userspace, struct ap_perms *perms,
		if (!zcrypt_card_compare(zc, pref_zc, wgt + cpen, pref_wgt))
			continue;
		for_each_zcrypt_queue(zq, zc) {
			/* check if device is online and eligible */
			/* check for device useable and eligible */
			if (!zq->online ||
			    !zq->ops->send_cprb ||
			    !zq->queue->config ||
			    (tdom != AUTOSEL_DOM &&
			     tdom != AP_QID_QUEUE(zq->queue->qid)))
				continue;
@@ -1012,8 +1018,9 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
	pref_zq = NULL;
	spin_lock(&zcrypt_list_lock);
	for_each_zcrypt_card(zc) {
		/* Check for online EP11 cards */
		if (!zc->online || !(zc->card->functions & 0x04000000))
		/* Check for useable EP11 card */
		if (!zc->online || !zc->card->config ||
		    !(zc->card->functions & 0x04000000))
			continue;
		/* Check for user selected EP11 card */
		if (targets &&
@@ -1031,9 +1038,10 @@ static long _zcrypt_send_ep11_cprb(bool userspace, struct ap_perms *perms,
		if (!zcrypt_card_compare(zc, pref_zc, wgt + cpen, pref_wgt))
			continue;
		for_each_zcrypt_queue(zq, zc) {
			/* check if device is online and eligible */
			/* check if device is useable and eligible */
			if (!zq->online ||
			    !zq->ops->send_ep11_cprb ||
			    !zq->queue->config ||
			    (targets &&
			     !is_desired_ep11_queue(zq->queue->qid,
						    target_num, targets)))
@@ -1110,16 +1118,18 @@ static long zcrypt_rng(char *buffer)
	pref_zq = NULL;
	spin_lock(&zcrypt_list_lock);
	for_each_zcrypt_card(zc) {
		/* Check for online CCA cards */
		if (!zc->online || !(zc->card->functions & 0x10000000))
		/* Check for useable CCA card */
		if (!zc->online || !zc->card->config ||
		    !(zc->card->functions & 0x10000000))
			continue;
		/* get weight index of the card device	*/
		wgt = zc->speed_rating[func_code];
		if (!zcrypt_card_compare(zc, pref_zc, wgt, pref_wgt))
			continue;
		for_each_zcrypt_queue(zq, zc) {
			/* check if device is online and eligible */
			if (!zq->online || !zq->ops->rng)
			/* check if device is useable and eligible */
			if (!zq->online || !zq->ops->rng ||
			    !zq->queue->config)
				continue;
			if (!zcrypt_queue_compare(zq, pref_zq, wgt, pref_wgt))
				continue;
Loading