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