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
cpqary3_send_NOE_command(cpqary3_t * ctlr,cpqary3_cmdpvt_t * memp,uint8_t flag)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
cpqary3_disable_NOE_command(cpqary3_t * ctlr)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
cpqary3_NOE_handler(cpqary3_cmdpvt_t * memp)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
cpqary3_noe_complete(cpqary3_cmdpvt_t * cpqary3_cmdpvtp)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