1c66ac9dbSNicholas Bellinger /*******************************************************************************
2c66ac9dbSNicholas Bellinger  * Filename: target_core_ua.c
3c66ac9dbSNicholas Bellinger  *
4c66ac9dbSNicholas Bellinger  * This file contains logic for SPC-3 Unit Attention emulation
5c66ac9dbSNicholas Bellinger  *
6c66ac9dbSNicholas Bellinger  * Copyright (c) 2009,2010 Rising Tide Systems
7c66ac9dbSNicholas Bellinger  * Copyright (c) 2009,2010 Linux-iSCSI.org
8c66ac9dbSNicholas Bellinger  *
9c66ac9dbSNicholas Bellinger  * Nicholas A. Bellinger <nab@kernel.org>
10c66ac9dbSNicholas Bellinger  *
11c66ac9dbSNicholas Bellinger  * This program is free software; you can redistribute it and/or modify
12c66ac9dbSNicholas Bellinger  * it under the terms of the GNU General Public License as published by
13c66ac9dbSNicholas Bellinger  * the Free Software Foundation; either version 2 of the License, or
14c66ac9dbSNicholas Bellinger  * (at your option) any later version.
15c66ac9dbSNicholas Bellinger  *
16c66ac9dbSNicholas Bellinger  * This program is distributed in the hope that it will be useful,
17c66ac9dbSNicholas Bellinger  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18c66ac9dbSNicholas Bellinger  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19c66ac9dbSNicholas Bellinger  * GNU General Public License for more details.
20c66ac9dbSNicholas Bellinger  *
21c66ac9dbSNicholas Bellinger  * You should have received a copy of the GNU General Public License
22c66ac9dbSNicholas Bellinger  * along with this program; if not, write to the Free Software
23c66ac9dbSNicholas Bellinger  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24c66ac9dbSNicholas Bellinger  *
25c66ac9dbSNicholas Bellinger  ******************************************************************************/
26c66ac9dbSNicholas Bellinger 
27c66ac9dbSNicholas Bellinger #include <linux/version.h>
28c66ac9dbSNicholas Bellinger #include <linux/slab.h>
29c66ac9dbSNicholas Bellinger #include <linux/spinlock.h>
30c66ac9dbSNicholas Bellinger #include <scsi/scsi.h>
31c66ac9dbSNicholas Bellinger #include <scsi/scsi_cmnd.h>
32c66ac9dbSNicholas Bellinger 
33c66ac9dbSNicholas Bellinger #include <target/target_core_base.h>
34c66ac9dbSNicholas Bellinger #include <target/target_core_device.h>
35c66ac9dbSNicholas Bellinger #include <target/target_core_transport.h>
36c66ac9dbSNicholas Bellinger #include <target/target_core_fabric_ops.h>
37c66ac9dbSNicholas Bellinger #include <target/target_core_configfs.h>
38c66ac9dbSNicholas Bellinger 
39c66ac9dbSNicholas Bellinger #include "target_core_alua.h"
40c66ac9dbSNicholas Bellinger #include "target_core_hba.h"
41c66ac9dbSNicholas Bellinger #include "target_core_pr.h"
42c66ac9dbSNicholas Bellinger #include "target_core_ua.h"
43c66ac9dbSNicholas Bellinger 
44c66ac9dbSNicholas Bellinger int core_scsi3_ua_check(
45c66ac9dbSNicholas Bellinger 	struct se_cmd *cmd,
46c66ac9dbSNicholas Bellinger 	unsigned char *cdb)
47c66ac9dbSNicholas Bellinger {
48c66ac9dbSNicholas Bellinger 	struct se_dev_entry *deve;
49c66ac9dbSNicholas Bellinger 	struct se_session *sess = cmd->se_sess;
50c66ac9dbSNicholas Bellinger 	struct se_node_acl *nacl;
51c66ac9dbSNicholas Bellinger 
52c66ac9dbSNicholas Bellinger 	if (!(sess))
53c66ac9dbSNicholas Bellinger 		return 0;
54c66ac9dbSNicholas Bellinger 
55c66ac9dbSNicholas Bellinger 	nacl = sess->se_node_acl;
56c66ac9dbSNicholas Bellinger 	if (!(nacl))
57c66ac9dbSNicholas Bellinger 		return 0;
58c66ac9dbSNicholas Bellinger 
59c66ac9dbSNicholas Bellinger 	deve = &nacl->device_list[cmd->orig_fe_lun];
60c66ac9dbSNicholas Bellinger 	if (!(atomic_read(&deve->ua_count)))
61c66ac9dbSNicholas Bellinger 		return 0;
62c66ac9dbSNicholas Bellinger 	/*
63c66ac9dbSNicholas Bellinger 	 * From sam4r14, section 5.14 Unit attention condition:
64c66ac9dbSNicholas Bellinger 	 *
65c66ac9dbSNicholas Bellinger 	 * a) if an INQUIRY command enters the enabled command state, the
66c66ac9dbSNicholas Bellinger 	 *    device server shall process the INQUIRY command and shall neither
67c66ac9dbSNicholas Bellinger 	 *    report nor clear any unit attention condition;
68c66ac9dbSNicholas Bellinger 	 * b) if a REPORT LUNS command enters the enabled command state, the
69c66ac9dbSNicholas Bellinger 	 *    device server shall process the REPORT LUNS command and shall not
70c66ac9dbSNicholas Bellinger 	 *    report any unit attention condition;
71c66ac9dbSNicholas Bellinger 	 * e) if a REQUEST SENSE command enters the enabled command state while
72c66ac9dbSNicholas Bellinger 	 *    a unit attention condition exists for the SCSI initiator port
73c66ac9dbSNicholas Bellinger 	 *    associated with the I_T nexus on which the REQUEST SENSE command
74c66ac9dbSNicholas Bellinger 	 *    was received, then the device server shall process the command
75c66ac9dbSNicholas Bellinger 	 *    and either:
76c66ac9dbSNicholas Bellinger 	 */
77c66ac9dbSNicholas Bellinger 	switch (cdb[0]) {
78c66ac9dbSNicholas Bellinger 	case INQUIRY:
79c66ac9dbSNicholas Bellinger 	case REPORT_LUNS:
80c66ac9dbSNicholas Bellinger 	case REQUEST_SENSE:
81c66ac9dbSNicholas Bellinger 		return 0;
82c66ac9dbSNicholas Bellinger 	default:
83c66ac9dbSNicholas Bellinger 		return -1;
84c66ac9dbSNicholas Bellinger 	}
85c66ac9dbSNicholas Bellinger 
86c66ac9dbSNicholas Bellinger 	return -1;
87c66ac9dbSNicholas Bellinger }
88c66ac9dbSNicholas Bellinger 
89c66ac9dbSNicholas Bellinger int core_scsi3_ua_allocate(
90c66ac9dbSNicholas Bellinger 	struct se_node_acl *nacl,
91c66ac9dbSNicholas Bellinger 	u32 unpacked_lun,
92c66ac9dbSNicholas Bellinger 	u8 asc,
93c66ac9dbSNicholas Bellinger 	u8 ascq)
94c66ac9dbSNicholas Bellinger {
95c66ac9dbSNicholas Bellinger 	struct se_dev_entry *deve;
96c66ac9dbSNicholas Bellinger 	struct se_ua *ua, *ua_p, *ua_tmp;
97c66ac9dbSNicholas Bellinger 	/*
98c66ac9dbSNicholas Bellinger 	 * PASSTHROUGH OPS
99c66ac9dbSNicholas Bellinger 	 */
100c66ac9dbSNicholas Bellinger 	if (!(nacl))
101c66ac9dbSNicholas Bellinger 		return -1;
102c66ac9dbSNicholas Bellinger 
103c66ac9dbSNicholas Bellinger 	ua = kmem_cache_zalloc(se_ua_cache, GFP_ATOMIC);
104c66ac9dbSNicholas Bellinger 	if (!(ua)) {
105c66ac9dbSNicholas Bellinger 		printk(KERN_ERR "Unable to allocate struct se_ua\n");
106c66ac9dbSNicholas Bellinger 		return -1;
107c66ac9dbSNicholas Bellinger 	}
108c66ac9dbSNicholas Bellinger 	INIT_LIST_HEAD(&ua->ua_dev_list);
109c66ac9dbSNicholas Bellinger 	INIT_LIST_HEAD(&ua->ua_nacl_list);
110c66ac9dbSNicholas Bellinger 
111c66ac9dbSNicholas Bellinger 	ua->ua_nacl = nacl;
112c66ac9dbSNicholas Bellinger 	ua->ua_asc = asc;
113c66ac9dbSNicholas Bellinger 	ua->ua_ascq = ascq;
114c66ac9dbSNicholas Bellinger 
115c66ac9dbSNicholas Bellinger 	spin_lock_irq(&nacl->device_list_lock);
116c66ac9dbSNicholas Bellinger 	deve = &nacl->device_list[unpacked_lun];
117c66ac9dbSNicholas Bellinger 
118c66ac9dbSNicholas Bellinger 	spin_lock(&deve->ua_lock);
119c66ac9dbSNicholas Bellinger 	list_for_each_entry_safe(ua_p, ua_tmp, &deve->ua_list, ua_nacl_list) {
120c66ac9dbSNicholas Bellinger 		/*
121c66ac9dbSNicholas Bellinger 		 * Do not report the same UNIT ATTENTION twice..
122c66ac9dbSNicholas Bellinger 		 */
123c66ac9dbSNicholas Bellinger 		if ((ua_p->ua_asc == asc) && (ua_p->ua_ascq == ascq)) {
124c66ac9dbSNicholas Bellinger 			spin_unlock(&deve->ua_lock);
125c66ac9dbSNicholas Bellinger 			spin_unlock_irq(&nacl->device_list_lock);
126c66ac9dbSNicholas Bellinger 			kmem_cache_free(se_ua_cache, ua);
127c66ac9dbSNicholas Bellinger 			return 0;
128c66ac9dbSNicholas Bellinger 		}
129c66ac9dbSNicholas Bellinger 		/*
130c66ac9dbSNicholas Bellinger 		 * Attach the highest priority Unit Attention to
131c66ac9dbSNicholas Bellinger 		 * the head of the list following sam4r14,
132c66ac9dbSNicholas Bellinger 		 * Section 5.14 Unit Attention Condition:
133c66ac9dbSNicholas Bellinger 		 *
134c66ac9dbSNicholas Bellinger 		 * POWER ON, RESET, OR BUS DEVICE RESET OCCURRED highest
135c66ac9dbSNicholas Bellinger 		 * POWER ON OCCURRED or
136c66ac9dbSNicholas Bellinger 		 * DEVICE INTERNAL RESET
137c66ac9dbSNicholas Bellinger 		 * SCSI BUS RESET OCCURRED or
138c66ac9dbSNicholas Bellinger 		 * MICROCODE HAS BEEN CHANGED or
139c66ac9dbSNicholas Bellinger 		 * protocol specific
140c66ac9dbSNicholas Bellinger 		 * BUS DEVICE RESET FUNCTION OCCURRED
141c66ac9dbSNicholas Bellinger 		 * I_T NEXUS LOSS OCCURRED
142c66ac9dbSNicholas Bellinger 		 * COMMANDS CLEARED BY POWER LOSS NOTIFICATION
143c66ac9dbSNicholas Bellinger 		 * all others                                    Lowest
144c66ac9dbSNicholas Bellinger 		 *
145c66ac9dbSNicholas Bellinger 		 * Each of the ASCQ codes listed above are defined in
146c66ac9dbSNicholas Bellinger 		 * the 29h ASC family, see spc4r17 Table D.1
147c66ac9dbSNicholas Bellinger 		 */
148c66ac9dbSNicholas Bellinger 		if (ua_p->ua_asc == 0x29) {
149c66ac9dbSNicholas Bellinger 			if ((asc == 0x29) && (ascq > ua_p->ua_ascq))
150c66ac9dbSNicholas Bellinger 				list_add(&ua->ua_nacl_list,
151c66ac9dbSNicholas Bellinger 						&deve->ua_list);
152c66ac9dbSNicholas Bellinger 			else
153c66ac9dbSNicholas Bellinger 				list_add_tail(&ua->ua_nacl_list,
154c66ac9dbSNicholas Bellinger 						&deve->ua_list);
155c66ac9dbSNicholas Bellinger 		} else if (ua_p->ua_asc == 0x2a) {
156c66ac9dbSNicholas Bellinger 			/*
157c66ac9dbSNicholas Bellinger 			 * Incoming Family 29h ASCQ codes will override
158c66ac9dbSNicholas Bellinger 			 * Family 2AHh ASCQ codes for Unit Attention condition.
159c66ac9dbSNicholas Bellinger 			 */
160c66ac9dbSNicholas Bellinger 			if ((asc == 0x29) || (ascq > ua_p->ua_asc))
161c66ac9dbSNicholas Bellinger 				list_add(&ua->ua_nacl_list,
162c66ac9dbSNicholas Bellinger 					&deve->ua_list);
163c66ac9dbSNicholas Bellinger 			else
164c66ac9dbSNicholas Bellinger 				list_add_tail(&ua->ua_nacl_list,
165c66ac9dbSNicholas Bellinger 						&deve->ua_list);
166c66ac9dbSNicholas Bellinger 		} else
167c66ac9dbSNicholas Bellinger 			list_add_tail(&ua->ua_nacl_list,
168c66ac9dbSNicholas Bellinger 				&deve->ua_list);
169c66ac9dbSNicholas Bellinger 		spin_unlock(&deve->ua_lock);
170c66ac9dbSNicholas Bellinger 		spin_unlock_irq(&nacl->device_list_lock);
171c66ac9dbSNicholas Bellinger 
172c66ac9dbSNicholas Bellinger 		atomic_inc(&deve->ua_count);
173c66ac9dbSNicholas Bellinger 		smp_mb__after_atomic_inc();
174c66ac9dbSNicholas Bellinger 		return 0;
175c66ac9dbSNicholas Bellinger 	}
176c66ac9dbSNicholas Bellinger 	list_add_tail(&ua->ua_nacl_list, &deve->ua_list);
177c66ac9dbSNicholas Bellinger 	spin_unlock(&deve->ua_lock);
178c66ac9dbSNicholas Bellinger 	spin_unlock_irq(&nacl->device_list_lock);
179c66ac9dbSNicholas Bellinger 
180c66ac9dbSNicholas Bellinger 	printk(KERN_INFO "[%s]: Allocated UNIT ATTENTION, mapped LUN: %u, ASC:"
181c66ac9dbSNicholas Bellinger 		" 0x%02x, ASCQ: 0x%02x\n",
182c66ac9dbSNicholas Bellinger 		TPG_TFO(nacl->se_tpg)->get_fabric_name(), unpacked_lun,
183c66ac9dbSNicholas Bellinger 		asc, ascq);
184c66ac9dbSNicholas Bellinger 
185c66ac9dbSNicholas Bellinger 	atomic_inc(&deve->ua_count);
186c66ac9dbSNicholas Bellinger 	smp_mb__after_atomic_inc();
187c66ac9dbSNicholas Bellinger 	return 0;
188c66ac9dbSNicholas Bellinger }
189c66ac9dbSNicholas Bellinger 
190c66ac9dbSNicholas Bellinger void core_scsi3_ua_release_all(
191c66ac9dbSNicholas Bellinger 	struct se_dev_entry *deve)
192c66ac9dbSNicholas Bellinger {
193c66ac9dbSNicholas Bellinger 	struct se_ua *ua, *ua_p;
194c66ac9dbSNicholas Bellinger 
195c66ac9dbSNicholas Bellinger 	spin_lock(&deve->ua_lock);
196c66ac9dbSNicholas Bellinger 	list_for_each_entry_safe(ua, ua_p, &deve->ua_list, ua_nacl_list) {
197c66ac9dbSNicholas Bellinger 		list_del(&ua->ua_nacl_list);
198c66ac9dbSNicholas Bellinger 		kmem_cache_free(se_ua_cache, ua);
199c66ac9dbSNicholas Bellinger 
200c66ac9dbSNicholas Bellinger 		atomic_dec(&deve->ua_count);
201c66ac9dbSNicholas Bellinger 		smp_mb__after_atomic_dec();
202c66ac9dbSNicholas Bellinger 	}
203c66ac9dbSNicholas Bellinger 	spin_unlock(&deve->ua_lock);
204c66ac9dbSNicholas Bellinger }
205c66ac9dbSNicholas Bellinger 
206c66ac9dbSNicholas Bellinger void core_scsi3_ua_for_check_condition(
207c66ac9dbSNicholas Bellinger 	struct se_cmd *cmd,
208c66ac9dbSNicholas Bellinger 	u8 *asc,
209c66ac9dbSNicholas Bellinger 	u8 *ascq)
210c66ac9dbSNicholas Bellinger {
211c66ac9dbSNicholas Bellinger 	struct se_device *dev = SE_DEV(cmd);
212c66ac9dbSNicholas Bellinger 	struct se_dev_entry *deve;
213c66ac9dbSNicholas Bellinger 	struct se_session *sess = cmd->se_sess;
214c66ac9dbSNicholas Bellinger 	struct se_node_acl *nacl;
215c66ac9dbSNicholas Bellinger 	struct se_ua *ua = NULL, *ua_p;
216c66ac9dbSNicholas Bellinger 	int head = 1;
217c66ac9dbSNicholas Bellinger 
218c66ac9dbSNicholas Bellinger 	if (!(sess))
219c66ac9dbSNicholas Bellinger 		return;
220c66ac9dbSNicholas Bellinger 
221c66ac9dbSNicholas Bellinger 	nacl = sess->se_node_acl;
222c66ac9dbSNicholas Bellinger 	if (!(nacl))
223c66ac9dbSNicholas Bellinger 		return;
224c66ac9dbSNicholas Bellinger 
225c66ac9dbSNicholas Bellinger 	spin_lock_irq(&nacl->device_list_lock);
226c66ac9dbSNicholas Bellinger 	deve = &nacl->device_list[cmd->orig_fe_lun];
227c66ac9dbSNicholas Bellinger 	if (!(atomic_read(&deve->ua_count))) {
228c66ac9dbSNicholas Bellinger 		spin_unlock_irq(&nacl->device_list_lock);
229c66ac9dbSNicholas Bellinger 		return;
230c66ac9dbSNicholas Bellinger 	}
231c66ac9dbSNicholas Bellinger 	/*
232c66ac9dbSNicholas Bellinger 	 * The highest priority Unit Attentions are placed at the head of the
233c66ac9dbSNicholas Bellinger 	 * struct se_dev_entry->ua_list, and will be returned in CHECK_CONDITION +
234c66ac9dbSNicholas Bellinger 	 * sense data for the received CDB.
235c66ac9dbSNicholas Bellinger 	 */
236c66ac9dbSNicholas Bellinger 	spin_lock(&deve->ua_lock);
237c66ac9dbSNicholas Bellinger 	list_for_each_entry_safe(ua, ua_p, &deve->ua_list, ua_nacl_list) {
238c66ac9dbSNicholas Bellinger 		/*
239c66ac9dbSNicholas Bellinger 		 * For ua_intlck_ctrl code not equal to 00b, only report the
240c66ac9dbSNicholas Bellinger 		 * highest priority UNIT_ATTENTION and ASC/ASCQ without
241c66ac9dbSNicholas Bellinger 		 * clearing it.
242c66ac9dbSNicholas Bellinger 		 */
243c66ac9dbSNicholas Bellinger 		if (DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl != 0) {
244c66ac9dbSNicholas Bellinger 			*asc = ua->ua_asc;
245c66ac9dbSNicholas Bellinger 			*ascq = ua->ua_ascq;
246c66ac9dbSNicholas Bellinger 			break;
247c66ac9dbSNicholas Bellinger 		}
248c66ac9dbSNicholas Bellinger 		/*
249c66ac9dbSNicholas Bellinger 		 * Otherwise for the default 00b, release the UNIT ATTENTION
25025985edcSLucas De Marchi 		 * condition.  Return the ASC/ASCQ of the highest priority UA
251c66ac9dbSNicholas Bellinger 		 * (head of the list) in the outgoing CHECK_CONDITION + sense.
252c66ac9dbSNicholas Bellinger 		 */
253c66ac9dbSNicholas Bellinger 		if (head) {
254c66ac9dbSNicholas Bellinger 			*asc = ua->ua_asc;
255c66ac9dbSNicholas Bellinger 			*ascq = ua->ua_ascq;
256c66ac9dbSNicholas Bellinger 			head = 0;
257c66ac9dbSNicholas Bellinger 		}
258c66ac9dbSNicholas Bellinger 		list_del(&ua->ua_nacl_list);
259c66ac9dbSNicholas Bellinger 		kmem_cache_free(se_ua_cache, ua);
260c66ac9dbSNicholas Bellinger 
261c66ac9dbSNicholas Bellinger 		atomic_dec(&deve->ua_count);
262c66ac9dbSNicholas Bellinger 		smp_mb__after_atomic_dec();
263c66ac9dbSNicholas Bellinger 	}
264c66ac9dbSNicholas Bellinger 	spin_unlock(&deve->ua_lock);
265c66ac9dbSNicholas Bellinger 	spin_unlock_irq(&nacl->device_list_lock);
266c66ac9dbSNicholas Bellinger 
267c66ac9dbSNicholas Bellinger 	printk(KERN_INFO "[%s]: %s UNIT ATTENTION condition with"
268c66ac9dbSNicholas Bellinger 		" INTLCK_CTRL: %d, mapped LUN: %u, got CDB: 0x%02x"
269c66ac9dbSNicholas Bellinger 		" reported ASC: 0x%02x, ASCQ: 0x%02x\n",
270c66ac9dbSNicholas Bellinger 		TPG_TFO(nacl->se_tpg)->get_fabric_name(),
271c66ac9dbSNicholas Bellinger 		(DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl != 0) ? "Reporting" :
272c66ac9dbSNicholas Bellinger 		"Releasing", DEV_ATTRIB(dev)->emulate_ua_intlck_ctrl,
273c66ac9dbSNicholas Bellinger 		cmd->orig_fe_lun, T_TASK(cmd)->t_task_cdb[0], *asc, *ascq);
274c66ac9dbSNicholas Bellinger }
275c66ac9dbSNicholas Bellinger 
276c66ac9dbSNicholas Bellinger int core_scsi3_ua_clear_for_request_sense(
277c66ac9dbSNicholas Bellinger 	struct se_cmd *cmd,
278c66ac9dbSNicholas Bellinger 	u8 *asc,
279c66ac9dbSNicholas Bellinger 	u8 *ascq)
280c66ac9dbSNicholas Bellinger {
281c66ac9dbSNicholas Bellinger 	struct se_dev_entry *deve;
282c66ac9dbSNicholas Bellinger 	struct se_session *sess = cmd->se_sess;
283c66ac9dbSNicholas Bellinger 	struct se_node_acl *nacl;
284c66ac9dbSNicholas Bellinger 	struct se_ua *ua = NULL, *ua_p;
285c66ac9dbSNicholas Bellinger 	int head = 1;
286c66ac9dbSNicholas Bellinger 
287c66ac9dbSNicholas Bellinger 	if (!(sess))
288c66ac9dbSNicholas Bellinger 		return -1;
289c66ac9dbSNicholas Bellinger 
290c66ac9dbSNicholas Bellinger 	nacl = sess->se_node_acl;
291c66ac9dbSNicholas Bellinger 	if (!(nacl))
292c66ac9dbSNicholas Bellinger 		return -1;
293c66ac9dbSNicholas Bellinger 
294c66ac9dbSNicholas Bellinger 	spin_lock_irq(&nacl->device_list_lock);
295c66ac9dbSNicholas Bellinger 	deve = &nacl->device_list[cmd->orig_fe_lun];
296c66ac9dbSNicholas Bellinger 	if (!(atomic_read(&deve->ua_count))) {
297c66ac9dbSNicholas Bellinger 		spin_unlock_irq(&nacl->device_list_lock);
298c66ac9dbSNicholas Bellinger 		return -1;
299c66ac9dbSNicholas Bellinger 	}
300c66ac9dbSNicholas Bellinger 	/*
301c66ac9dbSNicholas Bellinger 	 * The highest priority Unit Attentions are placed at the head of the
302c66ac9dbSNicholas Bellinger 	 * struct se_dev_entry->ua_list.  The First (and hence highest priority)
303c66ac9dbSNicholas Bellinger 	 * ASC/ASCQ will be returned in REQUEST_SENSE payload data for the
304c66ac9dbSNicholas Bellinger 	 * matching struct se_lun.
305c66ac9dbSNicholas Bellinger 	 *
306c66ac9dbSNicholas Bellinger 	 * Once the returning ASC/ASCQ values are set, we go ahead and
30725985edcSLucas De Marchi 	 * release all of the Unit Attention conditions for the associated
308c66ac9dbSNicholas Bellinger 	 * struct se_lun.
309c66ac9dbSNicholas Bellinger 	 */
310c66ac9dbSNicholas Bellinger 	spin_lock(&deve->ua_lock);
311c66ac9dbSNicholas Bellinger 	list_for_each_entry_safe(ua, ua_p, &deve->ua_list, ua_nacl_list) {
312c66ac9dbSNicholas Bellinger 		if (head) {
313c66ac9dbSNicholas Bellinger 			*asc = ua->ua_asc;
314c66ac9dbSNicholas Bellinger 			*ascq = ua->ua_ascq;
315c66ac9dbSNicholas Bellinger 			head = 0;
316c66ac9dbSNicholas Bellinger 		}
317c66ac9dbSNicholas Bellinger 		list_del(&ua->ua_nacl_list);
318c66ac9dbSNicholas Bellinger 		kmem_cache_free(se_ua_cache, ua);
319c66ac9dbSNicholas Bellinger 
320c66ac9dbSNicholas Bellinger 		atomic_dec(&deve->ua_count);
321c66ac9dbSNicholas Bellinger 		smp_mb__after_atomic_dec();
322c66ac9dbSNicholas Bellinger 	}
323c66ac9dbSNicholas Bellinger 	spin_unlock(&deve->ua_lock);
324c66ac9dbSNicholas Bellinger 	spin_unlock_irq(&nacl->device_list_lock);
325c66ac9dbSNicholas Bellinger 
326c66ac9dbSNicholas Bellinger 	printk(KERN_INFO "[%s]: Released UNIT ATTENTION condition, mapped"
327c66ac9dbSNicholas Bellinger 		" LUN: %u, got REQUEST_SENSE reported ASC: 0x%02x,"
328c66ac9dbSNicholas Bellinger 		" ASCQ: 0x%02x\n", TPG_TFO(nacl->se_tpg)->get_fabric_name(),
329c66ac9dbSNicholas Bellinger 		cmd->orig_fe_lun, *asc, *ascq);
330c66ac9dbSNicholas Bellinger 
331c66ac9dbSNicholas Bellinger 	return (head) ? -1 : 0;
332c66ac9dbSNicholas Bellinger }
333