xref: /titanic_52/usr/src/uts/common/io/cpqary3/cpqary3_noe.c (revision 80c94ecd7a524eb933a4bb221a9618b9dc490e76)
1*80c94ecdSKeith M Wesolowski /*
2*80c94ecdSKeith M Wesolowski  * This file and its contents are supplied under the terms of the
3*80c94ecdSKeith M Wesolowski  * Common Development and Distribution License ("CDDL"), version 1.0.
4*80c94ecdSKeith M Wesolowski  * You may only use this file in accordance with the terms of version
5*80c94ecdSKeith M Wesolowski  * 1.0 of the CDDL.
6*80c94ecdSKeith M Wesolowski  *
7*80c94ecdSKeith M Wesolowski  * A full copy of the text of the CDDL should have accompanied this
8*80c94ecdSKeith M Wesolowski  * source.  A copy of the CDDL is also available via the Internet at
9*80c94ecdSKeith M Wesolowski  * http://www.illumos.org/license/CDDL.
10*80c94ecdSKeith M Wesolowski  */
11*80c94ecdSKeith M Wesolowski 
12*80c94ecdSKeith M Wesolowski /*
13*80c94ecdSKeith M Wesolowski  * Copyright (C) 2013 Hewlett-Packard Development Company, L.P.
14*80c94ecdSKeith M Wesolowski  */
15*80c94ecdSKeith M Wesolowski 
16*80c94ecdSKeith M Wesolowski /*
17*80c94ecdSKeith M Wesolowski  * This  File  has  Modules  that  handle  the NOE  functionality  for
18*80c94ecdSKeith M Wesolowski  *	this driver.
19*80c94ecdSKeith M Wesolowski  *	It  builds and  submits  the NOE  command to  the adapter.  It also
20*80c94ecdSKeith M Wesolowski  *	processes a completed NOE command.
21*80c94ecdSKeith M Wesolowski  *	A study of the FirmWare specifications would be neccessary to relate
22*80c94ecdSKeith M Wesolowski  *	coding in this module to the hardware functionality.
23*80c94ecdSKeith M Wesolowski  */
24*80c94ecdSKeith M Wesolowski 
25*80c94ecdSKeith M Wesolowski #include "cpqary3.h"
26*80c94ecdSKeith M Wesolowski 
27*80c94ecdSKeith M Wesolowski /*
28*80c94ecdSKeith M Wesolowski  * Local Functions Definitions
29*80c94ecdSKeith M Wesolowski  */
30*80c94ecdSKeith M Wesolowski 
31*80c94ecdSKeith M Wesolowski uint8_t cpqary3_disable_NOE_command(cpqary3_t *);
32*80c94ecdSKeith M Wesolowski 
33*80c94ecdSKeith M Wesolowski /*
34*80c94ecdSKeith M Wesolowski  * Last reason a drive at this position was failed by the
35*80c94ecdSKeith M Wesolowski  * controller firmware (saved in the RIS).
36*80c94ecdSKeith M Wesolowski  */
37*80c94ecdSKeith M Wesolowski 
38*80c94ecdSKeith M Wesolowski #define	MAX_KNOWN_FAILURE_REASON	31
39*80c94ecdSKeith M Wesolowski 
40*80c94ecdSKeith M Wesolowski char *ascii_failure_reason[] = {
41*80c94ecdSKeith M Wesolowski 	"NONE",
42*80c94ecdSKeith M Wesolowski 	"TOO_SMALL_IN_LOAD_CONFIG",
43*80c94ecdSKeith M Wesolowski 	"ERROR_ERASING_RIS",
44*80c94ecdSKeith M Wesolowski 	"ERROR_SAVING_RIS",
45*80c94ecdSKeith M Wesolowski 	"FAIL_DRIVE_COMMAND",
46*80c94ecdSKeith M Wesolowski 	"MARK_BAD_FAILED",
47*80c94ecdSKeith M Wesolowski 	"MARK_BAD_FAILED_IN_FINISH_REMAP",
48*80c94ecdSKeith M Wesolowski 	"TIMEOUT",
49*80c94ecdSKeith M Wesolowski 	"AUTOSENSE_FAILED",
50*80c94ecdSKeith M Wesolowski 	"MEDIUM_ERROR_1",
51*80c94ecdSKeith M Wesolowski 	"MEDIUM_ERROR_2",
52*80c94ecdSKeith M Wesolowski 	"NOT_READY_BAD_SENSE",
53*80c94ecdSKeith M Wesolowski 	"NOT_READY",
54*80c94ecdSKeith M Wesolowski 	"HARDWARE_ERROR",
55*80c94ecdSKeith M Wesolowski 	"ABORTED_COMMAND",
56*80c94ecdSKeith M Wesolowski 	"WRITE_PROTECTED",
57*80c94ecdSKeith M Wesolowski 	"SPIN_UP_FAILURE_IN_RECOVER",
58*80c94ecdSKeith M Wesolowski 	"REBUILD_WRITE_ERROR",
59*80c94ecdSKeith M Wesolowski 	"TOO_SMALL_IN_HOT_PLUG",
60*80c94ecdSKeith M Wesolowski 	"RESET_RECOVERY_ABORT",
61*80c94ecdSKeith M Wesolowski 	"REMOVED_IN_HOT_PLUG",
62*80c94ecdSKeith M Wesolowski 	"INIT_REQUEST_SENSE_FAILED",
63*80c94ecdSKeith M Wesolowski 	"INIT_START_UNIT_FAILED",
64*80c94ecdSKeith M Wesolowski 	"GDP_INQUIRY_FAILED",
65*80c94ecdSKeith M Wesolowski 	"GDP_NON_DISK_DEVICE",
66*80c94ecdSKeith M Wesolowski 	"GDP_READ_CAPACITY_FAILED",
67*80c94ecdSKeith M Wesolowski 	"GDP_INVALID_BLOCK_SIZE",
68*80c94ecdSKeith M Wesolowski 	"HOTP_REQUEST_SENSE_FAILED",
69*80c94ecdSKeith M Wesolowski 	"HOTP_START_UNIT_FAILED",
70*80c94ecdSKeith M Wesolowski 	"WRITE_ERROR_AFTER_REMAP",
71*80c94ecdSKeith M Wesolowski 	"INIT_RESET_RECOVERY_ABORTED"
72*80c94ecdSKeith M Wesolowski };
73*80c94ecdSKeith M Wesolowski 
74*80c94ecdSKeith M Wesolowski /*
75*80c94ecdSKeith M Wesolowski  * All Possible Logical Volume Status
76*80c94ecdSKeith M Wesolowski  */
77*80c94ecdSKeith M Wesolowski 
78*80c94ecdSKeith M Wesolowski char *log_vol_status[] = {
79*80c94ecdSKeith M Wesolowski 	"OK",
80*80c94ecdSKeith M Wesolowski 	"Failed",
81*80c94ecdSKeith M Wesolowski 	"Not Configured",
82*80c94ecdSKeith M Wesolowski 	"Regenerating",
83*80c94ecdSKeith M Wesolowski 	"Needs Rebuild Permission",
84*80c94ecdSKeith M Wesolowski 	"Rebuilding",
85*80c94ecdSKeith M Wesolowski 	"Wrong Drive Replaced",
86*80c94ecdSKeith M Wesolowski 	"Bad Drive Connection",
87*80c94ecdSKeith M Wesolowski 	"Box Overheating",
88*80c94ecdSKeith M Wesolowski 	"Box Overheated",
89*80c94ecdSKeith M Wesolowski 	"Volume Expanding",
90*80c94ecdSKeith M Wesolowski 	"Not Yet Available",
91*80c94ecdSKeith M Wesolowski 	"Volume Needs to Expand",
92*80c94ecdSKeith M Wesolowski 	"Unknown"
93*80c94ecdSKeith M Wesolowski };
94*80c94ecdSKeith M Wesolowski 
95*80c94ecdSKeith M Wesolowski /*
96*80c94ecdSKeith M Wesolowski  * Function	: 	cpqary3_send_NOE_command
97*80c94ecdSKeith M Wesolowski  * Description	: 	This routine builds and submits the NOE Command
98*80c94ecdSKeith M Wesolowski  *  			to the Controller.
99*80c94ecdSKeith M Wesolowski  * Called By	:   	cpqary3_attach(), cpqary3_NOE_handler()
100*80c94ecdSKeith M Wesolowski  * Parameters	: 	per-controller, per-command,
101*80c94ecdSKeith M Wesolowski  *  			Flag to signify first time or otherwise
102*80c94ecdSKeith M Wesolowski  * Calls	:   	cpqary3_alloc_phyctgs_mem(), cpqary3_cmdlist_occupy(),
103*80c94ecdSKeith M Wesolowski  *			cpqary3_submit(), cpqary3_add2submitted_cmdq(),
104*80c94ecdSKeith M Wesolowski  *			cpqary3_free_phyctgs_mem()
105*80c94ecdSKeith M Wesolowski  * Return Values: 	SUCCESS / FAILURE
106*80c94ecdSKeith M Wesolowski  *			[Shall fail only if memory allocation issues exist]
107*80c94ecdSKeith M Wesolowski  */
108*80c94ecdSKeith M Wesolowski uint8_t
109*80c94ecdSKeith M Wesolowski cpqary3_send_NOE_command(cpqary3_t *ctlr, cpqary3_cmdpvt_t *memp, uint8_t flag)
110*80c94ecdSKeith M Wesolowski {
111*80c94ecdSKeith M Wesolowski 	uint32_t		phys_addr = 0;
112*80c94ecdSKeith M Wesolowski 	NoeBuffer 		*databuf;
113*80c94ecdSKeith M Wesolowski 	CommandList_t		*cmdlist;
114*80c94ecdSKeith M Wesolowski 	cpqary3_phyctg_t	*phys_handle;
115*80c94ecdSKeith M Wesolowski 	int			rv;
116*80c94ecdSKeith M Wesolowski 
117*80c94ecdSKeith M Wesolowski 	/*
118*80c94ecdSKeith M Wesolowski 	 * NOTE : DO NOT perform this operation for memp. Shall result in a
119*80c94ecdSKeith M Wesolowski 	 * failure of submission of the NOE command as it shall be NULL for
120*80c94ecdSKeith M Wesolowski 	 * the very first time
121*80c94ecdSKeith M Wesolowski 	 */
122*80c94ecdSKeith M Wesolowski 	RETURN_FAILURE_IF_NULL(ctlr);
123*80c94ecdSKeith M Wesolowski 
124*80c94ecdSKeith M Wesolowski 	/*
125*80c94ecdSKeith M Wesolowski 	 * Allocate Memory for Return data
126*80c94ecdSKeith M Wesolowski 	 * if failure, RETURN.
127*80c94ecdSKeith M Wesolowski 	 * Allocate Memory for CommandList
128*80c94ecdSKeith M Wesolowski 	 * If error, RETURN.
129*80c94ecdSKeith M Wesolowski 	 * get the Request Block from the CommandList
130*80c94ecdSKeith M Wesolowski 	 * Fill in the Request Packet with the corresponding values
131*80c94ecdSKeith M Wesolowski 	 * Special Information can be filled in the "bno" field of
132*80c94ecdSKeith M Wesolowski 	 * the request structure.
133*80c94ecdSKeith M Wesolowski 	 * Here, the "bno" field is filled for Asynchronous Mode.
134*80c94ecdSKeith M Wesolowski 	 * Submit the Command.
135*80c94ecdSKeith M Wesolowski 	 * If Failure, WARN and RETURN.
136*80c94ecdSKeith M Wesolowski 	 */
137*80c94ecdSKeith M Wesolowski 	if (CPQARY3_NOE_RESUBMIT == flag) {
138*80c94ecdSKeith M Wesolowski 		if ((NULL == memp) || (NULL == memp->cmdlist_memaddr)) {
139*80c94ecdSKeith M Wesolowski 			cmn_err(CE_WARN, " CPQary3 : _send_NOE_command : "
140*80c94ecdSKeith M Wesolowski 			    "Re-Use Not possible; CommandList NULL");
141*80c94ecdSKeith M Wesolowski 			return (CPQARY3_FAILURE);
142*80c94ecdSKeith M Wesolowski 		}
143*80c94ecdSKeith M Wesolowski 
144*80c94ecdSKeith M Wesolowski 		bzero(MEM2DRVPVT(memp)->sg, sizeof (NoeBuffer));
145*80c94ecdSKeith M Wesolowski 		memp->cmdlist_memaddr->Header.Tag.drvinfo_n_err =
146*80c94ecdSKeith M Wesolowski 		    CPQARY3_NOECMD_SUCCESS;
147*80c94ecdSKeith M Wesolowski 	} else if (CPQARY3_NOE_INIT == flag) {
148*80c94ecdSKeith M Wesolowski 		phys_handle =
149*80c94ecdSKeith M Wesolowski 		    (cpqary3_phyctg_t *)MEM_ZALLOC(sizeof (cpqary3_phyctg_t));
150*80c94ecdSKeith M Wesolowski 		if (!phys_handle)
151*80c94ecdSKeith M Wesolowski 			return (CPQARY3_FAILURE);
152*80c94ecdSKeith M Wesolowski 
153*80c94ecdSKeith M Wesolowski 		databuf = (NoeBuffer *)cpqary3_alloc_phyctgs_mem(ctlr,
154*80c94ecdSKeith M Wesolowski 		    sizeof (NoeBuffer), &phys_addr, phys_handle);
155*80c94ecdSKeith M Wesolowski 		if (!databuf) {
156*80c94ecdSKeith M Wesolowski 			return (CPQARY3_FAILURE);
157*80c94ecdSKeith M Wesolowski 		}
158*80c94ecdSKeith M Wesolowski 		bzero(databuf, sizeof (NoeBuffer));
159*80c94ecdSKeith M Wesolowski 
160*80c94ecdSKeith M Wesolowski 		if (NULL == (memp = cpqary3_cmdlist_occupy(ctlr))) {
161*80c94ecdSKeith M Wesolowski 			cpqary3_free_phyctgs_mem(phys_handle,
162*80c94ecdSKeith M Wesolowski 			    CPQARY3_FREE_PHYCTG_MEM);
163*80c94ecdSKeith M Wesolowski 			return (CPQARY3_FAILURE);
164*80c94ecdSKeith M Wesolowski 		}
165*80c94ecdSKeith M Wesolowski 
166*80c94ecdSKeith M Wesolowski 		memp->driverdata = (cpqary3_private_t *)
167*80c94ecdSKeith M Wesolowski 		    MEM_ZALLOC(sizeof (cpqary3_private_t));
168*80c94ecdSKeith M Wesolowski 		if (NULL == memp->driverdata) {
169*80c94ecdSKeith M Wesolowski 			cpqary3_free_phyctgs_mem(phys_handle,
170*80c94ecdSKeith M Wesolowski 			    CPQARY3_FREE_PHYCTG_MEM);
171*80c94ecdSKeith M Wesolowski 			cpqary3_cmdlist_release(memp, CPQARY3_HOLD_SW_MUTEX);
172*80c94ecdSKeith M Wesolowski 			return (CPQARY3_FAILURE);
173*80c94ecdSKeith M Wesolowski 		}
174*80c94ecdSKeith M Wesolowski 		memp->driverdata->sg = databuf;
175*80c94ecdSKeith M Wesolowski 		memp->driverdata->phyctgp = phys_handle;
176*80c94ecdSKeith M Wesolowski 
177*80c94ecdSKeith M Wesolowski 		cmdlist = memp->cmdlist_memaddr;
178*80c94ecdSKeith M Wesolowski 		cmdlist->Header.SGTotal = 1;
179*80c94ecdSKeith M Wesolowski 		cmdlist->Header.SGList = 1;
180*80c94ecdSKeith M Wesolowski 		cmdlist->Header.Tag.drvinfo_n_err = CPQARY3_NOECMD_SUCCESS;
181*80c94ecdSKeith M Wesolowski 		cmdlist->Header.LUN.PhysDev.Mode = PERIPHERIAL_DEV_ADDR;
182*80c94ecdSKeith M Wesolowski 
183*80c94ecdSKeith M Wesolowski 		cmdlist->Request.CDBLen = CISS_NOE_CDB_LEN;
184*80c94ecdSKeith M Wesolowski 		cmdlist->Request.Timeout = 0;
185*80c94ecdSKeith M Wesolowski 		cmdlist->Request.Type.Type = CISS_TYPE_CMD;
186*80c94ecdSKeith M Wesolowski 		cmdlist->Request.Type.Attribute = CISS_ATTR_HEADOFQUEUE;
187*80c94ecdSKeith M Wesolowski 		cmdlist->Request.Type.Direction = CISS_XFER_READ;
188*80c94ecdSKeith M Wesolowski 		cmdlist->Request.CDB[0] = CISS_NEW_READ;
189*80c94ecdSKeith M Wesolowski 		cmdlist->Request.CDB[1] = BMIC_NOTIFY_ON_EVENT;
190*80c94ecdSKeith M Wesolowski 		cmdlist->Request.CDB[10] = (NOE_BUFFER_LENGTH >> 8) & 0xff;
191*80c94ecdSKeith M Wesolowski 		cmdlist->Request.CDB[11] = NOE_BUFFER_LENGTH & 0xff;
192*80c94ecdSKeith M Wesolowski 
193*80c94ecdSKeith M Wesolowski 		cmdlist->SG[0].Addr = phys_addr;
194*80c94ecdSKeith M Wesolowski 		cmdlist->SG[0].Len = NOE_BUFFER_LENGTH;
195*80c94ecdSKeith M Wesolowski 	}
196*80c94ecdSKeith M Wesolowski 
197*80c94ecdSKeith M Wesolowski 	/* PERF */
198*80c94ecdSKeith M Wesolowski 
199*80c94ecdSKeith M Wesolowski 	memp->complete = cpqary3_noe_complete;
200*80c94ecdSKeith M Wesolowski 
201*80c94ecdSKeith M Wesolowski 	mutex_enter(&ctlr->hw_mutex);
202*80c94ecdSKeith M Wesolowski 	rv = cpqary3_submit(ctlr, memp->cmdlist_phyaddr);
203*80c94ecdSKeith M Wesolowski 	mutex_exit(&ctlr->hw_mutex);
204*80c94ecdSKeith M Wesolowski 
205*80c94ecdSKeith M Wesolowski 	if (rv != 0)
206*80c94ecdSKeith M Wesolowski 		return (CPQARY3_FAILURE);
207*80c94ecdSKeith M Wesolowski 
208*80c94ecdSKeith M Wesolowski 	/* PERF */
209*80c94ecdSKeith M Wesolowski 	return (CPQARY3_SUCCESS);
210*80c94ecdSKeith M Wesolowski }
211*80c94ecdSKeith M Wesolowski 
212*80c94ecdSKeith M Wesolowski /*
213*80c94ecdSKeith M Wesolowski  * Function	: 	cpqary3_disable_NOE_command
214*80c94ecdSKeith M Wesolowski  * Description	: 	This routine disables the Event Notifier
215*80c94ecdSKeith M Wesolowski  *			for the specified Controller.
216*80c94ecdSKeith M Wesolowski  * Called By	: 	cpqary3_cleanup()
217*80c94ecdSKeith M Wesolowski  * Parameters	: 	Per Controller Structure
218*80c94ecdSKeith M Wesolowski  * Calls	:   	cpqary3_cmdlist_occupy(), cpqary3_submit(),
219*80c94ecdSKeith M Wesolowski  *			cpqary3_add2submitted_cmdq()
220*80c94ecdSKeith M Wesolowski  * Return Values: 	SUCCESS / FAILURE
221*80c94ecdSKeith M Wesolowski  *			[Shall fail only if Memory Constraints exist]
222*80c94ecdSKeith M Wesolowski  */
223*80c94ecdSKeith M Wesolowski uint8_t
224*80c94ecdSKeith M Wesolowski cpqary3_disable_NOE_command(cpqary3_t *ctlr)
225*80c94ecdSKeith M Wesolowski {
226*80c94ecdSKeith M Wesolowski 	CommandList_t		*cmdlist;
227*80c94ecdSKeith M Wesolowski 	cpqary3_cmdpvt_t	*memp;
228*80c94ecdSKeith M Wesolowski 	int			rv;
229*80c94ecdSKeith M Wesolowski 
230*80c94ecdSKeith M Wesolowski 	RETURN_FAILURE_IF_NULL(ctlr);
231*80c94ecdSKeith M Wesolowski 
232*80c94ecdSKeith M Wesolowski 	/*
233*80c94ecdSKeith M Wesolowski 	 * Allocate Memory for CommandList
234*80c94ecdSKeith M Wesolowski 	 * If error, RETURN.
235*80c94ecdSKeith M Wesolowski 	 * get the Request Block from the CommandList
236*80c94ecdSKeith M Wesolowski 	 * Fill in the Request Packet with the corresponding values
237*80c94ecdSKeith M Wesolowski 	 * Submit the Command.
238*80c94ecdSKeith M Wesolowski 	 * If Failure, WARN and RETURN.
239*80c94ecdSKeith M Wesolowski 	 */
240*80c94ecdSKeith M Wesolowski 
241*80c94ecdSKeith M Wesolowski 	if (NULL == (memp = cpqary3_cmdlist_occupy(ctlr))) {
242*80c94ecdSKeith M Wesolowski 		cmn_err(CE_WARN, "CPQary3 : _disable_NOE_command : Failed");
243*80c94ecdSKeith M Wesolowski 		return (CPQARY3_FAILURE);
244*80c94ecdSKeith M Wesolowski 	}
245*80c94ecdSKeith M Wesolowski 
246*80c94ecdSKeith M Wesolowski 	cmdlist = memp->cmdlist_memaddr;
247*80c94ecdSKeith M Wesolowski 	cmdlist->Header.Tag.drvinfo_n_err = CPQARY3_NOECMD_SUCCESS;
248*80c94ecdSKeith M Wesolowski 	cmdlist->Header.LUN.PhysDev.Mode = PERIPHERIAL_DEV_ADDR;
249*80c94ecdSKeith M Wesolowski 
250*80c94ecdSKeith M Wesolowski 	cmdlist->Request.CDBLen = CISS_CANCEL_NOE_CDB_LEN;
251*80c94ecdSKeith M Wesolowski 	cmdlist->Request.Timeout = 0;
252*80c94ecdSKeith M Wesolowski 	cmdlist->Request.Type.Type = CISS_TYPE_CMD;
253*80c94ecdSKeith M Wesolowski 	cmdlist->Request.Type.Attribute = CISS_ATTR_HEADOFQUEUE;
254*80c94ecdSKeith M Wesolowski 	cmdlist->Request.Type.Direction = CISS_XFER_NONE;
255*80c94ecdSKeith M Wesolowski 	cmdlist->Request.CDB[0] = ARRAY_WRITE;	/* 0x27 */
256*80c94ecdSKeith M Wesolowski 	cmdlist->Request.CDB[6] = BMIC_CANCEL_NOTIFY_ON_EVENT;
257*80c94ecdSKeith M Wesolowski 
258*80c94ecdSKeith M Wesolowski 	/* PERF */
259*80c94ecdSKeith M Wesolowski 
260*80c94ecdSKeith M Wesolowski 	memp->complete = cpqary3_noe_complete;
261*80c94ecdSKeith M Wesolowski 
262*80c94ecdSKeith M Wesolowski 	mutex_enter(&ctlr->hw_mutex);
263*80c94ecdSKeith M Wesolowski 	rv = cpqary3_submit(ctlr, memp->cmdlist_phyaddr);
264*80c94ecdSKeith M Wesolowski 	mutex_exit(&ctlr->hw_mutex);
265*80c94ecdSKeith M Wesolowski 
266*80c94ecdSKeith M Wesolowski 	if (rv != 0)
267*80c94ecdSKeith M Wesolowski 		return (CPQARY3_FAILURE);
268*80c94ecdSKeith M Wesolowski 
269*80c94ecdSKeith M Wesolowski 	/* PERF */
270*80c94ecdSKeith M Wesolowski 	return (CPQARY3_SUCCESS);
271*80c94ecdSKeith M Wesolowski }
272*80c94ecdSKeith M Wesolowski 
273*80c94ecdSKeith M Wesolowski /*
274*80c94ecdSKeith M Wesolowski  * Function	: 	cpqary3_NOE_handler
275*80c94ecdSKeith M Wesolowski  * Description	: 	This routine handles all those NOEs tabulated at the
276*80c94ecdSKeith M Wesolowski  *			begining of this code.
277*80c94ecdSKeith M Wesolowski  * Called By	: 	cpqary3_process_pkt()
278*80c94ecdSKeith M Wesolowski  * Parameters	: 	Pointer to the Command List
279*80c94ecdSKeith M Wesolowski  * Calls	:   	cpqary3_send_NOE_command(),
280*80c94ecdSKeith M Wesolowski  *			cpqary3_display_spare_status()
281*80c94ecdSKeith M Wesolowski  *			cpqary3_free_phyctgs_mem(), cpqary3_cmdlist_release()
282*80c94ecdSKeith M Wesolowski  * Return Values: 	None
283*80c94ecdSKeith M Wesolowski  */
284*80c94ecdSKeith M Wesolowski void
285*80c94ecdSKeith M Wesolowski cpqary3_NOE_handler(cpqary3_cmdpvt_t *memp)
286*80c94ecdSKeith M Wesolowski {
287*80c94ecdSKeith M Wesolowski 	uint16_t		drive = 0;
288*80c94ecdSKeith M Wesolowski 	NoeBuffer 		*evt;
289*80c94ecdSKeith M Wesolowski 	cpqary3_t		*ctlr;
290*80c94ecdSKeith M Wesolowski 	cpqary3_phyctg_t	*phys_handle;
291*80c94ecdSKeith M Wesolowski 	uint8_t			driveId = 0;
292*80c94ecdSKeith M Wesolowski 
293*80c94ecdSKeith M Wesolowski 	/*
294*80c94ecdSKeith M Wesolowski 	 * This should never happen....
295*80c94ecdSKeith M Wesolowski 	 * If the pointer passed as argument is NULL, Panic the System.
296*80c94ecdSKeith M Wesolowski 	 */
297*80c94ecdSKeith M Wesolowski 	VERIFY(memp != NULL);
298*80c94ecdSKeith M Wesolowski 
299*80c94ecdSKeith M Wesolowski 	evt = (NoeBuffer *)MEM2DRVPVT(memp)->sg;
300*80c94ecdSKeith M Wesolowski 	ctlr = (cpqary3_t *)memp->ctlr;
301*80c94ecdSKeith M Wesolowski 	phys_handle = (cpqary3_phyctg_t *)MEM2DRVPVT(memp)->phyctgp;
302*80c94ecdSKeith M Wesolowski 
303*80c94ecdSKeith M Wesolowski 	/* Don't display more than 79 characters */
304*80c94ecdSKeith M Wesolowski 	evt->ascii_message[79] = 0;
305*80c94ecdSKeith M Wesolowski 
306*80c94ecdSKeith M Wesolowski 
307*80c94ecdSKeith M Wesolowski 	switch (evt->event_class_code) {
308*80c94ecdSKeith M Wesolowski 	case CLASS_PROTOCOL:
309*80c94ecdSKeith M Wesolowski 		/*
310*80c94ecdSKeith M Wesolowski 		 * the following cases are not handled:
311*80c94ecdSKeith M Wesolowski 		 * 000 	: This is for Synchronous NOE.
312*80c94ecdSKeith M Wesolowski 		 *	  CPQary3 follows asynchronous NOE.
313*80c94ecdSKeith M Wesolowski 		 * 002	: Asynchronous NOE time out.
314*80c94ecdSKeith M Wesolowski 		 *	  CPQary3 does not implement time
315*80c94ecdSKeith M Wesolowski 		 *	  outs for NOE. It shall always reside in the HBA.
316*80c94ecdSKeith M Wesolowski 		 */
317*80c94ecdSKeith M Wesolowski 
318*80c94ecdSKeith M Wesolowski 		cmn_err(CE_NOTE, " %s", ctlr->hba_name);
319*80c94ecdSKeith M Wesolowski 		if ((evt->event_subclass_code == SUB_CLASS_NON_EVENT) &&
320*80c94ecdSKeith M Wesolowski 		    (evt->event_detail_code == DETAIL_DISABLED)) {
321*80c94ecdSKeith M Wesolowski 			cmn_err(CE_CONT, " %s", ctlr->hba_name);
322*80c94ecdSKeith M Wesolowski 			cmn_err(CE_CONT,
323*80c94ecdSKeith M Wesolowski 			    "CPQary3 : Event Notifier Disabled \n");
324*80c94ecdSKeith M Wesolowski 			MEM_SFREE(memp->driverdata, sizeof (cpqary3_private_t));
325*80c94ecdSKeith M Wesolowski 			cpqary3_free_phyctgs_mem(phys_handle,
326*80c94ecdSKeith M Wesolowski 			    CPQARY3_FREE_PHYCTG_MEM);
327*80c94ecdSKeith M Wesolowski 			cpqary3_cmdlist_release(memp, CPQARY3_NO_MUTEX);
328*80c94ecdSKeith M Wesolowski 			return;
329*80c94ecdSKeith M Wesolowski 		} else if ((evt->event_subclass_code ==
330*80c94ecdSKeith M Wesolowski 		    SUB_CLASS_PROTOCOL_ERR) &&
331*80c94ecdSKeith M Wesolowski 		    (evt->event_detail_code == DETAIL_EVENT_Q_OVERFLOW)) {
332*80c94ecdSKeith M Wesolowski 			cmn_err(CE_CONT, " %s\n", evt->ascii_message);
333*80c94ecdSKeith M Wesolowski 		}
334*80c94ecdSKeith M Wesolowski 		cmn_err(CE_CONT, "\n");
335*80c94ecdSKeith M Wesolowski 		break;
336*80c94ecdSKeith M Wesolowski 
337*80c94ecdSKeith M Wesolowski 	case CLASS_HOT_PLUG:
338*80c94ecdSKeith M Wesolowski 		if (evt->event_subclass_code == SUB_CLASS_HP_CHANGE) {
339*80c94ecdSKeith M Wesolowski 			cmn_err(CE_NOTE, " %s", ctlr->hba_name);
340*80c94ecdSKeith M Wesolowski 			cmn_err(CE_CONT, " %s\n", evt->ascii_message);
341*80c94ecdSKeith M Wesolowski 
342*80c94ecdSKeith M Wesolowski 			/*
343*80c94ecdSKeith M Wesolowski 			 * Fix for QUIX 1000440284: Display the Physical
344*80c94ecdSKeith M Wesolowski 			 * Drive Num info only for CISS Controllers
345*80c94ecdSKeith M Wesolowski 			 */
346*80c94ecdSKeith M Wesolowski 
347*80c94ecdSKeith M Wesolowski 			if (!(ctlr->bddef->bd_flags & SA_BD_SAS)) {
348*80c94ecdSKeith M Wesolowski 				driveId =
349*80c94ecdSKeith M Wesolowski 				    /* LINTED: alignment */
350*80c94ecdSKeith M Wesolowski 				    *(uint16_t *)(&evt->event_specific_data[0]);
351*80c94ecdSKeith M Wesolowski 				if (driveId & 0x80) {
352*80c94ecdSKeith M Wesolowski 					driveId -= 0x80;
353*80c94ecdSKeith M Wesolowski 					cmn_err(CE_CONT, " Physical Drive Num "
354*80c94ecdSKeith M Wesolowski 					    "....... SCSI Port %u, "
355*80c94ecdSKeith M Wesolowski 					    "Drive Id %u\n",
356*80c94ecdSKeith M Wesolowski 					    (driveId / 16) + 1,
357*80c94ecdSKeith M Wesolowski 					    (driveId % 16));
358*80c94ecdSKeith M Wesolowski 				} else {
359*80c94ecdSKeith M Wesolowski 					cmn_err(CE_CONT, " Physical Drive Num "
360*80c94ecdSKeith M Wesolowski 					    "....... SCSI Port %u, "
361*80c94ecdSKeith M Wesolowski 					    "Drive Id %u\n",
362*80c94ecdSKeith M Wesolowski 					    (driveId / 16) + 1, (driveId % 16));
363*80c94ecdSKeith M Wesolowski 				}
364*80c94ecdSKeith M Wesolowski 			}
365*80c94ecdSKeith M Wesolowski 
366*80c94ecdSKeith M Wesolowski 			cmn_err(CE_CONT, " Configured Drive ? ....... %s\n",
367*80c94ecdSKeith M Wesolowski 			    evt->event_specific_data[2] ? "YES" : "NO");
368*80c94ecdSKeith M Wesolowski 			if (evt->event_specific_data[3]) {
369*80c94ecdSKeith M Wesolowski 				cmn_err(CE_CONT, " Spare Drive? "
370*80c94ecdSKeith M Wesolowski 				    "............. %s\n",
371*80c94ecdSKeith M Wesolowski 				    evt->event_specific_data[3] ? "YES" : "NO");
372*80c94ecdSKeith M Wesolowski 			}
373*80c94ecdSKeith M Wesolowski 		} else if (evt->event_subclass_code == SUB_CLASS_SB_HP_CHANGE) {
374*80c94ecdSKeith M Wesolowski 			if (evt->event_detail_code == DETAIL_PATH_REMOVED) {
375*80c94ecdSKeith M Wesolowski 				cmn_err(CE_WARN, " %s", ctlr->hba_name);
376*80c94ecdSKeith M Wesolowski 				cmn_err(CE_CONT,
377*80c94ecdSKeith M Wesolowski 				    " Storage Enclosure cable or %s\n",
378*80c94ecdSKeith M Wesolowski 				    evt->ascii_message);
379*80c94ecdSKeith M Wesolowski 			} else if (evt->event_detail_code ==
380*80c94ecdSKeith M Wesolowski 			    DETAIL_PATH_REPAIRED) {
381*80c94ecdSKeith M Wesolowski 				cmn_err(CE_NOTE, " %s", ctlr->hba_name);
382*80c94ecdSKeith M Wesolowski 				cmn_err(CE_CONT,
383*80c94ecdSKeith M Wesolowski 				    " Storage Enclosure Cable or %s\n",
384*80c94ecdSKeith M Wesolowski 				    evt->ascii_message);
385*80c94ecdSKeith M Wesolowski 			} else {
386*80c94ecdSKeith M Wesolowski 				cmn_err(CE_NOTE, " %s", ctlr->hba_name);
387*80c94ecdSKeith M Wesolowski 				cmn_err(CE_CONT, " %s\n", evt->ascii_message);
388*80c94ecdSKeith M Wesolowski 			}
389*80c94ecdSKeith M Wesolowski 		} else {
390*80c94ecdSKeith M Wesolowski 			cmn_err(CE_NOTE, " %s", ctlr->hba_name);
391*80c94ecdSKeith M Wesolowski 			cmn_err(CE_CONT, " %s\n", evt->ascii_message);
392*80c94ecdSKeith M Wesolowski 		}
393*80c94ecdSKeith M Wesolowski 
394*80c94ecdSKeith M Wesolowski 		cmn_err(CE_CONT, "\n");
395*80c94ecdSKeith M Wesolowski 		break;
396*80c94ecdSKeith M Wesolowski 
397*80c94ecdSKeith M Wesolowski 	case CLASS_HARDWARE:
398*80c94ecdSKeith M Wesolowski 	case CLASS_ENVIRONMENT:
399*80c94ecdSKeith M Wesolowski 		cmn_err(CE_NOTE, " %s", ctlr->hba_name);
400*80c94ecdSKeith M Wesolowski 		cmn_err(CE_CONT, " %s\n", evt->ascii_message);
401*80c94ecdSKeith M Wesolowski 		cmn_err(CE_CONT, "\n");
402*80c94ecdSKeith M Wesolowski 		break;
403*80c94ecdSKeith M Wesolowski 
404*80c94ecdSKeith M Wesolowski 	case CLASS_PHYSICAL_DRIVE:
405*80c94ecdSKeith M Wesolowski 		cmn_err(CE_WARN, " %s", ctlr->hba_name);
406*80c94ecdSKeith M Wesolowski 		cmn_err(CE_CONT, " %s\n", evt->ascii_message);
407*80c94ecdSKeith M Wesolowski 
408*80c94ecdSKeith M Wesolowski 		/*
409*80c94ecdSKeith M Wesolowski 		 * Fix for QUIX 1000440284: Display the Physical Drive
410*80c94ecdSKeith M Wesolowski 		 * Num info only for CISS Controllers
411*80c94ecdSKeith M Wesolowski 		 */
412*80c94ecdSKeith M Wesolowski 
413*80c94ecdSKeith M Wesolowski 		if (!(ctlr->bddef->bd_flags & SA_BD_SAS)) {
414*80c94ecdSKeith M Wesolowski 			/* LINTED: alignment */
415*80c94ecdSKeith M Wesolowski 			driveId = *(uint16_t *)(&evt->event_specific_data[0]);
416*80c94ecdSKeith M Wesolowski 			if (driveId & 0x80) {
417*80c94ecdSKeith M Wesolowski 				driveId -= 0x80;
418*80c94ecdSKeith M Wesolowski 				cmn_err(CE_CONT, " Physical Drive Num ....... "
419*80c94ecdSKeith M Wesolowski 				    "SCSI Port %u, Drive Id %u\n",
420*80c94ecdSKeith M Wesolowski 				    (driveId / 16) + 1, (driveId % 16));
421*80c94ecdSKeith M Wesolowski 			} else {
422*80c94ecdSKeith M Wesolowski 				cmn_err(CE_CONT, " Physical Drive Num ....... "
423*80c94ecdSKeith M Wesolowski 				    "SCSI Port %u, Drive Id %u\n",
424*80c94ecdSKeith M Wesolowski 				    (driveId / 16) + 1, (driveId % 16));
425*80c94ecdSKeith M Wesolowski 			}
426*80c94ecdSKeith M Wesolowski 		}
427*80c94ecdSKeith M Wesolowski 
428*80c94ecdSKeith M Wesolowski 		if (evt->event_specific_data[2] < MAX_KNOWN_FAILURE_REASON) {
429*80c94ecdSKeith M Wesolowski 			cmn_err(CE_CONT, " Failure Reason............ %s\n",
430*80c94ecdSKeith M Wesolowski 			    ascii_failure_reason[evt->event_specific_data[2]]);
431*80c94ecdSKeith M Wesolowski 		} else {
432*80c94ecdSKeith M Wesolowski 			cmn_err(CE_CONT,
433*80c94ecdSKeith M Wesolowski 			    " Failure Reason............ UNKNOWN \n");
434*80c94ecdSKeith M Wesolowski 		}
435*80c94ecdSKeith M Wesolowski 
436*80c94ecdSKeith M Wesolowski 		cmn_err(CE_CONT, "\n");
437*80c94ecdSKeith M Wesolowski 		break;
438*80c94ecdSKeith M Wesolowski 
439*80c94ecdSKeith M Wesolowski 	case CLASS_LOGICAL_DRIVE:
440*80c94ecdSKeith M Wesolowski 		cmn_err(CE_NOTE, " %s", ctlr->hba_name);
441*80c94ecdSKeith M Wesolowski 
442*80c94ecdSKeith M Wesolowski 		/*
443*80c94ecdSKeith M Wesolowski 		 * Fix for QXCR1000717274 - We are appending the logical
444*80c94ecdSKeith M Wesolowski 		 * voulme number by one to be in sync with logical volume
445*80c94ecdSKeith M Wesolowski 		 * details given by HPQacucli
446*80c94ecdSKeith M Wesolowski 		 */
447*80c94ecdSKeith M Wesolowski 
448*80c94ecdSKeith M Wesolowski 		if ((evt->event_subclass_code == SUB_CLASS_STATUS) &&
449*80c94ecdSKeith M Wesolowski 		    (evt->event_detail_code == DETAIL_CHANGE)) {
450*80c94ecdSKeith M Wesolowski 			cmn_err(CE_CONT, " State change, logical drive %u\n",
451*80c94ecdSKeith M Wesolowski 			    /* LINTED: alignment */
452*80c94ecdSKeith M Wesolowski 			    (*(uint16_t *)(&evt->event_specific_data[0]) + 1));
453*80c94ecdSKeith M Wesolowski 			cmn_err(CE_CONT, " New Logical Drive State... %s\n",
454*80c94ecdSKeith M Wesolowski 			    log_vol_status[evt->event_specific_data[3]]);
455*80c94ecdSKeith M Wesolowski 
456*80c94ecdSKeith M Wesolowski 			/*
457*80c94ecdSKeith M Wesolowski 			 * If the Logical drive has FAILED or it was
458*80c94ecdSKeith M Wesolowski 			 * NOT CONFIGURED, in the corresponding target
459*80c94ecdSKeith M Wesolowski 			 * structure, set flag as NONE to suggest that no
460*80c94ecdSKeith M Wesolowski 			 * target exists at this id.
461*80c94ecdSKeith M Wesolowski 			 */
462*80c94ecdSKeith M Wesolowski 
463*80c94ecdSKeith M Wesolowski 			if ((evt->event_specific_data[3] == 1) ||
464*80c94ecdSKeith M Wesolowski 			    (evt->event_specific_data[3] == 2)) {
465*80c94ecdSKeith M Wesolowski 				/* LINTED: alignment */
466*80c94ecdSKeith M Wesolowski 				drive =	*(uint16_t *)
467*80c94ecdSKeith M Wesolowski 				    (&evt->event_specific_data[0]);
468*80c94ecdSKeith M Wesolowski 				drive = ((drive < CTLR_SCSI_ID)
469*80c94ecdSKeith M Wesolowski 				    ? drive : drive + CPQARY3_TGT_ALIGNMENT);
470*80c94ecdSKeith M Wesolowski 				if (ctlr && ctlr->cpqary3_tgtp[drive]) {
471*80c94ecdSKeith M Wesolowski 					ctlr->cpqary3_tgtp[drive]->type =
472*80c94ecdSKeith M Wesolowski 					    CPQARY3_TARGET_NONE;
473*80c94ecdSKeith M Wesolowski 				}
474*80c94ecdSKeith M Wesolowski 			}
475*80c94ecdSKeith M Wesolowski 
476*80c94ecdSKeith M Wesolowski 			if (evt->event_specific_data[4] & SPARE_REBUILDING) {
477*80c94ecdSKeith M Wesolowski 				cmn_err(CE_CONT, " Logical Drive %d: "
478*80c94ecdSKeith M Wesolowski 				    "Data is rebuilding on spare drive\n",
479*80c94ecdSKeith M Wesolowski 				    /* LINTED: alignment */
480*80c94ecdSKeith M Wesolowski 				    (*(uint16_t *)
481*80c94ecdSKeith M Wesolowski 				    (&evt->event_specific_data[0]) + 1));
482*80c94ecdSKeith M Wesolowski 			}
483*80c94ecdSKeith M Wesolowski 
484*80c94ecdSKeith M Wesolowski 			if (evt->event_specific_data[4] & SPARE_REBUILT) {
485*80c94ecdSKeith M Wesolowski 				cmn_err(CE_CONT,
486*80c94ecdSKeith M Wesolowski 				    " Logical Drive %d: Rebuild complete. "
487*80c94ecdSKeith M Wesolowski 				    "Spare is now active\n",
488*80c94ecdSKeith M Wesolowski 				    /* LINTED: alignment */
489*80c94ecdSKeith M Wesolowski 				    (*(uint16_t *)
490*80c94ecdSKeith M Wesolowski 				    (&evt->event_specific_data[0]) + 1));
491*80c94ecdSKeith M Wesolowski 			}
492*80c94ecdSKeith M Wesolowski 		} else if ((evt->event_subclass_code == SUB_CLASS_STATUS) &&
493*80c94ecdSKeith M Wesolowski 		    (evt->event_detail_code == MEDIA_EXCHANGE)) {
494*80c94ecdSKeith M Wesolowski 			cmn_err(CE_CONT, " Media exchange detected, "
495*80c94ecdSKeith M Wesolowski 			    "logical drive %u\n",
496*80c94ecdSKeith M Wesolowski 			    /* LINTED: alignment */
497*80c94ecdSKeith M Wesolowski 			    (*(uint16_t *)
498*80c94ecdSKeith M Wesolowski 			    (&evt->event_specific_data[0]) + 1));
499*80c94ecdSKeith M Wesolowski 		} else {
500*80c94ecdSKeith M Wesolowski 			cmn_err(CE_CONT, " %s\n", evt->ascii_message);
501*80c94ecdSKeith M Wesolowski 		}
502*80c94ecdSKeith M Wesolowski 
503*80c94ecdSKeith M Wesolowski 		cmn_err(CE_CONT, "\n");
504*80c94ecdSKeith M Wesolowski 		break;
505*80c94ecdSKeith M Wesolowski 
506*80c94ecdSKeith M Wesolowski 	default:
507*80c94ecdSKeith M Wesolowski 		cmn_err(CE_NOTE, "%s", ctlr->hba_name);
508*80c94ecdSKeith M Wesolowski 		cmn_err(CE_CONT, " %s\n", evt->ascii_message);
509*80c94ecdSKeith M Wesolowski 		cmn_err(CE_CONT, "\n");
510*80c94ecdSKeith M Wesolowski 		break;
511*80c94ecdSKeith M Wesolowski 	}
512*80c94ecdSKeith M Wesolowski 
513*80c94ecdSKeith M Wesolowski 	/*
514*80c94ecdSKeith M Wesolowski 	 * Here, we reuse this command block to resubmit the NOE
515*80c94ecdSKeith M Wesolowski 	 * command.
516*80c94ecdSKeith M Wesolowski 	 * Ideally speaking, the resubmit should never fail
517*80c94ecdSKeith M Wesolowski 	 */
518*80c94ecdSKeith M Wesolowski 	if (CPQARY3_FAILURE ==
519*80c94ecdSKeith M Wesolowski 	    cpqary3_send_NOE_command(ctlr, memp, CPQARY3_NOE_RESUBMIT)) {
520*80c94ecdSKeith M Wesolowski 		cmn_err(CE_WARN, "CPQary3: Failed to ReInitialize "
521*80c94ecdSKeith M Wesolowski 		    "NOTIFY OF EVENT");
522*80c94ecdSKeith M Wesolowski 		cpqary3_free_phyctgs_mem(MEM2DRVPVT(memp)->phyctgp,
523*80c94ecdSKeith M Wesolowski 		    CPQARY3_FREE_PHYCTG_MEM);
524*80c94ecdSKeith M Wesolowski 		cpqary3_cmdlist_release(memp, CPQARY3_NO_MUTEX);
525*80c94ecdSKeith M Wesolowski 	}
526*80c94ecdSKeith M Wesolowski }
527*80c94ecdSKeith M Wesolowski 
528*80c94ecdSKeith M Wesolowski /* PERF */
529*80c94ecdSKeith M Wesolowski /*
530*80c94ecdSKeith M Wesolowski  * Function	:      	cpqary3_noe_complete
531*80c94ecdSKeith M Wesolowski  * Description	:      	This routine processes the completed
532*80c94ecdSKeith M Wesolowski  *			NOE commands and
533*80c94ecdSKeith M Wesolowski  *			initiates any callback that is needed.
534*80c94ecdSKeith M Wesolowski  * Called By	:      	cpqary3_send_NOE_command,
535*80c94ecdSKeith M Wesolowski  *			cpqary3_disable_NOE_command
536*80c94ecdSKeith M Wesolowski  * Parameters	:      	per-command
537*80c94ecdSKeith M Wesolowski  * Calls	:      	cpqary3_NOE_handler, cpqary3_cmdlist_release
538*80c94ecdSKeith M Wesolowski  * Return Values:      	None
539*80c94ecdSKeith M Wesolowski  */
540*80c94ecdSKeith M Wesolowski void
541*80c94ecdSKeith M Wesolowski cpqary3_noe_complete(cpqary3_cmdpvt_t *cpqary3_cmdpvtp)
542*80c94ecdSKeith M Wesolowski {
543*80c94ecdSKeith M Wesolowski 	ASSERT(cpqary3_cmdpvtp != NULL);
544*80c94ecdSKeith M Wesolowski 
545*80c94ecdSKeith M Wesolowski 	if (CPQARY3_TIMEOUT == cpqary3_cmdpvtp->cmdpvt_flag) {
546*80c94ecdSKeith M Wesolowski 		cpqary3_cmdlist_release(cpqary3_cmdpvtp, CPQARY3_NO_MUTEX);
547*80c94ecdSKeith M Wesolowski 		return;
548*80c94ecdSKeith M Wesolowski 	}
549*80c94ecdSKeith M Wesolowski 
550*80c94ecdSKeith M Wesolowski 	if (cpqary3_cmdpvtp->cmdlist_memaddr->Request.CDB[6] ==
551*80c94ecdSKeith M Wesolowski 	    BMIC_CANCEL_NOTIFY_ON_EVENT) {
552*80c94ecdSKeith M Wesolowski 		cv_signal(&cpqary3_cmdpvtp->ctlr->cv_noe_wait);
553*80c94ecdSKeith M Wesolowski 		cpqary3_cmdlist_release(cpqary3_cmdpvtp, CPQARY3_NO_MUTEX);
554*80c94ecdSKeith M Wesolowski 	} else {
555*80c94ecdSKeith M Wesolowski 		cpqary3_NOE_handler(cpqary3_cmdpvtp);
556*80c94ecdSKeith M Wesolowski 	}
557*80c94ecdSKeith M Wesolowski }
558*80c94ecdSKeith M Wesolowski 
559*80c94ecdSKeith M Wesolowski /* PERF */
560