1 /* 2 * linux/drivers/message/fusion/mptbase.c 3 * This is the Fusion MPT base driver which supports multiple 4 * (SCSI + LAN) specialized protocol drivers. 5 * For use with LSI PCI chip/adapter(s) 6 * running LSI Fusion MPT (Message Passing Technology) firmware. 7 * 8 * Copyright (c) 1999-2008 LSI Corporation 9 * (mailto:DL-MPTFusionLinux@lsi.com) 10 * 11 */ 12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 13 /* 14 This program is free software; you can redistribute it and/or modify 15 it under the terms of the GNU General Public License as published by 16 the Free Software Foundation; version 2 of the License. 17 18 This program is distributed in the hope that it will be useful, 19 but WITHOUT ANY WARRANTY; without even the implied warranty of 20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 GNU General Public License for more details. 22 23 NO WARRANTY 24 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR 25 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT 26 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT, 27 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is 28 solely responsible for determining the appropriateness of using and 29 distributing the Program and assumes all risks associated with its 30 exercise of rights under this Agreement, including but not limited to 31 the risks and costs of program errors, damage to or loss of data, 32 programs or equipment, and unavailability or interruption of operations. 33 34 DISCLAIMER OF LIABILITY 35 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY 36 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 37 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND 38 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 39 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 40 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED 41 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES 42 43 You should have received a copy of the GNU General Public License 44 along with this program; if not, write to the Free Software 45 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 46 */ 47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 48 49 #include <linux/kernel.h> 50 #include <linux/module.h> 51 #include <linux/errno.h> 52 #include <linux/init.h> 53 #include <linux/slab.h> 54 #include <linux/types.h> 55 #include <linux/pci.h> 56 #include <linux/kdev_t.h> 57 #include <linux/blkdev.h> 58 #include <linux/delay.h> 59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */ 60 #include <linux/dma-mapping.h> 61 #include <asm/io.h> 62 #ifdef CONFIG_MTRR 63 #include <asm/mtrr.h> 64 #endif 65 66 #include "mptbase.h" 67 #include "lsi/mpi_log_fc.h" 68 69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 70 #define my_NAME "Fusion MPT base driver" 71 #define my_VERSION MPT_LINUX_VERSION_COMMON 72 #define MYNAM "mptbase" 73 74 MODULE_AUTHOR(MODULEAUTHOR); 75 MODULE_DESCRIPTION(my_NAME); 76 MODULE_LICENSE("GPL"); 77 MODULE_VERSION(my_VERSION); 78 79 /* 80 * cmd line parameters 81 */ 82 static int mpt_msi_enable = -1; 83 module_param(mpt_msi_enable, int, 0); 84 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)"); 85 86 static int mpt_channel_mapping; 87 module_param(mpt_channel_mapping, int, 0); 88 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)"); 89 90 static int mpt_debug_level; 91 static int mpt_set_debug_level(const char *val, struct kernel_param *kp); 92 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int, 93 &mpt_debug_level, 0600); 94 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h - (default=0)"); 95 96 #ifdef MFCNT 97 static int mfcounter = 0; 98 #define PRINT_MF_COUNT 20000 99 #endif 100 101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 102 /* 103 * Public data... 104 */ 105 106 static struct proc_dir_entry *mpt_proc_root_dir; 107 108 #define WHOINIT_UNKNOWN 0xAA 109 110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 111 /* 112 * Private data... 113 */ 114 /* Adapter link list */ 115 LIST_HEAD(ioc_list); 116 /* Callback lookup table */ 117 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS]; 118 /* Protocol driver class lookup table */ 119 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS]; 120 /* Event handler lookup table */ 121 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 122 /* Reset handler lookup table */ 123 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 124 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS]; 125 126 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq); 127 128 /* 129 * Driver Callback Index's 130 */ 131 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS; 132 static u8 last_drv_idx; 133 134 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 135 /* 136 * Forward protos... 137 */ 138 static irqreturn_t mpt_interrupt(int irq, void *bus_id); 139 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply); 140 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, 141 u32 *req, int replyBytes, u16 *u16reply, int maxwait, 142 int sleepFlag); 143 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag); 144 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev); 145 static void mpt_adapter_disable(MPT_ADAPTER *ioc); 146 static void mpt_adapter_dispose(MPT_ADAPTER *ioc); 147 148 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc); 149 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag); 150 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason); 151 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag); 152 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag); 153 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag); 154 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag); 155 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag); 156 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag); 157 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag); 158 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag); 159 static int PrimeIocFifos(MPT_ADAPTER *ioc); 160 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 161 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 162 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag); 163 static int GetLanConfigPages(MPT_ADAPTER *ioc); 164 static int GetIoUnitPage2(MPT_ADAPTER *ioc); 165 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode); 166 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum); 167 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum); 168 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc); 169 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc); 170 static void mpt_timer_expired(unsigned long data); 171 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc); 172 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch); 173 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp); 174 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag); 175 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init); 176 177 #ifdef CONFIG_PROC_FS 178 static int procmpt_summary_read(char *buf, char **start, off_t offset, 179 int request, int *eof, void *data); 180 static int procmpt_version_read(char *buf, char **start, off_t offset, 181 int request, int *eof, void *data); 182 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset, 183 int request, int *eof, void *data); 184 #endif 185 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc); 186 187 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag); 188 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers); 189 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf); 190 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info); 191 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info); 192 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info); 193 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc); 194 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc); 195 196 /* module entry point */ 197 static int __init fusion_init (void); 198 static void __exit fusion_exit (void); 199 200 #define CHIPREG_READ32(addr) readl_relaxed(addr) 201 #define CHIPREG_READ32_dmasync(addr) readl(addr) 202 #define CHIPREG_WRITE32(addr,val) writel(val, addr) 203 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr) 204 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr) 205 206 static void 207 pci_disable_io_access(struct pci_dev *pdev) 208 { 209 u16 command_reg; 210 211 pci_read_config_word(pdev, PCI_COMMAND, &command_reg); 212 command_reg &= ~1; 213 pci_write_config_word(pdev, PCI_COMMAND, command_reg); 214 } 215 216 static void 217 pci_enable_io_access(struct pci_dev *pdev) 218 { 219 u16 command_reg; 220 221 pci_read_config_word(pdev, PCI_COMMAND, &command_reg); 222 command_reg |= 1; 223 pci_write_config_word(pdev, PCI_COMMAND, command_reg); 224 } 225 226 static int mpt_set_debug_level(const char *val, struct kernel_param *kp) 227 { 228 int ret = param_set_int(val, kp); 229 MPT_ADAPTER *ioc; 230 231 if (ret) 232 return ret; 233 234 list_for_each_entry(ioc, &ioc_list, list) 235 ioc->debug_level = mpt_debug_level; 236 return 0; 237 } 238 239 /** 240 * mpt_get_cb_idx - obtain cb_idx for registered driver 241 * @dclass: class driver enum 242 * 243 * Returns cb_idx, or zero means it wasn't found 244 **/ 245 static u8 246 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass) 247 { 248 u8 cb_idx; 249 250 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) 251 if (MptDriverClass[cb_idx] == dclass) 252 return cb_idx; 253 return 0; 254 } 255 256 /** 257 * mpt_fault_reset_work - work performed on workq after ioc fault 258 * @work: input argument, used to derive ioc 259 * 260 **/ 261 static void 262 mpt_fault_reset_work(struct work_struct *work) 263 { 264 MPT_ADAPTER *ioc = 265 container_of(work, MPT_ADAPTER, fault_reset_work.work); 266 u32 ioc_raw_state; 267 int rc; 268 unsigned long flags; 269 270 if (ioc->diagPending || !ioc->active) 271 goto out; 272 273 ioc_raw_state = mpt_GetIocState(ioc, 0); 274 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { 275 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n", 276 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); 277 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n", 278 ioc->name, __func__); 279 rc = mpt_HardResetHandler(ioc, CAN_SLEEP); 280 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name, 281 __func__, (rc == 0) ? "success" : "failed"); 282 ioc_raw_state = mpt_GetIocState(ioc, 0); 283 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) 284 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after " 285 "reset (%04xh)\n", ioc->name, ioc_raw_state & 286 MPI_DOORBELL_DATA_MASK); 287 } 288 289 out: 290 /* 291 * Take turns polling alternate controller 292 */ 293 if (ioc->alt_ioc) 294 ioc = ioc->alt_ioc; 295 296 /* rearm the timer */ 297 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags); 298 if (ioc->reset_work_q) 299 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work, 300 msecs_to_jiffies(MPT_POLLING_INTERVAL)); 301 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags); 302 } 303 304 305 /* 306 * Process turbo (context) reply... 307 */ 308 static void 309 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa) 310 { 311 MPT_FRAME_HDR *mf = NULL; 312 MPT_FRAME_HDR *mr = NULL; 313 u16 req_idx = 0; 314 u8 cb_idx; 315 316 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n", 317 ioc->name, pa)); 318 319 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) { 320 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT: 321 req_idx = pa & 0x0000FFFF; 322 cb_idx = (pa & 0x00FF0000) >> 16; 323 mf = MPT_INDEX_2_MFPTR(ioc, req_idx); 324 break; 325 case MPI_CONTEXT_REPLY_TYPE_LAN: 326 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER); 327 /* 328 * Blind set of mf to NULL here was fatal 329 * after lan_reply says "freeme" 330 * Fix sort of combined with an optimization here; 331 * added explicit check for case where lan_reply 332 * was just returning 1 and doing nothing else. 333 * For this case skip the callback, but set up 334 * proper mf value first here:-) 335 */ 336 if ((pa & 0x58000000) == 0x58000000) { 337 req_idx = pa & 0x0000FFFF; 338 mf = MPT_INDEX_2_MFPTR(ioc, req_idx); 339 mpt_free_msg_frame(ioc, mf); 340 mb(); 341 return; 342 break; 343 } 344 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa); 345 break; 346 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET: 347 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER); 348 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa); 349 break; 350 default: 351 cb_idx = 0; 352 BUG(); 353 } 354 355 /* Check for (valid) IO callback! */ 356 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || 357 MptCallbacks[cb_idx] == NULL) { 358 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", 359 __func__, ioc->name, cb_idx); 360 goto out; 361 } 362 363 if (MptCallbacks[cb_idx](ioc, mf, mr)) 364 mpt_free_msg_frame(ioc, mf); 365 out: 366 mb(); 367 } 368 369 static void 370 mpt_reply(MPT_ADAPTER *ioc, u32 pa) 371 { 372 MPT_FRAME_HDR *mf; 373 MPT_FRAME_HDR *mr; 374 u16 req_idx; 375 u8 cb_idx; 376 int freeme; 377 378 u32 reply_dma_low; 379 u16 ioc_stat; 380 381 /* non-TURBO reply! Hmmm, something may be up... 382 * Newest turbo reply mechanism; get address 383 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)! 384 */ 385 386 /* Map DMA address of reply header to cpu address. 387 * pa is 32 bits - but the dma address may be 32 or 64 bits 388 * get offset based only only the low addresses 389 */ 390 391 reply_dma_low = (pa <<= 1); 392 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames + 393 (reply_dma_low - ioc->reply_frames_low_dma)); 394 395 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx); 396 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx; 397 mf = MPT_INDEX_2_MFPTR(ioc, req_idx); 398 399 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n", 400 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function)); 401 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr); 402 403 /* Check/log IOC log info 404 */ 405 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus); 406 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) { 407 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo); 408 if (ioc->bus_type == FC) 409 mpt_fc_log_info(ioc, log_info); 410 else if (ioc->bus_type == SPI) 411 mpt_spi_log_info(ioc, log_info); 412 else if (ioc->bus_type == SAS) 413 mpt_sas_log_info(ioc, log_info); 414 } 415 416 if (ioc_stat & MPI_IOCSTATUS_MASK) 417 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf); 418 419 /* Check for (valid) IO callback! */ 420 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS || 421 MptCallbacks[cb_idx] == NULL) { 422 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n", 423 __func__, ioc->name, cb_idx); 424 freeme = 0; 425 goto out; 426 } 427 428 freeme = MptCallbacks[cb_idx](ioc, mf, mr); 429 430 out: 431 /* Flush (non-TURBO) reply with a WRITE! */ 432 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa); 433 434 if (freeme) 435 mpt_free_msg_frame(ioc, mf); 436 mb(); 437 } 438 439 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 440 /** 441 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler. 442 * @irq: irq number (not used) 443 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure 444 * 445 * This routine is registered via the request_irq() kernel API call, 446 * and handles all interrupts generated from a specific MPT adapter 447 * (also referred to as a IO Controller or IOC). 448 * This routine must clear the interrupt from the adapter and does 449 * so by reading the reply FIFO. Multiple replies may be processed 450 * per single call to this routine. 451 * 452 * This routine handles register-level access of the adapter but 453 * dispatches (calls) a protocol-specific callback routine to handle 454 * the protocol-specific details of the MPT request completion. 455 */ 456 static irqreturn_t 457 mpt_interrupt(int irq, void *bus_id) 458 { 459 MPT_ADAPTER *ioc = bus_id; 460 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); 461 462 if (pa == 0xFFFFFFFF) 463 return IRQ_NONE; 464 465 /* 466 * Drain the reply FIFO! 467 */ 468 do { 469 if (pa & MPI_ADDRESS_REPLY_A_BIT) 470 mpt_reply(ioc, pa); 471 else 472 mpt_turbo_reply(ioc, pa); 473 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo); 474 } while (pa != 0xFFFFFFFF); 475 476 return IRQ_HANDLED; 477 } 478 479 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 480 /** 481 * mpt_base_reply - MPT base driver's callback routine 482 * @ioc: Pointer to MPT_ADAPTER structure 483 * @mf: Pointer to original MPT request frame 484 * @reply: Pointer to MPT reply frame (NULL if TurboReply) 485 * 486 * MPT base driver's callback routine; all base driver 487 * "internal" request/reply processing is routed here. 488 * Currently used for EventNotification and EventAck handling. 489 * 490 * Returns 1 indicating original alloc'd request frame ptr 491 * should be freed, or 0 if it shouldn't. 492 */ 493 static int 494 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply) 495 { 496 int freereq = 1; 497 u8 func; 498 499 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name)); 500 #ifdef CONFIG_FUSION_LOGGING 501 if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) && 502 !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) { 503 dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n", 504 ioc->name, mf)); 505 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf); 506 } 507 #endif 508 509 func = reply->u.hdr.Function; 510 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n", 511 ioc->name, func)); 512 513 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) { 514 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply; 515 int evHandlers = 0; 516 int results; 517 518 results = ProcessEventNotification(ioc, pEvReply, &evHandlers); 519 if (results != evHandlers) { 520 /* CHECKME! Any special handling needed here? */ 521 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n", 522 ioc->name, evHandlers, results)); 523 } 524 525 /* 526 * Hmmm... It seems that EventNotificationReply is an exception 527 * to the rule of one reply per request. 528 */ 529 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) { 530 freereq = 0; 531 } else { 532 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n", 533 ioc->name, pEvReply)); 534 } 535 536 #ifdef CONFIG_PROC_FS 537 // LogEvent(ioc, pEvReply); 538 #endif 539 540 } else if (func == MPI_FUNCTION_EVENT_ACK) { 541 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n", 542 ioc->name)); 543 } else if (func == MPI_FUNCTION_CONFIG) { 544 CONFIGPARMS *pCfg; 545 unsigned long flags; 546 547 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n", 548 ioc->name, mf, reply)); 549 550 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *))); 551 552 if (pCfg) { 553 /* disable timer and remove from linked list */ 554 del_timer(&pCfg->timer); 555 556 spin_lock_irqsave(&ioc->FreeQlock, flags); 557 list_del(&pCfg->linkage); 558 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 559 560 /* 561 * If IOC Status is SUCCESS, save the header 562 * and set the status code to GOOD. 563 */ 564 pCfg->status = MPT_CONFIG_ERROR; 565 if (reply) { 566 ConfigReply_t *pReply = (ConfigReply_t *)reply; 567 u16 status; 568 569 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK; 570 dcprintk(ioc, printk(MYIOC_s_NOTE_FMT " IOCStatus=%04xh, IOCLogInfo=%08xh\n", 571 ioc->name, status, le32_to_cpu(pReply->IOCLogInfo))); 572 573 pCfg->status = status; 574 if (status == MPI_IOCSTATUS_SUCCESS) { 575 if ((pReply->Header.PageType & 576 MPI_CONFIG_PAGETYPE_MASK) == 577 MPI_CONFIG_PAGETYPE_EXTENDED) { 578 pCfg->cfghdr.ehdr->ExtPageLength = 579 le16_to_cpu(pReply->ExtPageLength); 580 pCfg->cfghdr.ehdr->ExtPageType = 581 pReply->ExtPageType; 582 } 583 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion; 584 585 /* If this is a regular header, save PageLength. */ 586 /* LMP Do this better so not using a reserved field! */ 587 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength; 588 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber; 589 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType; 590 } 591 } 592 593 /* 594 * Wake up the original calling thread 595 */ 596 pCfg->wait_done = 1; 597 wake_up(&mpt_waitq); 598 } 599 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) { 600 /* we should be always getting a reply frame */ 601 memcpy(ioc->persist_reply_frame, reply, 602 min(MPT_DEFAULT_FRAME_SIZE, 603 4*reply->u.reply.MsgLength)); 604 del_timer(&ioc->persist_timer); 605 ioc->persist_wait_done = 1; 606 wake_up(&mpt_waitq); 607 } else { 608 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n", 609 ioc->name, func); 610 } 611 612 /* 613 * Conditionally tell caller to free the original 614 * EventNotification/EventAck/unexpected request frame! 615 */ 616 return freereq; 617 } 618 619 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 620 /** 621 * mpt_register - Register protocol-specific main callback handler. 622 * @cbfunc: callback function pointer 623 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value) 624 * 625 * This routine is called by a protocol-specific driver (SCSI host, 626 * LAN, SCSI target) to register its reply callback routine. Each 627 * protocol-specific driver must do this before it will be able to 628 * use any IOC resources, such as obtaining request frames. 629 * 630 * NOTES: The SCSI protocol driver currently calls this routine thrice 631 * in order to register separate callbacks; one for "normal" SCSI IO; 632 * one for MptScsiTaskMgmt requests; one for Scan/DV requests. 633 * 634 * Returns u8 valued "handle" in the range (and S.O.D. order) 635 * {N,...,7,6,5,...,1} if successful. 636 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be 637 * considered an error by the caller. 638 */ 639 u8 640 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass) 641 { 642 u8 cb_idx; 643 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS; 644 645 /* 646 * Search for empty callback slot in this order: {N,...,7,6,5,...,1} 647 * (slot/handle 0 is reserved!) 648 */ 649 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 650 if (MptCallbacks[cb_idx] == NULL) { 651 MptCallbacks[cb_idx] = cbfunc; 652 MptDriverClass[cb_idx] = dclass; 653 MptEvHandlers[cb_idx] = NULL; 654 last_drv_idx = cb_idx; 655 break; 656 } 657 } 658 659 return last_drv_idx; 660 } 661 662 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 663 /** 664 * mpt_deregister - Deregister a protocol drivers resources. 665 * @cb_idx: previously registered callback handle 666 * 667 * Each protocol-specific driver should call this routine when its 668 * module is unloaded. 669 */ 670 void 671 mpt_deregister(u8 cb_idx) 672 { 673 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) { 674 MptCallbacks[cb_idx] = NULL; 675 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER; 676 MptEvHandlers[cb_idx] = NULL; 677 678 last_drv_idx++; 679 } 680 } 681 682 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 683 /** 684 * mpt_event_register - Register protocol-specific event callback handler. 685 * @cb_idx: previously registered (via mpt_register) callback handle 686 * @ev_cbfunc: callback function 687 * 688 * This routine can be called by one or more protocol-specific drivers 689 * if/when they choose to be notified of MPT events. 690 * 691 * Returns 0 for success. 692 */ 693 int 694 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc) 695 { 696 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 697 return -1; 698 699 MptEvHandlers[cb_idx] = ev_cbfunc; 700 return 0; 701 } 702 703 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 704 /** 705 * mpt_event_deregister - Deregister protocol-specific event callback handler 706 * @cb_idx: previously registered callback handle 707 * 708 * Each protocol-specific driver should call this routine 709 * when it does not (or can no longer) handle events, 710 * or when its module is unloaded. 711 */ 712 void 713 mpt_event_deregister(u8 cb_idx) 714 { 715 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 716 return; 717 718 MptEvHandlers[cb_idx] = NULL; 719 } 720 721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 722 /** 723 * mpt_reset_register - Register protocol-specific IOC reset handler. 724 * @cb_idx: previously registered (via mpt_register) callback handle 725 * @reset_func: reset function 726 * 727 * This routine can be called by one or more protocol-specific drivers 728 * if/when they choose to be notified of IOC resets. 729 * 730 * Returns 0 for success. 731 */ 732 int 733 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func) 734 { 735 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 736 return -1; 737 738 MptResetHandlers[cb_idx] = reset_func; 739 return 0; 740 } 741 742 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 743 /** 744 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler. 745 * @cb_idx: previously registered callback handle 746 * 747 * Each protocol-specific driver should call this routine 748 * when it does not (or can no longer) handle IOC reset handling, 749 * or when its module is unloaded. 750 */ 751 void 752 mpt_reset_deregister(u8 cb_idx) 753 { 754 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 755 return; 756 757 MptResetHandlers[cb_idx] = NULL; 758 } 759 760 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 761 /** 762 * mpt_device_driver_register - Register device driver hooks 763 * @dd_cbfunc: driver callbacks struct 764 * @cb_idx: MPT protocol driver index 765 */ 766 int 767 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx) 768 { 769 MPT_ADAPTER *ioc; 770 const struct pci_device_id *id; 771 772 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 773 return -EINVAL; 774 775 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc; 776 777 /* call per pci device probe entry point */ 778 list_for_each_entry(ioc, &ioc_list, list) { 779 id = ioc->pcidev->driver ? 780 ioc->pcidev->driver->id_table : NULL; 781 if (dd_cbfunc->probe) 782 dd_cbfunc->probe(ioc->pcidev, id); 783 } 784 785 return 0; 786 } 787 788 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 789 /** 790 * mpt_device_driver_deregister - DeRegister device driver hooks 791 * @cb_idx: MPT protocol driver index 792 */ 793 void 794 mpt_device_driver_deregister(u8 cb_idx) 795 { 796 struct mpt_pci_driver *dd_cbfunc; 797 MPT_ADAPTER *ioc; 798 799 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS) 800 return; 801 802 dd_cbfunc = MptDeviceDriverHandlers[cb_idx]; 803 804 list_for_each_entry(ioc, &ioc_list, list) { 805 if (dd_cbfunc->remove) 806 dd_cbfunc->remove(ioc->pcidev); 807 } 808 809 MptDeviceDriverHandlers[cb_idx] = NULL; 810 } 811 812 813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 814 /** 815 * mpt_get_msg_frame - Obtain an MPT request frame from the pool 816 * @cb_idx: Handle of registered MPT protocol driver 817 * @ioc: Pointer to MPT adapter structure 818 * 819 * Obtain an MPT request frame from the pool (of 1024) that are 820 * allocated per MPT adapter. 821 * 822 * Returns pointer to a MPT request frame or %NULL if none are available 823 * or IOC is not active. 824 */ 825 MPT_FRAME_HDR* 826 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc) 827 { 828 MPT_FRAME_HDR *mf; 829 unsigned long flags; 830 u16 req_idx; /* Request index */ 831 832 /* validate handle and ioc identifier */ 833 834 #ifdef MFCNT 835 if (!ioc->active) 836 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame " 837 "returning NULL!\n", ioc->name); 838 #endif 839 840 /* If interrupts are not attached, do not return a request frame */ 841 if (!ioc->active) 842 return NULL; 843 844 spin_lock_irqsave(&ioc->FreeQlock, flags); 845 if (!list_empty(&ioc->FreeQ)) { 846 int req_offset; 847 848 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR, 849 u.frame.linkage.list); 850 list_del(&mf->u.frame.linkage.list); 851 mf->u.frame.linkage.arg1 = 0; 852 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */ 853 req_offset = (u8 *)mf - (u8 *)ioc->req_frames; 854 /* u16! */ 855 req_idx = req_offset / ioc->req_sz; 856 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx); 857 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0; 858 /* Default, will be changed if necessary in SG generation */ 859 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame; 860 #ifdef MFCNT 861 ioc->mfcnt++; 862 #endif 863 } 864 else 865 mf = NULL; 866 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 867 868 #ifdef MFCNT 869 if (mf == NULL) 870 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! " 871 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt, 872 ioc->req_depth); 873 mfcounter++; 874 if (mfcounter == PRINT_MF_COUNT) 875 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name, 876 ioc->mfcnt, ioc->req_depth); 877 #endif 878 879 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n", 880 ioc->name, cb_idx, ioc->id, mf)); 881 return mf; 882 } 883 884 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 885 /** 886 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC 887 * @cb_idx: Handle of registered MPT protocol driver 888 * @ioc: Pointer to MPT adapter structure 889 * @mf: Pointer to MPT request frame 890 * 891 * This routine posts an MPT request frame to the request post FIFO of a 892 * specific MPT adapter. 893 */ 894 void 895 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) 896 { 897 u32 mf_dma_addr; 898 int req_offset; 899 u16 req_idx; /* Request index */ 900 901 /* ensure values are reset properly! */ 902 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */ 903 req_offset = (u8 *)mf - (u8 *)ioc->req_frames; 904 /* u16! */ 905 req_idx = req_offset / ioc->req_sz; 906 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx); 907 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0; 908 909 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf); 910 911 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx]; 912 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d " 913 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx, 914 ioc->RequestNB[req_idx])); 915 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr); 916 } 917 918 /** 919 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame 920 * @cb_idx: Handle of registered MPT protocol driver 921 * @ioc: Pointer to MPT adapter structure 922 * @mf: Pointer to MPT request frame 923 * 924 * Send a protocol-specific MPT request frame to an IOC using 925 * hi-priority request queue. 926 * 927 * This routine posts an MPT request frame to the request post FIFO of a 928 * specific MPT adapter. 929 **/ 930 void 931 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) 932 { 933 u32 mf_dma_addr; 934 int req_offset; 935 u16 req_idx; /* Request index */ 936 937 /* ensure values are reset properly! */ 938 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; 939 req_offset = (u8 *)mf - (u8 *)ioc->req_frames; 940 req_idx = req_offset / ioc->req_sz; 941 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx); 942 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0; 943 944 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf); 945 946 mf_dma_addr = (ioc->req_frames_low_dma + req_offset); 947 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n", 948 ioc->name, mf_dma_addr, req_idx)); 949 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr); 950 } 951 952 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 953 /** 954 * mpt_free_msg_frame - Place MPT request frame back on FreeQ. 955 * @ioc: Pointer to MPT adapter structure 956 * @mf: Pointer to MPT request frame 957 * 958 * This routine places a MPT request frame back on the MPT adapter's 959 * FreeQ. 960 */ 961 void 962 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf) 963 { 964 unsigned long flags; 965 966 /* Put Request back on FreeQ! */ 967 spin_lock_irqsave(&ioc->FreeQlock, flags); 968 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */ 969 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); 970 #ifdef MFCNT 971 ioc->mfcnt--; 972 #endif 973 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 974 } 975 976 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 977 /** 978 * mpt_add_sge - Place a simple SGE at address pAddr. 979 * @pAddr: virtual address for SGE 980 * @flagslength: SGE flags and data transfer length 981 * @dma_addr: Physical address 982 * 983 * This routine places a MPT request frame back on the MPT adapter's 984 * FreeQ. 985 */ 986 void 987 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr) 988 { 989 if (sizeof(dma_addr_t) == sizeof(u64)) { 990 SGESimple64_t *pSge = (SGESimple64_t *) pAddr; 991 u32 tmp = dma_addr & 0xFFFFFFFF; 992 993 pSge->FlagsLength = cpu_to_le32(flagslength); 994 pSge->Address.Low = cpu_to_le32(tmp); 995 tmp = (u32) ((u64)dma_addr >> 32); 996 pSge->Address.High = cpu_to_le32(tmp); 997 998 } else { 999 SGESimple32_t *pSge = (SGESimple32_t *) pAddr; 1000 pSge->FlagsLength = cpu_to_le32(flagslength); 1001 pSge->Address = cpu_to_le32(dma_addr); 1002 } 1003 } 1004 1005 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1006 /** 1007 * mpt_send_handshake_request - Send MPT request via doorbell handshake method. 1008 * @cb_idx: Handle of registered MPT protocol driver 1009 * @ioc: Pointer to MPT adapter structure 1010 * @reqBytes: Size of the request in bytes 1011 * @req: Pointer to MPT request frame 1012 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay. 1013 * 1014 * This routine is used exclusively to send MptScsiTaskMgmt 1015 * requests since they are required to be sent via doorbell handshake. 1016 * 1017 * NOTE: It is the callers responsibility to byte-swap fields in the 1018 * request which are greater than 1 byte in size. 1019 * 1020 * Returns 0 for success, non-zero for failure. 1021 */ 1022 int 1023 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag) 1024 { 1025 int r = 0; 1026 u8 *req_as_bytes; 1027 int ii; 1028 1029 /* State is known to be good upon entering 1030 * this function so issue the bus reset 1031 * request. 1032 */ 1033 1034 /* 1035 * Emulate what mpt_put_msg_frame() does /wrt to sanity 1036 * setting cb_idx/req_idx. But ONLY if this request 1037 * is in proper (pre-alloc'd) request buffer range... 1038 */ 1039 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req); 1040 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) { 1041 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req; 1042 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii); 1043 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; 1044 } 1045 1046 /* Make sure there are no doorbells */ 1047 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1048 1049 CHIPREG_WRITE32(&ioc->chip->Doorbell, 1050 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) | 1051 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT))); 1052 1053 /* Wait for IOC doorbell int */ 1054 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) { 1055 return ii; 1056 } 1057 1058 /* Read doorbell and check for active bit */ 1059 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE)) 1060 return -5; 1061 1062 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n", 1063 ioc->name, ii)); 1064 1065 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1066 1067 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) { 1068 return -2; 1069 } 1070 1071 /* Send request via doorbell handshake */ 1072 req_as_bytes = (u8 *) req; 1073 for (ii = 0; ii < reqBytes/4; ii++) { 1074 u32 word; 1075 1076 word = ((req_as_bytes[(ii*4) + 0] << 0) | 1077 (req_as_bytes[(ii*4) + 1] << 8) | 1078 (req_as_bytes[(ii*4) + 2] << 16) | 1079 (req_as_bytes[(ii*4) + 3] << 24)); 1080 CHIPREG_WRITE32(&ioc->chip->Doorbell, word); 1081 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) { 1082 r = -3; 1083 break; 1084 } 1085 } 1086 1087 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0) 1088 r = 0; 1089 else 1090 r = -4; 1091 1092 /* Make sure there are no doorbells */ 1093 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1094 1095 return r; 1096 } 1097 1098 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1099 /** 1100 * mpt_host_page_access_control - control the IOC's Host Page Buffer access 1101 * @ioc: Pointer to MPT adapter structure 1102 * @access_control_value: define bits below 1103 * @sleepFlag: Specifies whether the process can sleep 1104 * 1105 * Provides mechanism for the host driver to control the IOC's 1106 * Host Page Buffer access. 1107 * 1108 * Access Control Value - bits[15:12] 1109 * 0h Reserved 1110 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS } 1111 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS } 1112 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER } 1113 * 1114 * Returns 0 for success, non-zero for failure. 1115 */ 1116 1117 static int 1118 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag) 1119 { 1120 int r = 0; 1121 1122 /* return if in use */ 1123 if (CHIPREG_READ32(&ioc->chip->Doorbell) 1124 & MPI_DOORBELL_ACTIVE) 1125 return -1; 1126 1127 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1128 1129 CHIPREG_WRITE32(&ioc->chip->Doorbell, 1130 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL 1131 <<MPI_DOORBELL_FUNCTION_SHIFT) | 1132 (access_control_value<<12))); 1133 1134 /* Wait for IOC to clear Doorbell Status bit */ 1135 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) { 1136 return -2; 1137 }else 1138 return 0; 1139 } 1140 1141 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1142 /** 1143 * mpt_host_page_alloc - allocate system memory for the fw 1144 * @ioc: Pointer to pointer to IOC adapter 1145 * @ioc_init: Pointer to ioc init config page 1146 * 1147 * If we already allocated memory in past, then resend the same pointer. 1148 * Returns 0 for success, non-zero for failure. 1149 */ 1150 static int 1151 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init) 1152 { 1153 char *psge; 1154 int flags_length; 1155 u32 host_page_buffer_sz=0; 1156 1157 if(!ioc->HostPageBuffer) { 1158 1159 host_page_buffer_sz = 1160 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF; 1161 1162 if(!host_page_buffer_sz) 1163 return 0; /* fw doesn't need any host buffers */ 1164 1165 /* spin till we get enough memory */ 1166 while(host_page_buffer_sz > 0) { 1167 1168 if((ioc->HostPageBuffer = pci_alloc_consistent( 1169 ioc->pcidev, 1170 host_page_buffer_sz, 1171 &ioc->HostPageBuffer_dma)) != NULL) { 1172 1173 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 1174 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n", 1175 ioc->name, ioc->HostPageBuffer, 1176 (u32)ioc->HostPageBuffer_dma, 1177 host_page_buffer_sz)); 1178 ioc->alloc_total += host_page_buffer_sz; 1179 ioc->HostPageBuffer_sz = host_page_buffer_sz; 1180 break; 1181 } 1182 1183 host_page_buffer_sz -= (4*1024); 1184 } 1185 } 1186 1187 if(!ioc->HostPageBuffer) { 1188 printk(MYIOC_s_ERR_FMT 1189 "Failed to alloc memory for host_page_buffer!\n", 1190 ioc->name); 1191 return -999; 1192 } 1193 1194 psge = (char *)&ioc_init->HostPageBufferSGE; 1195 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT | 1196 MPI_SGE_FLAGS_SYSTEM_ADDRESS | 1197 MPI_SGE_FLAGS_32_BIT_ADDRESSING | 1198 MPI_SGE_FLAGS_HOST_TO_IOC | 1199 MPI_SGE_FLAGS_END_OF_BUFFER; 1200 if (sizeof(dma_addr_t) == sizeof(u64)) { 1201 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING; 1202 } 1203 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT; 1204 flags_length |= ioc->HostPageBuffer_sz; 1205 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma); 1206 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE; 1207 1208 return 0; 1209 } 1210 1211 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1212 /** 1213 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure. 1214 * @iocid: IOC unique identifier (integer) 1215 * @iocpp: Pointer to pointer to IOC adapter 1216 * 1217 * Given a unique IOC identifier, set pointer to the associated MPT 1218 * adapter structure. 1219 * 1220 * Returns iocid and sets iocpp if iocid is found. 1221 * Returns -1 if iocid is not found. 1222 */ 1223 int 1224 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp) 1225 { 1226 MPT_ADAPTER *ioc; 1227 1228 list_for_each_entry(ioc,&ioc_list,list) { 1229 if (ioc->id == iocid) { 1230 *iocpp =ioc; 1231 return iocid; 1232 } 1233 } 1234 1235 *iocpp = NULL; 1236 return -1; 1237 } 1238 1239 /** 1240 * mpt_get_product_name - returns product string 1241 * @vendor: pci vendor id 1242 * @device: pci device id 1243 * @revision: pci revision id 1244 * @prod_name: string returned 1245 * 1246 * Returns product string displayed when driver loads, 1247 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product 1248 * 1249 **/ 1250 static void 1251 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name) 1252 { 1253 char *product_str = NULL; 1254 1255 if (vendor == PCI_VENDOR_ID_BROCADE) { 1256 switch (device) 1257 { 1258 case MPI_MANUFACTPAGE_DEVICEID_FC949E: 1259 switch (revision) 1260 { 1261 case 0x00: 1262 product_str = "BRE040 A0"; 1263 break; 1264 case 0x01: 1265 product_str = "BRE040 A1"; 1266 break; 1267 default: 1268 product_str = "BRE040"; 1269 break; 1270 } 1271 break; 1272 } 1273 goto out; 1274 } 1275 1276 switch (device) 1277 { 1278 case MPI_MANUFACTPAGE_DEVICEID_FC909: 1279 product_str = "LSIFC909 B1"; 1280 break; 1281 case MPI_MANUFACTPAGE_DEVICEID_FC919: 1282 product_str = "LSIFC919 B0"; 1283 break; 1284 case MPI_MANUFACTPAGE_DEVICEID_FC929: 1285 product_str = "LSIFC929 B0"; 1286 break; 1287 case MPI_MANUFACTPAGE_DEVICEID_FC919X: 1288 if (revision < 0x80) 1289 product_str = "LSIFC919X A0"; 1290 else 1291 product_str = "LSIFC919XL A1"; 1292 break; 1293 case MPI_MANUFACTPAGE_DEVICEID_FC929X: 1294 if (revision < 0x80) 1295 product_str = "LSIFC929X A0"; 1296 else 1297 product_str = "LSIFC929XL A1"; 1298 break; 1299 case MPI_MANUFACTPAGE_DEVICEID_FC939X: 1300 product_str = "LSIFC939X A1"; 1301 break; 1302 case MPI_MANUFACTPAGE_DEVICEID_FC949X: 1303 product_str = "LSIFC949X A1"; 1304 break; 1305 case MPI_MANUFACTPAGE_DEVICEID_FC949E: 1306 switch (revision) 1307 { 1308 case 0x00: 1309 product_str = "LSIFC949E A0"; 1310 break; 1311 case 0x01: 1312 product_str = "LSIFC949E A1"; 1313 break; 1314 default: 1315 product_str = "LSIFC949E"; 1316 break; 1317 } 1318 break; 1319 case MPI_MANUFACTPAGE_DEVID_53C1030: 1320 switch (revision) 1321 { 1322 case 0x00: 1323 product_str = "LSI53C1030 A0"; 1324 break; 1325 case 0x01: 1326 product_str = "LSI53C1030 B0"; 1327 break; 1328 case 0x03: 1329 product_str = "LSI53C1030 B1"; 1330 break; 1331 case 0x07: 1332 product_str = "LSI53C1030 B2"; 1333 break; 1334 case 0x08: 1335 product_str = "LSI53C1030 C0"; 1336 break; 1337 case 0x80: 1338 product_str = "LSI53C1030T A0"; 1339 break; 1340 case 0x83: 1341 product_str = "LSI53C1030T A2"; 1342 break; 1343 case 0x87: 1344 product_str = "LSI53C1030T A3"; 1345 break; 1346 case 0xc1: 1347 product_str = "LSI53C1020A A1"; 1348 break; 1349 default: 1350 product_str = "LSI53C1030"; 1351 break; 1352 } 1353 break; 1354 case MPI_MANUFACTPAGE_DEVID_1030_53C1035: 1355 switch (revision) 1356 { 1357 case 0x03: 1358 product_str = "LSI53C1035 A2"; 1359 break; 1360 case 0x04: 1361 product_str = "LSI53C1035 B0"; 1362 break; 1363 default: 1364 product_str = "LSI53C1035"; 1365 break; 1366 } 1367 break; 1368 case MPI_MANUFACTPAGE_DEVID_SAS1064: 1369 switch (revision) 1370 { 1371 case 0x00: 1372 product_str = "LSISAS1064 A1"; 1373 break; 1374 case 0x01: 1375 product_str = "LSISAS1064 A2"; 1376 break; 1377 case 0x02: 1378 product_str = "LSISAS1064 A3"; 1379 break; 1380 case 0x03: 1381 product_str = "LSISAS1064 A4"; 1382 break; 1383 default: 1384 product_str = "LSISAS1064"; 1385 break; 1386 } 1387 break; 1388 case MPI_MANUFACTPAGE_DEVID_SAS1064E: 1389 switch (revision) 1390 { 1391 case 0x00: 1392 product_str = "LSISAS1064E A0"; 1393 break; 1394 case 0x01: 1395 product_str = "LSISAS1064E B0"; 1396 break; 1397 case 0x02: 1398 product_str = "LSISAS1064E B1"; 1399 break; 1400 case 0x04: 1401 product_str = "LSISAS1064E B2"; 1402 break; 1403 case 0x08: 1404 product_str = "LSISAS1064E B3"; 1405 break; 1406 default: 1407 product_str = "LSISAS1064E"; 1408 break; 1409 } 1410 break; 1411 case MPI_MANUFACTPAGE_DEVID_SAS1068: 1412 switch (revision) 1413 { 1414 case 0x00: 1415 product_str = "LSISAS1068 A0"; 1416 break; 1417 case 0x01: 1418 product_str = "LSISAS1068 B0"; 1419 break; 1420 case 0x02: 1421 product_str = "LSISAS1068 B1"; 1422 break; 1423 default: 1424 product_str = "LSISAS1068"; 1425 break; 1426 } 1427 break; 1428 case MPI_MANUFACTPAGE_DEVID_SAS1068E: 1429 switch (revision) 1430 { 1431 case 0x00: 1432 product_str = "LSISAS1068E A0"; 1433 break; 1434 case 0x01: 1435 product_str = "LSISAS1068E B0"; 1436 break; 1437 case 0x02: 1438 product_str = "LSISAS1068E B1"; 1439 break; 1440 case 0x04: 1441 product_str = "LSISAS1068E B2"; 1442 break; 1443 case 0x08: 1444 product_str = "LSISAS1068E B3"; 1445 break; 1446 default: 1447 product_str = "LSISAS1068E"; 1448 break; 1449 } 1450 break; 1451 case MPI_MANUFACTPAGE_DEVID_SAS1078: 1452 switch (revision) 1453 { 1454 case 0x00: 1455 product_str = "LSISAS1078 A0"; 1456 break; 1457 case 0x01: 1458 product_str = "LSISAS1078 B0"; 1459 break; 1460 case 0x02: 1461 product_str = "LSISAS1078 C0"; 1462 break; 1463 case 0x03: 1464 product_str = "LSISAS1078 C1"; 1465 break; 1466 case 0x04: 1467 product_str = "LSISAS1078 C2"; 1468 break; 1469 default: 1470 product_str = "LSISAS1078"; 1471 break; 1472 } 1473 break; 1474 } 1475 1476 out: 1477 if (product_str) 1478 sprintf(prod_name, "%s", product_str); 1479 } 1480 1481 /** 1482 * mpt_mapresources - map in memory mapped io 1483 * @ioc: Pointer to pointer to IOC adapter 1484 * 1485 **/ 1486 static int 1487 mpt_mapresources(MPT_ADAPTER *ioc) 1488 { 1489 u8 __iomem *mem; 1490 int ii; 1491 unsigned long mem_phys; 1492 unsigned long port; 1493 u32 msize; 1494 u32 psize; 1495 u8 revision; 1496 int r = -ENODEV; 1497 struct pci_dev *pdev; 1498 1499 pdev = ioc->pcidev; 1500 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); 1501 if (pci_enable_device_mem(pdev)) { 1502 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() " 1503 "failed\n", ioc->name); 1504 return r; 1505 } 1506 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) { 1507 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with " 1508 "MEM failed\n", ioc->name); 1509 return r; 1510 } 1511 1512 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); 1513 1514 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK) 1515 && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) { 1516 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 1517 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", 1518 ioc->name)); 1519 } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK) 1520 && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) { 1521 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 1522 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n", 1523 ioc->name)); 1524 } else { 1525 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n", 1526 ioc->name, pci_name(pdev)); 1527 pci_release_selected_regions(pdev, ioc->bars); 1528 return r; 1529 } 1530 1531 mem_phys = msize = 0; 1532 port = psize = 0; 1533 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) { 1534 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) { 1535 if (psize) 1536 continue; 1537 /* Get I/O space! */ 1538 port = pci_resource_start(pdev, ii); 1539 psize = pci_resource_len(pdev, ii); 1540 } else { 1541 if (msize) 1542 continue; 1543 /* Get memmap */ 1544 mem_phys = pci_resource_start(pdev, ii); 1545 msize = pci_resource_len(pdev, ii); 1546 } 1547 } 1548 ioc->mem_size = msize; 1549 1550 mem = NULL; 1551 /* Get logical ptr for PciMem0 space */ 1552 /*mem = ioremap(mem_phys, msize);*/ 1553 mem = ioremap(mem_phys, msize); 1554 if (mem == NULL) { 1555 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter" 1556 " memory!\n", ioc->name); 1557 return -EINVAL; 1558 } 1559 ioc->memmap = mem; 1560 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n", 1561 ioc->name, mem, mem_phys)); 1562 1563 ioc->mem_phys = mem_phys; 1564 ioc->chip = (SYSIF_REGS __iomem *)mem; 1565 1566 /* Save Port IO values in case we need to do downloadboot */ 1567 ioc->pio_mem_phys = port; 1568 ioc->pio_chip = (SYSIF_REGS __iomem *)port; 1569 1570 return 0; 1571 } 1572 1573 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1574 /** 1575 * mpt_attach - Install a PCI intelligent MPT adapter. 1576 * @pdev: Pointer to pci_dev structure 1577 * @id: PCI device ID information 1578 * 1579 * This routine performs all the steps necessary to bring the IOC of 1580 * a MPT adapter to a OPERATIONAL state. This includes registering 1581 * memory regions, registering the interrupt, and allocating request 1582 * and reply memory pools. 1583 * 1584 * This routine also pre-fetches the LAN MAC address of a Fibre Channel 1585 * MPT adapter. 1586 * 1587 * Returns 0 for success, non-zero for failure. 1588 * 1589 * TODO: Add support for polled controllers 1590 */ 1591 int 1592 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) 1593 { 1594 MPT_ADAPTER *ioc; 1595 u8 cb_idx; 1596 int r = -ENODEV; 1597 u8 revision; 1598 u8 pcixcmd; 1599 static int mpt_ids = 0; 1600 #ifdef CONFIG_PROC_FS 1601 struct proc_dir_entry *dent, *ent; 1602 #endif 1603 1604 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); 1605 if (ioc == NULL) { 1606 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); 1607 return -ENOMEM; 1608 } 1609 1610 ioc->id = mpt_ids++; 1611 sprintf(ioc->name, "ioc%d", ioc->id); 1612 1613 /* 1614 * set initial debug level 1615 * (refer to mptdebug.h) 1616 * 1617 */ 1618 ioc->debug_level = mpt_debug_level; 1619 if (mpt_debug_level) 1620 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level); 1621 1622 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name)); 1623 1624 ioc->pcidev = pdev; 1625 if (mpt_mapresources(ioc)) { 1626 kfree(ioc); 1627 return r; 1628 } 1629 1630 ioc->alloc_total = sizeof(MPT_ADAPTER); 1631 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */ 1632 ioc->reply_sz = MPT_REPLY_FRAME_SIZE; 1633 1634 ioc->pcidev = pdev; 1635 ioc->diagPending = 0; 1636 spin_lock_init(&ioc->diagLock); 1637 spin_lock_init(&ioc->initializing_hba_lock); 1638 1639 /* Initialize the event logging. 1640 */ 1641 ioc->eventTypes = 0; /* None */ 1642 ioc->eventContext = 0; 1643 ioc->eventLogSize = 0; 1644 ioc->events = NULL; 1645 1646 #ifdef MFCNT 1647 ioc->mfcnt = 0; 1648 #endif 1649 1650 ioc->cached_fw = NULL; 1651 1652 /* Initilize SCSI Config Data structure 1653 */ 1654 memset(&ioc->spi_data, 0, sizeof(SpiCfgData)); 1655 1656 /* Initialize the running configQ head. 1657 */ 1658 INIT_LIST_HEAD(&ioc->configQ); 1659 1660 /* Initialize the fc rport list head. 1661 */ 1662 INIT_LIST_HEAD(&ioc->fc_rports); 1663 1664 /* Find lookup slot. */ 1665 INIT_LIST_HEAD(&ioc->list); 1666 1667 1668 /* Initialize workqueue */ 1669 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work); 1670 spin_lock_init(&ioc->fault_reset_work_lock); 1671 1672 snprintf(ioc->reset_work_q_name, sizeof(ioc->reset_work_q_name), 1673 "mpt_poll_%d", ioc->id); 1674 ioc->reset_work_q = 1675 create_singlethread_workqueue(ioc->reset_work_q_name); 1676 if (!ioc->reset_work_q) { 1677 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n", 1678 ioc->name); 1679 pci_release_selected_regions(pdev, ioc->bars); 1680 kfree(ioc); 1681 return -ENOMEM; 1682 } 1683 1684 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n", 1685 ioc->name, &ioc->facts, &ioc->pfacts[0])); 1686 1687 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision); 1688 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name); 1689 1690 switch (pdev->device) 1691 { 1692 case MPI_MANUFACTPAGE_DEVICEID_FC939X: 1693 case MPI_MANUFACTPAGE_DEVICEID_FC949X: 1694 ioc->errata_flag_1064 = 1; 1695 case MPI_MANUFACTPAGE_DEVICEID_FC909: 1696 case MPI_MANUFACTPAGE_DEVICEID_FC929: 1697 case MPI_MANUFACTPAGE_DEVICEID_FC919: 1698 case MPI_MANUFACTPAGE_DEVICEID_FC949E: 1699 ioc->bus_type = FC; 1700 break; 1701 1702 case MPI_MANUFACTPAGE_DEVICEID_FC929X: 1703 if (revision < XL_929) { 1704 /* 929X Chip Fix. Set Split transactions level 1705 * for PCIX. Set MOST bits to zero. 1706 */ 1707 pci_read_config_byte(pdev, 0x6a, &pcixcmd); 1708 pcixcmd &= 0x8F; 1709 pci_write_config_byte(pdev, 0x6a, pcixcmd); 1710 } else { 1711 /* 929XL Chip Fix. Set MMRBC to 0x08. 1712 */ 1713 pci_read_config_byte(pdev, 0x6a, &pcixcmd); 1714 pcixcmd |= 0x08; 1715 pci_write_config_byte(pdev, 0x6a, pcixcmd); 1716 } 1717 ioc->bus_type = FC; 1718 break; 1719 1720 case MPI_MANUFACTPAGE_DEVICEID_FC919X: 1721 /* 919X Chip Fix. Set Split transactions level 1722 * for PCIX. Set MOST bits to zero. 1723 */ 1724 pci_read_config_byte(pdev, 0x6a, &pcixcmd); 1725 pcixcmd &= 0x8F; 1726 pci_write_config_byte(pdev, 0x6a, pcixcmd); 1727 ioc->bus_type = FC; 1728 break; 1729 1730 case MPI_MANUFACTPAGE_DEVID_53C1030: 1731 /* 1030 Chip Fix. Disable Split transactions 1732 * for PCIX. Set MOST bits to zero if Rev < C0( = 8). 1733 */ 1734 if (revision < C0_1030) { 1735 pci_read_config_byte(pdev, 0x6a, &pcixcmd); 1736 pcixcmd &= 0x8F; 1737 pci_write_config_byte(pdev, 0x6a, pcixcmd); 1738 } 1739 1740 case MPI_MANUFACTPAGE_DEVID_1030_53C1035: 1741 ioc->bus_type = SPI; 1742 break; 1743 1744 case MPI_MANUFACTPAGE_DEVID_SAS1064: 1745 case MPI_MANUFACTPAGE_DEVID_SAS1068: 1746 ioc->errata_flag_1064 = 1; 1747 1748 case MPI_MANUFACTPAGE_DEVID_SAS1064E: 1749 case MPI_MANUFACTPAGE_DEVID_SAS1068E: 1750 case MPI_MANUFACTPAGE_DEVID_SAS1078: 1751 ioc->bus_type = SAS; 1752 } 1753 1754 if (mpt_msi_enable == -1) { 1755 /* Enable on SAS, disable on FC and SPI */ 1756 if (ioc->bus_type == SAS) 1757 ioc->msi_enable = 1; 1758 else 1759 ioc->msi_enable = 0; 1760 } else 1761 /* follow flag: 0 - disable; 1 - enable */ 1762 ioc->msi_enable = mpt_msi_enable; 1763 1764 if (ioc->errata_flag_1064) 1765 pci_disable_io_access(pdev); 1766 1767 spin_lock_init(&ioc->FreeQlock); 1768 1769 /* Disable all! */ 1770 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 1771 ioc->active = 0; 1772 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1773 1774 /* Set IOC ptr in the pcidev's driver data. */ 1775 pci_set_drvdata(ioc->pcidev, ioc); 1776 1777 /* Set lookup ptr. */ 1778 list_add_tail(&ioc->list, &ioc_list); 1779 1780 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets. 1781 */ 1782 mpt_detect_bound_ports(ioc, pdev); 1783 1784 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, 1785 CAN_SLEEP)) != 0){ 1786 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n", 1787 ioc->name, r); 1788 1789 list_del(&ioc->list); 1790 if (ioc->alt_ioc) 1791 ioc->alt_ioc->alt_ioc = NULL; 1792 iounmap(ioc->memmap); 1793 if (r != -5) 1794 pci_release_selected_regions(pdev, ioc->bars); 1795 1796 destroy_workqueue(ioc->reset_work_q); 1797 ioc->reset_work_q = NULL; 1798 1799 kfree(ioc); 1800 pci_set_drvdata(pdev, NULL); 1801 return r; 1802 } 1803 1804 /* call per device driver probe entry point */ 1805 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) { 1806 if(MptDeviceDriverHandlers[cb_idx] && 1807 MptDeviceDriverHandlers[cb_idx]->probe) { 1808 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id); 1809 } 1810 } 1811 1812 #ifdef CONFIG_PROC_FS 1813 /* 1814 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter. 1815 */ 1816 dent = proc_mkdir(ioc->name, mpt_proc_root_dir); 1817 if (dent) { 1818 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent); 1819 if (ent) { 1820 ent->read_proc = procmpt_iocinfo_read; 1821 ent->data = ioc; 1822 } 1823 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent); 1824 if (ent) { 1825 ent->read_proc = procmpt_summary_read; 1826 ent->data = ioc; 1827 } 1828 } 1829 #endif 1830 1831 if (!ioc->alt_ioc) 1832 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work, 1833 msecs_to_jiffies(MPT_POLLING_INTERVAL)); 1834 1835 return 0; 1836 } 1837 1838 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1839 /** 1840 * mpt_detach - Remove a PCI intelligent MPT adapter. 1841 * @pdev: Pointer to pci_dev structure 1842 */ 1843 1844 void 1845 mpt_detach(struct pci_dev *pdev) 1846 { 1847 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 1848 char pname[32]; 1849 u8 cb_idx; 1850 unsigned long flags; 1851 struct workqueue_struct *wq; 1852 1853 /* 1854 * Stop polling ioc for fault condition 1855 */ 1856 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags); 1857 wq = ioc->reset_work_q; 1858 ioc->reset_work_q = NULL; 1859 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags); 1860 cancel_delayed_work(&ioc->fault_reset_work); 1861 destroy_workqueue(wq); 1862 1863 1864 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name); 1865 remove_proc_entry(pname, NULL); 1866 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name); 1867 remove_proc_entry(pname, NULL); 1868 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name); 1869 remove_proc_entry(pname, NULL); 1870 1871 /* call per device driver remove entry point */ 1872 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) { 1873 if(MptDeviceDriverHandlers[cb_idx] && 1874 MptDeviceDriverHandlers[cb_idx]->remove) { 1875 MptDeviceDriverHandlers[cb_idx]->remove(pdev); 1876 } 1877 } 1878 1879 /* Disable interrupts! */ 1880 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 1881 1882 ioc->active = 0; 1883 synchronize_irq(pdev->irq); 1884 1885 /* Clear any lingering interrupt */ 1886 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1887 1888 CHIPREG_READ32(&ioc->chip->IntStatus); 1889 1890 mpt_adapter_dispose(ioc); 1891 1892 pci_set_drvdata(pdev, NULL); 1893 } 1894 1895 /************************************************************************** 1896 * Power Management 1897 */ 1898 #ifdef CONFIG_PM 1899 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1900 /** 1901 * mpt_suspend - Fusion MPT base driver suspend routine. 1902 * @pdev: Pointer to pci_dev structure 1903 * @state: new state to enter 1904 */ 1905 int 1906 mpt_suspend(struct pci_dev *pdev, pm_message_t state) 1907 { 1908 u32 device_state; 1909 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 1910 1911 device_state = pci_choose_state(pdev, state); 1912 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering " 1913 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev), 1914 device_state); 1915 1916 /* put ioc into READY_STATE */ 1917 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) { 1918 printk(MYIOC_s_ERR_FMT 1919 "pci-suspend: IOC msg unit reset failed!\n", ioc->name); 1920 } 1921 1922 /* disable interrupts */ 1923 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 1924 ioc->active = 0; 1925 1926 /* Clear any lingering interrupt */ 1927 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 1928 1929 free_irq(ioc->pci_irq, ioc); 1930 if (ioc->msi_enable) 1931 pci_disable_msi(ioc->pcidev); 1932 ioc->pci_irq = -1; 1933 pci_save_state(pdev); 1934 pci_disable_device(pdev); 1935 pci_release_selected_regions(pdev, ioc->bars); 1936 pci_set_power_state(pdev, device_state); 1937 return 0; 1938 } 1939 1940 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 1941 /** 1942 * mpt_resume - Fusion MPT base driver resume routine. 1943 * @pdev: Pointer to pci_dev structure 1944 */ 1945 int 1946 mpt_resume(struct pci_dev *pdev) 1947 { 1948 MPT_ADAPTER *ioc = pci_get_drvdata(pdev); 1949 u32 device_state = pdev->current_state; 1950 int recovery_state; 1951 int err; 1952 1953 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous " 1954 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev), 1955 device_state); 1956 1957 pci_set_power_state(pdev, PCI_D0); 1958 pci_enable_wake(pdev, PCI_D0, 0); 1959 pci_restore_state(pdev); 1960 ioc->pcidev = pdev; 1961 err = mpt_mapresources(ioc); 1962 if (err) 1963 return err; 1964 1965 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n", 1966 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT), 1967 CHIPREG_READ32(&ioc->chip->Doorbell)); 1968 1969 /* 1970 * Errata workaround for SAS pci express: 1971 * Upon returning to the D0 state, the contents of the doorbell will be 1972 * stale data, and this will incorrectly signal to the host driver that 1973 * the firmware is ready to process mpt commands. The workaround is 1974 * to issue a diagnostic reset. 1975 */ 1976 if (ioc->bus_type == SAS && (pdev->device == 1977 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device == 1978 MPI_MANUFACTPAGE_DEVID_SAS1064E)) { 1979 if (KickStart(ioc, 1, CAN_SLEEP) < 0) { 1980 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n", 1981 ioc->name); 1982 goto out; 1983 } 1984 } 1985 1986 /* bring ioc to operational state */ 1987 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name); 1988 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP, 1989 CAN_SLEEP); 1990 if (recovery_state != 0) 1991 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, " 1992 "error:[%x]\n", ioc->name, recovery_state); 1993 else 1994 printk(MYIOC_s_INFO_FMT 1995 "pci-resume: success\n", ioc->name); 1996 out: 1997 return 0; 1998 1999 } 2000 #endif 2001 2002 static int 2003 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase) 2004 { 2005 if ((MptDriverClass[index] == MPTSPI_DRIVER && 2006 ioc->bus_type != SPI) || 2007 (MptDriverClass[index] == MPTFC_DRIVER && 2008 ioc->bus_type != FC) || 2009 (MptDriverClass[index] == MPTSAS_DRIVER && 2010 ioc->bus_type != SAS)) 2011 /* make sure we only call the relevant reset handler 2012 * for the bus */ 2013 return 0; 2014 return (MptResetHandlers[index])(ioc, reset_phase); 2015 } 2016 2017 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2018 /** 2019 * mpt_do_ioc_recovery - Initialize or recover MPT adapter. 2020 * @ioc: Pointer to MPT adapter structure 2021 * @reason: Event word / reason 2022 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay. 2023 * 2024 * This routine performs all the steps necessary to bring the IOC 2025 * to a OPERATIONAL state. 2026 * 2027 * This routine also pre-fetches the LAN MAC address of a Fibre Channel 2028 * MPT adapter. 2029 * 2030 * Returns: 2031 * 0 for success 2032 * -1 if failed to get board READY 2033 * -2 if READY but IOCFacts Failed 2034 * -3 if READY but PrimeIOCFifos Failed 2035 * -4 if READY but IOCInit Failed 2036 * -5 if failed to enable_device and/or request_selected_regions 2037 * -6 if failed to upload firmware 2038 */ 2039 static int 2040 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) 2041 { 2042 int hard_reset_done = 0; 2043 int alt_ioc_ready = 0; 2044 int hard; 2045 int rc=0; 2046 int ii; 2047 u8 cb_idx; 2048 int handlers; 2049 int ret = 0; 2050 int reset_alt_ioc_active = 0; 2051 int irq_allocated = 0; 2052 u8 *a; 2053 2054 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name, 2055 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery"); 2056 2057 /* Disable reply interrupts (also blocks FreeQ) */ 2058 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 2059 ioc->active = 0; 2060 2061 if (ioc->alt_ioc) { 2062 if (ioc->alt_ioc->active) 2063 reset_alt_ioc_active = 1; 2064 2065 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */ 2066 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF); 2067 ioc->alt_ioc->active = 0; 2068 } 2069 2070 hard = 1; 2071 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) 2072 hard = 0; 2073 2074 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) { 2075 if (hard_reset_done == -4) { 2076 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n", 2077 ioc->name); 2078 2079 if (reset_alt_ioc_active && ioc->alt_ioc) { 2080 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */ 2081 dprintk(ioc, printk(MYIOC_s_INFO_FMT 2082 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name)); 2083 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM); 2084 ioc->alt_ioc->active = 1; 2085 } 2086 2087 } else { 2088 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name); 2089 } 2090 return -1; 2091 } 2092 2093 /* hard_reset_done = 0 if a soft reset was performed 2094 * and 1 if a hard reset was performed. 2095 */ 2096 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) { 2097 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0) 2098 alt_ioc_ready = 1; 2099 else 2100 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name); 2101 } 2102 2103 for (ii=0; ii<5; ii++) { 2104 /* Get IOC facts! Allow 5 retries */ 2105 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0) 2106 break; 2107 } 2108 2109 2110 if (ii == 5) { 2111 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2112 "Retry IocFacts failed rc=%x\n", ioc->name, rc)); 2113 ret = -2; 2114 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 2115 MptDisplayIocCapabilities(ioc); 2116 } 2117 2118 if (alt_ioc_ready) { 2119 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) { 2120 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2121 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc)); 2122 /* Retry - alt IOC was initialized once 2123 */ 2124 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason); 2125 } 2126 if (rc) { 2127 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2128 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc)); 2129 alt_ioc_ready = 0; 2130 reset_alt_ioc_active = 0; 2131 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 2132 MptDisplayIocCapabilities(ioc->alt_ioc); 2133 } 2134 } 2135 2136 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) && 2137 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) { 2138 pci_release_selected_regions(ioc->pcidev, ioc->bars); 2139 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM | 2140 IORESOURCE_IO); 2141 if (pci_enable_device(ioc->pcidev)) 2142 return -5; 2143 if (pci_request_selected_regions(ioc->pcidev, ioc->bars, 2144 "mpt")) 2145 return -5; 2146 } 2147 2148 /* 2149 * Device is reset now. It must have de-asserted the interrupt line 2150 * (if it was asserted) and it should be safe to register for the 2151 * interrupt now. 2152 */ 2153 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { 2154 ioc->pci_irq = -1; 2155 if (ioc->pcidev->irq) { 2156 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev)) 2157 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n", 2158 ioc->name); 2159 else 2160 ioc->msi_enable = 0; 2161 rc = request_irq(ioc->pcidev->irq, mpt_interrupt, 2162 IRQF_SHARED, ioc->name, ioc); 2163 if (rc < 0) { 2164 printk(MYIOC_s_ERR_FMT "Unable to allocate " 2165 "interrupt %d!\n", ioc->name, ioc->pcidev->irq); 2166 if (ioc->msi_enable) 2167 pci_disable_msi(ioc->pcidev); 2168 return -EBUSY; 2169 } 2170 irq_allocated = 1; 2171 ioc->pci_irq = ioc->pcidev->irq; 2172 pci_set_master(ioc->pcidev); /* ?? */ 2173 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt " 2174 "%d\n", ioc->name, ioc->pcidev->irq)); 2175 } 2176 } 2177 2178 /* Prime reply & request queues! 2179 * (mucho alloc's) Must be done prior to 2180 * init as upper addresses are needed for init. 2181 * If fails, continue with alt-ioc processing 2182 */ 2183 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0)) 2184 ret = -3; 2185 2186 /* May need to check/upload firmware & data here! 2187 * If fails, continue with alt-ioc processing 2188 */ 2189 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0)) 2190 ret = -4; 2191 // NEW! 2192 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) { 2193 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n", 2194 ioc->alt_ioc->name, rc); 2195 alt_ioc_ready = 0; 2196 reset_alt_ioc_active = 0; 2197 } 2198 2199 if (alt_ioc_ready) { 2200 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) { 2201 alt_ioc_ready = 0; 2202 reset_alt_ioc_active = 0; 2203 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n", 2204 ioc->alt_ioc->name, rc); 2205 } 2206 } 2207 2208 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){ 2209 if (ioc->upload_fw) { 2210 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2211 "firmware upload required!\n", ioc->name)); 2212 2213 /* Controller is not operational, cannot do upload 2214 */ 2215 if (ret == 0) { 2216 rc = mpt_do_upload(ioc, sleepFlag); 2217 if (rc == 0) { 2218 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) { 2219 /* 2220 * Maintain only one pointer to FW memory 2221 * so there will not be two attempt to 2222 * downloadboot onboard dual function 2223 * chips (mpt_adapter_disable, 2224 * mpt_diag_reset) 2225 */ 2226 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2227 "mpt_upload: alt_%s has cached_fw=%p \n", 2228 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw)); 2229 ioc->cached_fw = NULL; 2230 } 2231 } else { 2232 printk(MYIOC_s_WARN_FMT 2233 "firmware upload failure!\n", ioc->name); 2234 ret = -6; 2235 } 2236 } 2237 } 2238 } 2239 2240 if (ret == 0) { 2241 /* Enable! (reply interrupt) */ 2242 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); 2243 ioc->active = 1; 2244 } 2245 2246 if (reset_alt_ioc_active && ioc->alt_ioc) { 2247 /* (re)Enable alt-IOC! (reply interrupt) */ 2248 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n", 2249 ioc->alt_ioc->name)); 2250 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM); 2251 ioc->alt_ioc->active = 1; 2252 } 2253 2254 /* Enable MPT base driver management of EventNotification 2255 * and EventAck handling. 2256 */ 2257 if ((ret == 0) && (!ioc->facts.EventState)) 2258 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */ 2259 2260 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState) 2261 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */ 2262 2263 /* Add additional "reason" check before call to GetLanConfigPages 2264 * (combined with GetIoUnitPage2 call). This prevents a somewhat 2265 * recursive scenario; GetLanConfigPages times out, timer expired 2266 * routine calls HardResetHandler, which calls into here again, 2267 * and we try GetLanConfigPages again... 2268 */ 2269 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) { 2270 2271 /* 2272 * Initalize link list for inactive raid volumes. 2273 */ 2274 mutex_init(&ioc->raid_data.inactive_list_mutex); 2275 INIT_LIST_HEAD(&ioc->raid_data.inactive_list); 2276 2277 if (ioc->bus_type == SAS) { 2278 2279 /* clear persistency table */ 2280 if(ioc->facts.IOCExceptions & 2281 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) { 2282 ret = mptbase_sas_persist_operation(ioc, 2283 MPI_SAS_OP_CLEAR_NOT_PRESENT); 2284 if(ret != 0) 2285 goto out; 2286 } 2287 2288 /* Find IM volumes 2289 */ 2290 mpt_findImVolumes(ioc); 2291 2292 } else if (ioc->bus_type == FC) { 2293 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) && 2294 (ioc->lan_cnfg_page0.Header.PageLength == 0)) { 2295 /* 2296 * Pre-fetch the ports LAN MAC address! 2297 * (LANPage1_t stuff) 2298 */ 2299 (void) GetLanConfigPages(ioc); 2300 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; 2301 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2302 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", 2303 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0])); 2304 2305 } 2306 } else { 2307 /* Get NVRAM and adapter maximums from SPP 0 and 2 2308 */ 2309 mpt_GetScsiPortSettings(ioc, 0); 2310 2311 /* Get version and length of SDP 1 2312 */ 2313 mpt_readScsiDevicePageHeaders(ioc, 0); 2314 2315 /* Find IM volumes 2316 */ 2317 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02) 2318 mpt_findImVolumes(ioc); 2319 2320 /* Check, and possibly reset, the coalescing value 2321 */ 2322 mpt_read_ioc_pg_1(ioc); 2323 2324 mpt_read_ioc_pg_4(ioc); 2325 } 2326 2327 GetIoUnitPage2(ioc); 2328 mpt_get_manufacturing_pg_0(ioc); 2329 } 2330 2331 /* 2332 * Call each currently registered protocol IOC reset handler 2333 * with post-reset indication. 2334 * NOTE: If we're doing _IOC_BRINGUP, there can be no 2335 * MptResetHandlers[] registered yet. 2336 */ 2337 if (hard_reset_done) { 2338 rc = handlers = 0; 2339 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 2340 if ((ret == 0) && MptResetHandlers[cb_idx]) { 2341 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2342 "Calling IOC post_reset handler #%d\n", 2343 ioc->name, cb_idx)); 2344 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET); 2345 handlers++; 2346 } 2347 2348 if (alt_ioc_ready && MptResetHandlers[cb_idx]) { 2349 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2350 "Calling IOC post_reset handler #%d\n", 2351 ioc->alt_ioc->name, cb_idx)); 2352 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET); 2353 handlers++; 2354 } 2355 } 2356 /* FIXME? Examine results here? */ 2357 } 2358 2359 out: 2360 if ((ret != 0) && irq_allocated) { 2361 free_irq(ioc->pci_irq, ioc); 2362 if (ioc->msi_enable) 2363 pci_disable_msi(ioc->pcidev); 2364 } 2365 return ret; 2366 } 2367 2368 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2369 /** 2370 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function 2371 * @ioc: Pointer to MPT adapter structure 2372 * @pdev: Pointer to (struct pci_dev) structure 2373 * 2374 * Search for PCI bus/dev_function which matches 2375 * PCI bus/dev_function (+/-1) for newly discovered 929, 2376 * 929X, 1030 or 1035. 2377 * 2378 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters 2379 * using alt_ioc pointer fields in their %MPT_ADAPTER structures. 2380 */ 2381 static void 2382 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev) 2383 { 2384 struct pci_dev *peer=NULL; 2385 unsigned int slot = PCI_SLOT(pdev->devfn); 2386 unsigned int func = PCI_FUNC(pdev->devfn); 2387 MPT_ADAPTER *ioc_srch; 2388 2389 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x," 2390 " searching for devfn match on %x or %x\n", 2391 ioc->name, pci_name(pdev), pdev->bus->number, 2392 pdev->devfn, func-1, func+1)); 2393 2394 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1)); 2395 if (!peer) { 2396 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1)); 2397 if (!peer) 2398 return; 2399 } 2400 2401 list_for_each_entry(ioc_srch, &ioc_list, list) { 2402 struct pci_dev *_pcidev = ioc_srch->pcidev; 2403 if (_pcidev == peer) { 2404 /* Paranoia checks */ 2405 if (ioc->alt_ioc != NULL) { 2406 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n", 2407 ioc->name, ioc->alt_ioc->name); 2408 break; 2409 } else if (ioc_srch->alt_ioc != NULL) { 2410 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n", 2411 ioc_srch->name, ioc_srch->alt_ioc->name); 2412 break; 2413 } 2414 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n", 2415 ioc->name, ioc_srch->name)); 2416 ioc_srch->alt_ioc = ioc; 2417 ioc->alt_ioc = ioc_srch; 2418 } 2419 } 2420 pci_dev_put(peer); 2421 } 2422 2423 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2424 /** 2425 * mpt_adapter_disable - Disable misbehaving MPT adapter. 2426 * @ioc: Pointer to MPT adapter structure 2427 */ 2428 static void 2429 mpt_adapter_disable(MPT_ADAPTER *ioc) 2430 { 2431 int sz; 2432 int ret; 2433 2434 if (ioc->cached_fw != NULL) { 2435 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto " 2436 "adapter\n", __func__, ioc->name)); 2437 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *) 2438 ioc->cached_fw, CAN_SLEEP)) < 0) { 2439 printk(MYIOC_s_WARN_FMT 2440 ": firmware downloadboot failure (%d)!\n", 2441 ioc->name, ret); 2442 } 2443 } 2444 2445 /* Disable adapter interrupts! */ 2446 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF); 2447 ioc->active = 0; 2448 /* Clear any lingering interrupt */ 2449 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 2450 2451 if (ioc->alloc != NULL) { 2452 sz = ioc->alloc_sz; 2453 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n", 2454 ioc->name, ioc->alloc, ioc->alloc_sz)); 2455 pci_free_consistent(ioc->pcidev, sz, 2456 ioc->alloc, ioc->alloc_dma); 2457 ioc->reply_frames = NULL; 2458 ioc->req_frames = NULL; 2459 ioc->alloc = NULL; 2460 ioc->alloc_total -= sz; 2461 } 2462 2463 if (ioc->sense_buf_pool != NULL) { 2464 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); 2465 pci_free_consistent(ioc->pcidev, sz, 2466 ioc->sense_buf_pool, ioc->sense_buf_pool_dma); 2467 ioc->sense_buf_pool = NULL; 2468 ioc->alloc_total -= sz; 2469 } 2470 2471 if (ioc->events != NULL){ 2472 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS); 2473 kfree(ioc->events); 2474 ioc->events = NULL; 2475 ioc->alloc_total -= sz; 2476 } 2477 2478 mpt_free_fw_memory(ioc); 2479 2480 kfree(ioc->spi_data.nvram); 2481 mpt_inactive_raid_list_free(ioc); 2482 kfree(ioc->raid_data.pIocPg2); 2483 kfree(ioc->raid_data.pIocPg3); 2484 ioc->spi_data.nvram = NULL; 2485 ioc->raid_data.pIocPg3 = NULL; 2486 2487 if (ioc->spi_data.pIocPg4 != NULL) { 2488 sz = ioc->spi_data.IocPg4Sz; 2489 pci_free_consistent(ioc->pcidev, sz, 2490 ioc->spi_data.pIocPg4, 2491 ioc->spi_data.IocPg4_dma); 2492 ioc->spi_data.pIocPg4 = NULL; 2493 ioc->alloc_total -= sz; 2494 } 2495 2496 if (ioc->ReqToChain != NULL) { 2497 kfree(ioc->ReqToChain); 2498 kfree(ioc->RequestNB); 2499 ioc->ReqToChain = NULL; 2500 } 2501 2502 kfree(ioc->ChainToChain); 2503 ioc->ChainToChain = NULL; 2504 2505 if (ioc->HostPageBuffer != NULL) { 2506 if((ret = mpt_host_page_access_control(ioc, 2507 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) { 2508 printk(MYIOC_s_ERR_FMT 2509 "host page buffers free failed (%d)!\n", 2510 ioc->name, ret); 2511 } 2512 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n", 2513 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz)); 2514 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz, 2515 ioc->HostPageBuffer, ioc->HostPageBuffer_dma); 2516 ioc->HostPageBuffer = NULL; 2517 ioc->HostPageBuffer_sz = 0; 2518 ioc->alloc_total -= ioc->HostPageBuffer_sz; 2519 } 2520 } 2521 2522 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2523 /** 2524 * mpt_adapter_dispose - Free all resources associated with an MPT adapter 2525 * @ioc: Pointer to MPT adapter structure 2526 * 2527 * This routine unregisters h/w resources and frees all alloc'd memory 2528 * associated with a MPT adapter structure. 2529 */ 2530 static void 2531 mpt_adapter_dispose(MPT_ADAPTER *ioc) 2532 { 2533 int sz_first, sz_last; 2534 2535 if (ioc == NULL) 2536 return; 2537 2538 sz_first = ioc->alloc_total; 2539 2540 mpt_adapter_disable(ioc); 2541 2542 if (ioc->pci_irq != -1) { 2543 free_irq(ioc->pci_irq, ioc); 2544 if (ioc->msi_enable) 2545 pci_disable_msi(ioc->pcidev); 2546 ioc->pci_irq = -1; 2547 } 2548 2549 if (ioc->memmap != NULL) { 2550 iounmap(ioc->memmap); 2551 ioc->memmap = NULL; 2552 } 2553 2554 pci_disable_device(ioc->pcidev); 2555 pci_release_selected_regions(ioc->pcidev, ioc->bars); 2556 2557 #if defined(CONFIG_MTRR) && 0 2558 if (ioc->mtrr_reg > 0) { 2559 mtrr_del(ioc->mtrr_reg, 0, 0); 2560 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name)); 2561 } 2562 #endif 2563 2564 /* Zap the adapter lookup ptr! */ 2565 list_del(&ioc->list); 2566 2567 sz_last = ioc->alloc_total; 2568 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n", 2569 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first)); 2570 2571 if (ioc->alt_ioc) 2572 ioc->alt_ioc->alt_ioc = NULL; 2573 2574 kfree(ioc); 2575 } 2576 2577 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2578 /** 2579 * MptDisplayIocCapabilities - Disply IOC's capabilities. 2580 * @ioc: Pointer to MPT adapter structure 2581 */ 2582 static void 2583 MptDisplayIocCapabilities(MPT_ADAPTER *ioc) 2584 { 2585 int i = 0; 2586 2587 printk(KERN_INFO "%s: ", ioc->name); 2588 if (ioc->prod_name) 2589 printk("%s: ", ioc->prod_name); 2590 printk("Capabilities={"); 2591 2592 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) { 2593 printk("Initiator"); 2594 i++; 2595 } 2596 2597 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) { 2598 printk("%sTarget", i ? "," : ""); 2599 i++; 2600 } 2601 2602 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) { 2603 printk("%sLAN", i ? "," : ""); 2604 i++; 2605 } 2606 2607 #if 0 2608 /* 2609 * This would probably evoke more questions than it's worth 2610 */ 2611 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) { 2612 printk("%sLogBusAddr", i ? "," : ""); 2613 i++; 2614 } 2615 #endif 2616 2617 printk("}\n"); 2618 } 2619 2620 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2621 /** 2622 * MakeIocReady - Get IOC to a READY state, using KickStart if needed. 2623 * @ioc: Pointer to MPT_ADAPTER structure 2624 * @force: Force hard KickStart of IOC 2625 * @sleepFlag: Specifies whether the process can sleep 2626 * 2627 * Returns: 2628 * 1 - DIAG reset and READY 2629 * 0 - READY initially OR soft reset and READY 2630 * -1 - Any failure on KickStart 2631 * -2 - Msg Unit Reset Failed 2632 * -3 - IO Unit Reset Failed 2633 * -4 - IOC owned by a PEER 2634 */ 2635 static int 2636 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag) 2637 { 2638 u32 ioc_state; 2639 int statefault = 0; 2640 int cntdn; 2641 int hard_reset_done = 0; 2642 int r; 2643 int ii; 2644 int whoinit; 2645 2646 /* Get current [raw] IOC state */ 2647 ioc_state = mpt_GetIocState(ioc, 0); 2648 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state)); 2649 2650 /* 2651 * Check to see if IOC got left/stuck in doorbell handshake 2652 * grip of death. If so, hard reset the IOC. 2653 */ 2654 if (ioc_state & MPI_DOORBELL_ACTIVE) { 2655 statefault = 1; 2656 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n", 2657 ioc->name); 2658 } 2659 2660 /* Is it already READY? */ 2661 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY) 2662 return 0; 2663 2664 /* 2665 * Check to see if IOC is in FAULT state. 2666 */ 2667 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { 2668 statefault = 2; 2669 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n", 2670 ioc->name); 2671 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n", 2672 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK); 2673 } 2674 2675 /* 2676 * Hmmm... Did it get left operational? 2677 */ 2678 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) { 2679 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n", 2680 ioc->name)); 2681 2682 /* Check WhoInit. 2683 * If PCI Peer, exit. 2684 * Else, if no fault conditions are present, issue a MessageUnitReset 2685 * Else, fall through to KickStart case 2686 */ 2687 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT; 2688 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT 2689 "whoinit 0x%x statefault %d force %d\n", 2690 ioc->name, whoinit, statefault, force)); 2691 if (whoinit == MPI_WHOINIT_PCI_PEER) 2692 return -4; 2693 else { 2694 if ((statefault == 0 ) && (force == 0)) { 2695 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0) 2696 return 0; 2697 } 2698 statefault = 3; 2699 } 2700 } 2701 2702 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag); 2703 if (hard_reset_done < 0) 2704 return -1; 2705 2706 /* 2707 * Loop here waiting for IOC to come READY. 2708 */ 2709 ii = 0; 2710 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */ 2711 2712 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) { 2713 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) { 2714 /* 2715 * BIOS or previous driver load left IOC in OP state. 2716 * Reset messaging FIFOs. 2717 */ 2718 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) { 2719 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name); 2720 return -2; 2721 } 2722 } else if (ioc_state == MPI_IOC_STATE_RESET) { 2723 /* 2724 * Something is wrong. Try to get IOC back 2725 * to a known state. 2726 */ 2727 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) { 2728 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name); 2729 return -3; 2730 } 2731 } 2732 2733 ii++; cntdn--; 2734 if (!cntdn) { 2735 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n", 2736 ioc->name, (int)((ii+5)/HZ)); 2737 return -ETIME; 2738 } 2739 2740 if (sleepFlag == CAN_SLEEP) { 2741 msleep(1); 2742 } else { 2743 mdelay (1); /* 1 msec delay */ 2744 } 2745 2746 } 2747 2748 if (statefault < 3) { 2749 printk(MYIOC_s_INFO_FMT "Recovered from %s\n", 2750 ioc->name, 2751 statefault==1 ? "stuck handshake" : "IOC FAULT"); 2752 } 2753 2754 return hard_reset_done; 2755 } 2756 2757 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2758 /** 2759 * mpt_GetIocState - Get the current state of a MPT adapter. 2760 * @ioc: Pointer to MPT_ADAPTER structure 2761 * @cooked: Request raw or cooked IOC state 2762 * 2763 * Returns all IOC Doorbell register bits if cooked==0, else just the 2764 * Doorbell bits in MPI_IOC_STATE_MASK. 2765 */ 2766 u32 2767 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked) 2768 { 2769 u32 s, sc; 2770 2771 /* Get! */ 2772 s = CHIPREG_READ32(&ioc->chip->Doorbell); 2773 sc = s & MPI_IOC_STATE_MASK; 2774 2775 /* Save! */ 2776 ioc->last_state = sc; 2777 2778 return cooked ? sc : s; 2779 } 2780 2781 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2782 /** 2783 * GetIocFacts - Send IOCFacts request to MPT adapter. 2784 * @ioc: Pointer to MPT_ADAPTER structure 2785 * @sleepFlag: Specifies whether the process can sleep 2786 * @reason: If recovery, only update facts. 2787 * 2788 * Returns 0 for success, non-zero for failure. 2789 */ 2790 static int 2791 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason) 2792 { 2793 IOCFacts_t get_facts; 2794 IOCFactsReply_t *facts; 2795 int r; 2796 int req_sz; 2797 int reply_sz; 2798 int sz; 2799 u32 status, vv; 2800 u8 shiftFactor=1; 2801 2802 /* IOC *must* NOT be in RESET state! */ 2803 if (ioc->last_state == MPI_IOC_STATE_RESET) { 2804 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n", 2805 ioc->name, ioc->last_state ); 2806 return -44; 2807 } 2808 2809 facts = &ioc->facts; 2810 2811 /* Destination (reply area)... */ 2812 reply_sz = sizeof(*facts); 2813 memset(facts, 0, reply_sz); 2814 2815 /* Request area (get_facts on the stack right now!) */ 2816 req_sz = sizeof(get_facts); 2817 memset(&get_facts, 0, req_sz); 2818 2819 get_facts.Function = MPI_FUNCTION_IOC_FACTS; 2820 /* Assert: All other get_facts fields are zero! */ 2821 2822 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2823 "Sending get IocFacts request req_sz=%d reply_sz=%d\n", 2824 ioc->name, req_sz, reply_sz)); 2825 2826 /* No non-zero fields in the get_facts request are greater than 2827 * 1 byte in size, so we can just fire it off as is. 2828 */ 2829 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts, 2830 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag); 2831 if (r != 0) 2832 return r; 2833 2834 /* 2835 * Now byte swap (GRRR) the necessary fields before any further 2836 * inspection of reply contents. 2837 * 2838 * But need to do some sanity checks on MsgLength (byte) field 2839 * to make sure we don't zero IOC's req_sz! 2840 */ 2841 /* Did we get a valid reply? */ 2842 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) { 2843 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 2844 /* 2845 * If not been here, done that, save off first WhoInit value 2846 */ 2847 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN) 2848 ioc->FirstWhoInit = facts->WhoInit; 2849 } 2850 2851 facts->MsgVersion = le16_to_cpu(facts->MsgVersion); 2852 facts->MsgContext = le32_to_cpu(facts->MsgContext); 2853 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions); 2854 facts->IOCStatus = le16_to_cpu(facts->IOCStatus); 2855 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo); 2856 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK; 2857 /* CHECKME! IOCStatus, IOCLogInfo */ 2858 2859 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth); 2860 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize); 2861 2862 /* 2863 * FC f/w version changed between 1.1 and 1.2 2864 * Old: u16{Major(4),Minor(4),SubMinor(8)} 2865 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)} 2866 */ 2867 if (facts->MsgVersion < 0x0102) { 2868 /* 2869 * Handle old FC f/w style, convert to new... 2870 */ 2871 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion); 2872 facts->FWVersion.Word = 2873 ((oldv<<12) & 0xFF000000) | 2874 ((oldv<<8) & 0x000FFF00); 2875 } else 2876 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word); 2877 2878 facts->ProductID = le16_to_cpu(facts->ProductID); 2879 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK) 2880 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI) 2881 ioc->ir_firmware = 1; 2882 facts->CurrentHostMfaHighAddr = 2883 le32_to_cpu(facts->CurrentHostMfaHighAddr); 2884 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits); 2885 facts->CurrentSenseBufferHighAddr = 2886 le32_to_cpu(facts->CurrentSenseBufferHighAddr); 2887 facts->CurReplyFrameSize = 2888 le16_to_cpu(facts->CurReplyFrameSize); 2889 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities); 2890 2891 /* 2892 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx 2893 * Older MPI-1.00.xx struct had 13 dwords, and enlarged 2894 * to 14 in MPI-1.01.0x. 2895 */ 2896 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 && 2897 facts->MsgVersion > 0x0100) { 2898 facts->FWImageSize = le32_to_cpu(facts->FWImageSize); 2899 } 2900 2901 sz = facts->FWImageSize; 2902 if ( sz & 0x01 ) 2903 sz += 1; 2904 if ( sz & 0x02 ) 2905 sz += 2; 2906 facts->FWImageSize = sz; 2907 2908 if (!facts->RequestFrameSize) { 2909 /* Something is wrong! */ 2910 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n", 2911 ioc->name); 2912 return -55; 2913 } 2914 2915 r = sz = facts->BlockSize; 2916 vv = ((63 / (sz * 4)) + 1) & 0x03; 2917 ioc->NB_for_64_byte_frame = vv; 2918 while ( sz ) 2919 { 2920 shiftFactor++; 2921 sz = sz >> 1; 2922 } 2923 ioc->NBShiftFactor = shiftFactor; 2924 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT 2925 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n", 2926 ioc->name, vv, shiftFactor, r)); 2927 2928 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) { 2929 /* 2930 * Set values for this IOC's request & reply frame sizes, 2931 * and request & reply queue depths... 2932 */ 2933 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4); 2934 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits); 2935 ioc->reply_sz = MPT_REPLY_FRAME_SIZE; 2936 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth); 2937 2938 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n", 2939 ioc->name, ioc->reply_sz, ioc->reply_depth)); 2940 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n", 2941 ioc->name, ioc->req_sz, ioc->req_depth)); 2942 2943 /* Get port facts! */ 2944 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 ) 2945 return r; 2946 } 2947 } else { 2948 printk(MYIOC_s_ERR_FMT 2949 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n", 2950 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t, 2951 RequestFrameSize)/sizeof(u32))); 2952 return -66; 2953 } 2954 2955 return 0; 2956 } 2957 2958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 2959 /** 2960 * GetPortFacts - Send PortFacts request to MPT adapter. 2961 * @ioc: Pointer to MPT_ADAPTER structure 2962 * @portnum: Port number 2963 * @sleepFlag: Specifies whether the process can sleep 2964 * 2965 * Returns 0 for success, non-zero for failure. 2966 */ 2967 static int 2968 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag) 2969 { 2970 PortFacts_t get_pfacts; 2971 PortFactsReply_t *pfacts; 2972 int ii; 2973 int req_sz; 2974 int reply_sz; 2975 int max_id; 2976 2977 /* IOC *must* NOT be in RESET state! */ 2978 if (ioc->last_state == MPI_IOC_STATE_RESET) { 2979 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n", 2980 ioc->name, ioc->last_state ); 2981 return -4; 2982 } 2983 2984 pfacts = &ioc->pfacts[portnum]; 2985 2986 /* Destination (reply area)... */ 2987 reply_sz = sizeof(*pfacts); 2988 memset(pfacts, 0, reply_sz); 2989 2990 /* Request area (get_pfacts on the stack right now!) */ 2991 req_sz = sizeof(get_pfacts); 2992 memset(&get_pfacts, 0, req_sz); 2993 2994 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS; 2995 get_pfacts.PortNumber = portnum; 2996 /* Assert: All other get_pfacts fields are zero! */ 2997 2998 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n", 2999 ioc->name, portnum)); 3000 3001 /* No non-zero fields in the get_pfacts request are greater than 3002 * 1 byte in size, so we can just fire it off as is. 3003 */ 3004 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts, 3005 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag); 3006 if (ii != 0) 3007 return ii; 3008 3009 /* Did we get a valid reply? */ 3010 3011 /* Now byte swap the necessary fields in the response. */ 3012 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext); 3013 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus); 3014 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo); 3015 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices); 3016 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID); 3017 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags); 3018 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers); 3019 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs); 3020 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets); 3021 3022 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID : 3023 pfacts->MaxDevices; 3024 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id; 3025 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256; 3026 3027 /* 3028 * Place all the devices on channels 3029 * 3030 * (for debuging) 3031 */ 3032 if (mpt_channel_mapping) { 3033 ioc->devices_per_bus = 1; 3034 ioc->number_of_buses = (max_id > 255) ? 255 : max_id; 3035 } 3036 3037 return 0; 3038 } 3039 3040 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3041 /** 3042 * SendIocInit - Send IOCInit request to MPT adapter. 3043 * @ioc: Pointer to MPT_ADAPTER structure 3044 * @sleepFlag: Specifies whether the process can sleep 3045 * 3046 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state. 3047 * 3048 * Returns 0 for success, non-zero for failure. 3049 */ 3050 static int 3051 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag) 3052 { 3053 IOCInit_t ioc_init; 3054 MPIDefaultReply_t init_reply; 3055 u32 state; 3056 int r; 3057 int count; 3058 int cntdn; 3059 3060 memset(&ioc_init, 0, sizeof(ioc_init)); 3061 memset(&init_reply, 0, sizeof(init_reply)); 3062 3063 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER; 3064 ioc_init.Function = MPI_FUNCTION_IOC_INIT; 3065 3066 /* If we are in a recovery mode and we uploaded the FW image, 3067 * then this pointer is not NULL. Skip the upload a second time. 3068 * Set this flag if cached_fw set for either IOC. 3069 */ 3070 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) 3071 ioc->upload_fw = 1; 3072 else 3073 ioc->upload_fw = 0; 3074 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n", 3075 ioc->name, ioc->upload_fw, ioc->facts.Flags)); 3076 3077 ioc_init.MaxDevices = (U8)ioc->devices_per_bus; 3078 ioc_init.MaxBuses = (U8)ioc->number_of_buses; 3079 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n", 3080 ioc->name, ioc->facts.MsgVersion)); 3081 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) { 3082 // set MsgVersion and HeaderVersion host driver was built with 3083 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION); 3084 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION); 3085 3086 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) { 3087 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE; 3088 } else if(mpt_host_page_alloc(ioc, &ioc_init)) 3089 return -99; 3090 } 3091 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */ 3092 3093 if (sizeof(dma_addr_t) == sizeof(u64)) { 3094 /* Save the upper 32-bits of the request 3095 * (reply) and sense buffers. 3096 */ 3097 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32)); 3098 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32)); 3099 } else { 3100 /* Force 32-bit addressing */ 3101 ioc_init.HostMfaHighAddr = cpu_to_le32(0); 3102 ioc_init.SenseBufferHighAddr = cpu_to_le32(0); 3103 } 3104 3105 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr; 3106 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr; 3107 ioc->facts.MaxDevices = ioc_init.MaxDevices; 3108 ioc->facts.MaxBuses = ioc_init.MaxBuses; 3109 3110 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n", 3111 ioc->name, &ioc_init)); 3112 3113 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init, 3114 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag); 3115 if (r != 0) { 3116 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r); 3117 return r; 3118 } 3119 3120 /* No need to byte swap the multibyte fields in the reply 3121 * since we don't even look at its contents. 3122 */ 3123 3124 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n", 3125 ioc->name, &ioc_init)); 3126 3127 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) { 3128 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r); 3129 return r; 3130 } 3131 3132 /* YIKES! SUPER IMPORTANT!!! 3133 * Poll IocState until _OPERATIONAL while IOC is doing 3134 * LoopInit and TargetDiscovery! 3135 */ 3136 count = 0; 3137 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */ 3138 state = mpt_GetIocState(ioc, 1); 3139 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) { 3140 if (sleepFlag == CAN_SLEEP) { 3141 msleep(1); 3142 } else { 3143 mdelay(1); 3144 } 3145 3146 if (!cntdn) { 3147 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n", 3148 ioc->name, (int)((count+5)/HZ)); 3149 return -9; 3150 } 3151 3152 state = mpt_GetIocState(ioc, 1); 3153 count++; 3154 } 3155 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n", 3156 ioc->name, count)); 3157 3158 ioc->aen_event_read_flag=0; 3159 return r; 3160 } 3161 3162 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3163 /** 3164 * SendPortEnable - Send PortEnable request to MPT adapter port. 3165 * @ioc: Pointer to MPT_ADAPTER structure 3166 * @portnum: Port number to enable 3167 * @sleepFlag: Specifies whether the process can sleep 3168 * 3169 * Send PortEnable to bring IOC to OPERATIONAL state. 3170 * 3171 * Returns 0 for success, non-zero for failure. 3172 */ 3173 static int 3174 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag) 3175 { 3176 PortEnable_t port_enable; 3177 MPIDefaultReply_t reply_buf; 3178 int rc; 3179 int req_sz; 3180 int reply_sz; 3181 3182 /* Destination... */ 3183 reply_sz = sizeof(MPIDefaultReply_t); 3184 memset(&reply_buf, 0, reply_sz); 3185 3186 req_sz = sizeof(PortEnable_t); 3187 memset(&port_enable, 0, req_sz); 3188 3189 port_enable.Function = MPI_FUNCTION_PORT_ENABLE; 3190 port_enable.PortNumber = portnum; 3191 /* port_enable.ChainOffset = 0; */ 3192 /* port_enable.MsgFlags = 0; */ 3193 /* port_enable.MsgContext = 0; */ 3194 3195 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n", 3196 ioc->name, portnum, &port_enable)); 3197 3198 /* RAID FW may take a long time to enable 3199 */ 3200 if (ioc->ir_firmware || ioc->bus_type == SAS) { 3201 rc = mpt_handshake_req_reply_wait(ioc, req_sz, 3202 (u32*)&port_enable, reply_sz, (u16*)&reply_buf, 3203 300 /*seconds*/, sleepFlag); 3204 } else { 3205 rc = mpt_handshake_req_reply_wait(ioc, req_sz, 3206 (u32*)&port_enable, reply_sz, (u16*)&reply_buf, 3207 30 /*seconds*/, sleepFlag); 3208 } 3209 return rc; 3210 } 3211 3212 /** 3213 * mpt_alloc_fw_memory - allocate firmware memory 3214 * @ioc: Pointer to MPT_ADAPTER structure 3215 * @size: total FW bytes 3216 * 3217 * If memory has already been allocated, the same (cached) value 3218 * is returned. 3219 * 3220 * Return 0 if successfull, or non-zero for failure 3221 **/ 3222 int 3223 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size) 3224 { 3225 int rc; 3226 3227 if (ioc->cached_fw) { 3228 rc = 0; /* use already allocated memory */ 3229 goto out; 3230 } 3231 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) { 3232 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */ 3233 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma; 3234 rc = 0; 3235 goto out; 3236 } 3237 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma); 3238 if (!ioc->cached_fw) { 3239 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n", 3240 ioc->name); 3241 rc = -1; 3242 } else { 3243 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n", 3244 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size)); 3245 ioc->alloc_total += size; 3246 rc = 0; 3247 } 3248 out: 3249 return rc; 3250 } 3251 3252 /** 3253 * mpt_free_fw_memory - free firmware memory 3254 * @ioc: Pointer to MPT_ADAPTER structure 3255 * 3256 * If alt_img is NULL, delete from ioc structure. 3257 * Else, delete a secondary image in same format. 3258 **/ 3259 void 3260 mpt_free_fw_memory(MPT_ADAPTER *ioc) 3261 { 3262 int sz; 3263 3264 if (!ioc->cached_fw) 3265 return; 3266 3267 sz = ioc->facts.FWImageSize; 3268 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n", 3269 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); 3270 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma); 3271 ioc->alloc_total -= sz; 3272 ioc->cached_fw = NULL; 3273 } 3274 3275 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3276 /** 3277 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port. 3278 * @ioc: Pointer to MPT_ADAPTER structure 3279 * @sleepFlag: Specifies whether the process can sleep 3280 * 3281 * Returns 0 for success, >0 for handshake failure 3282 * <0 for fw upload failure. 3283 * 3284 * Remark: If bound IOC and a successful FWUpload was performed 3285 * on the bound IOC, the second image is discarded 3286 * and memory is free'd. Both channels must upload to prevent 3287 * IOC from running in degraded mode. 3288 */ 3289 static int 3290 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag) 3291 { 3292 u8 reply[sizeof(FWUploadReply_t)]; 3293 FWUpload_t *prequest; 3294 FWUploadReply_t *preply; 3295 FWUploadTCSGE_t *ptcsge; 3296 int sgeoffset; 3297 u32 flagsLength; 3298 int ii, sz, reply_sz; 3299 int cmdStatus; 3300 3301 /* If the image size is 0, we are done. 3302 */ 3303 if ((sz = ioc->facts.FWImageSize) == 0) 3304 return 0; 3305 3306 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0) 3307 return -ENOMEM; 3308 3309 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n", 3310 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz)); 3311 3312 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) : 3313 kzalloc(ioc->req_sz, GFP_KERNEL); 3314 if (!prequest) { 3315 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed " 3316 "while allocating memory \n", ioc->name)); 3317 mpt_free_fw_memory(ioc); 3318 return -ENOMEM; 3319 } 3320 3321 preply = (FWUploadReply_t *)&reply; 3322 3323 reply_sz = sizeof(reply); 3324 memset(preply, 0, reply_sz); 3325 3326 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM; 3327 prequest->Function = MPI_FUNCTION_FW_UPLOAD; 3328 3329 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL; 3330 ptcsge->DetailsLength = 12; 3331 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT; 3332 ptcsge->ImageSize = cpu_to_le32(sz); 3333 ptcsge++; 3334 3335 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t); 3336 3337 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz; 3338 mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma); 3339 3340 sgeoffset += sizeof(u32) + sizeof(dma_addr_t); 3341 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n", 3342 ioc->name, prequest, sgeoffset)); 3343 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest); 3344 3345 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest, 3346 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag); 3347 3348 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii)); 3349 3350 cmdStatus = -EFAULT; 3351 if (ii == 0) { 3352 /* Handshake transfer was complete and successful. 3353 * Check the Reply Frame. 3354 */ 3355 int status, transfer_sz; 3356 status = le16_to_cpu(preply->IOCStatus); 3357 if (status == MPI_IOCSTATUS_SUCCESS) { 3358 transfer_sz = le32_to_cpu(preply->ActualImageSize); 3359 if (transfer_sz == sz) 3360 cmdStatus = 0; 3361 } 3362 } 3363 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n", 3364 ioc->name, cmdStatus)); 3365 3366 3367 if (cmdStatus) { 3368 3369 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n", 3370 ioc->name)); 3371 mpt_free_fw_memory(ioc); 3372 } 3373 kfree(prequest); 3374 3375 return cmdStatus; 3376 } 3377 3378 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3379 /** 3380 * mpt_downloadboot - DownloadBoot code 3381 * @ioc: Pointer to MPT_ADAPTER structure 3382 * @pFwHeader: Pointer to firmware header info 3383 * @sleepFlag: Specifies whether the process can sleep 3384 * 3385 * FwDownloadBoot requires Programmed IO access. 3386 * 3387 * Returns 0 for success 3388 * -1 FW Image size is 0 3389 * -2 No valid cached_fw Pointer 3390 * <0 for fw upload failure. 3391 */ 3392 static int 3393 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag) 3394 { 3395 MpiExtImageHeader_t *pExtImage; 3396 u32 fwSize; 3397 u32 diag0val; 3398 int count; 3399 u32 *ptrFw; 3400 u32 diagRwData; 3401 u32 nextImage; 3402 u32 load_addr; 3403 u32 ioc_state=0; 3404 3405 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n", 3406 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader)); 3407 3408 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3409 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 3410 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); 3411 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); 3412 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); 3413 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); 3414 3415 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM)); 3416 3417 /* wait 1 msec */ 3418 if (sleepFlag == CAN_SLEEP) { 3419 msleep(1); 3420 } else { 3421 mdelay (1); 3422 } 3423 3424 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3425 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER); 3426 3427 for (count = 0; count < 30; count ++) { 3428 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3429 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) { 3430 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n", 3431 ioc->name, count)); 3432 break; 3433 } 3434 /* wait .1 sec */ 3435 if (sleepFlag == CAN_SLEEP) { 3436 msleep (100); 3437 } else { 3438 mdelay (100); 3439 } 3440 } 3441 3442 if ( count == 30 ) { 3443 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! " 3444 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n", 3445 ioc->name, diag0val)); 3446 return -3; 3447 } 3448 3449 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3450 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 3451 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); 3452 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); 3453 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); 3454 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); 3455 3456 /* Set the DiagRwEn and Disable ARM bits */ 3457 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM)); 3458 3459 fwSize = (pFwHeader->ImageSize + 3)/4; 3460 ptrFw = (u32 *) pFwHeader; 3461 3462 /* Write the LoadStartAddress to the DiagRw Address Register 3463 * using Programmed IO 3464 */ 3465 if (ioc->errata_flag_1064) 3466 pci_enable_io_access(ioc->pcidev); 3467 3468 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress); 3469 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n", 3470 ioc->name, pFwHeader->LoadStartAddress)); 3471 3472 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n", 3473 ioc->name, fwSize*4, ptrFw)); 3474 while (fwSize--) { 3475 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++); 3476 } 3477 3478 nextImage = pFwHeader->NextImageHeaderOffset; 3479 while (nextImage) { 3480 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage); 3481 3482 load_addr = pExtImage->LoadStartAddress; 3483 3484 fwSize = (pExtImage->ImageSize + 3) >> 2; 3485 ptrFw = (u32 *)pExtImage; 3486 3487 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n", 3488 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr)); 3489 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr); 3490 3491 while (fwSize--) { 3492 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++); 3493 } 3494 nextImage = pExtImage->NextImageHeaderOffset; 3495 } 3496 3497 /* Write the IopResetVectorRegAddr */ 3498 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr)); 3499 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr); 3500 3501 /* Write the IopResetVectorValue */ 3502 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue)); 3503 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue); 3504 3505 /* Clear the internal flash bad bit - autoincrementing register, 3506 * so must do two writes. 3507 */ 3508 if (ioc->bus_type == SPI) { 3509 /* 3510 * 1030 and 1035 H/W errata, workaround to access 3511 * the ClearFlashBadSignatureBit 3512 */ 3513 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000); 3514 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData); 3515 diagRwData |= 0x40000000; 3516 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000); 3517 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData); 3518 3519 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ { 3520 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3521 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | 3522 MPI_DIAG_CLEAR_FLASH_BAD_SIG); 3523 3524 /* wait 1 msec */ 3525 if (sleepFlag == CAN_SLEEP) { 3526 msleep (1); 3527 } else { 3528 mdelay (1); 3529 } 3530 } 3531 3532 if (ioc->errata_flag_1064) 3533 pci_disable_io_access(ioc->pcidev); 3534 3535 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3536 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, " 3537 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n", 3538 ioc->name, diag0val)); 3539 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE); 3540 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n", 3541 ioc->name, diag0val)); 3542 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val); 3543 3544 /* Write 0xFF to reset the sequencer */ 3545 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3546 3547 if (ioc->bus_type == SAS) { 3548 ioc_state = mpt_GetIocState(ioc, 0); 3549 if ( (GetIocFacts(ioc, sleepFlag, 3550 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) { 3551 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n", 3552 ioc->name, ioc_state)); 3553 return -EFAULT; 3554 } 3555 } 3556 3557 for (count=0; count<HZ*20; count++) { 3558 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) { 3559 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3560 "downloadboot successful! (count=%d) IocState=%x\n", 3561 ioc->name, count, ioc_state)); 3562 if (ioc->bus_type == SAS) { 3563 return 0; 3564 } 3565 if ((SendIocInit(ioc, sleepFlag)) != 0) { 3566 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3567 "downloadboot: SendIocInit failed\n", 3568 ioc->name)); 3569 return -EFAULT; 3570 } 3571 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3572 "downloadboot: SendIocInit successful\n", 3573 ioc->name)); 3574 return 0; 3575 } 3576 if (sleepFlag == CAN_SLEEP) { 3577 msleep (10); 3578 } else { 3579 mdelay (10); 3580 } 3581 } 3582 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3583 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state)); 3584 return -EFAULT; 3585 } 3586 3587 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3588 /** 3589 * KickStart - Perform hard reset of MPT adapter. 3590 * @ioc: Pointer to MPT_ADAPTER structure 3591 * @force: Force hard reset 3592 * @sleepFlag: Specifies whether the process can sleep 3593 * 3594 * This routine places MPT adapter in diagnostic mode via the 3595 * WriteSequence register, and then performs a hard reset of adapter 3596 * via the Diagnostic register. 3597 * 3598 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread) 3599 * or NO_SLEEP (interrupt thread, use mdelay) 3600 * force - 1 if doorbell active, board fault state 3601 * board operational, IOC_RECOVERY or 3602 * IOC_BRINGUP and there is an alt_ioc. 3603 * 0 else 3604 * 3605 * Returns: 3606 * 1 - hard reset, READY 3607 * 0 - no reset due to History bit, READY 3608 * -1 - no reset due to History bit but not READY 3609 * OR reset but failed to come READY 3610 * -2 - no reset, could not enter DIAG mode 3611 * -3 - reset but bad FW bit 3612 */ 3613 static int 3614 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag) 3615 { 3616 int hard_reset_done = 0; 3617 u32 ioc_state=0; 3618 int cnt,cntdn; 3619 3620 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name)); 3621 if (ioc->bus_type == SPI) { 3622 /* Always issue a Msg Unit Reset first. This will clear some 3623 * SCSI bus hang conditions. 3624 */ 3625 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag); 3626 3627 if (sleepFlag == CAN_SLEEP) { 3628 msleep (1000); 3629 } else { 3630 mdelay (1000); 3631 } 3632 } 3633 3634 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag); 3635 if (hard_reset_done < 0) 3636 return hard_reset_done; 3637 3638 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n", 3639 ioc->name)); 3640 3641 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */ 3642 for (cnt=0; cnt<cntdn; cnt++) { 3643 ioc_state = mpt_GetIocState(ioc, 1); 3644 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) { 3645 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n", 3646 ioc->name, cnt)); 3647 return hard_reset_done; 3648 } 3649 if (sleepFlag == CAN_SLEEP) { 3650 msleep (10); 3651 } else { 3652 mdelay (10); 3653 } 3654 } 3655 3656 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n", 3657 ioc->name, mpt_GetIocState(ioc, 0))); 3658 return -1; 3659 } 3660 3661 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3662 /** 3663 * mpt_diag_reset - Perform hard reset of the adapter. 3664 * @ioc: Pointer to MPT_ADAPTER structure 3665 * @ignore: Set if to honor and clear to ignore 3666 * the reset history bit 3667 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread, 3668 * else set to NO_SLEEP (use mdelay instead) 3669 * 3670 * This routine places the adapter in diagnostic mode via the 3671 * WriteSequence register and then performs a hard reset of adapter 3672 * via the Diagnostic register. Adapter should be in ready state 3673 * upon successful completion. 3674 * 3675 * Returns: 1 hard reset successful 3676 * 0 no reset performed because reset history bit set 3677 * -2 enabling diagnostic mode failed 3678 * -3 diagnostic reset failed 3679 */ 3680 static int 3681 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag) 3682 { 3683 u32 diag0val; 3684 u32 doorbell; 3685 int hard_reset_done = 0; 3686 int count = 0; 3687 u32 diag1val = 0; 3688 MpiFwHeader_t *cached_fw; /* Pointer to FW */ 3689 3690 /* Clear any existing interrupts */ 3691 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 3692 3693 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) { 3694 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset " 3695 "address=%p\n", ioc->name, __func__, 3696 &ioc->chip->Doorbell, &ioc->chip->Reset_1078)); 3697 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07); 3698 if (sleepFlag == CAN_SLEEP) 3699 msleep(1); 3700 else 3701 mdelay(1); 3702 3703 for (count = 0; count < 60; count ++) { 3704 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); 3705 doorbell &= MPI_IOC_STATE_MASK; 3706 3707 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3708 "looking for READY STATE: doorbell=%x" 3709 " count=%d\n", 3710 ioc->name, doorbell, count)); 3711 if (doorbell == MPI_IOC_STATE_READY) { 3712 return 1; 3713 } 3714 3715 /* wait 1 sec */ 3716 if (sleepFlag == CAN_SLEEP) 3717 msleep(1000); 3718 else 3719 mdelay(1000); 3720 } 3721 return -1; 3722 } 3723 3724 /* Use "Diagnostic reset" method! (only thing available!) */ 3725 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3726 3727 if (ioc->debug_level & MPT_DEBUG) { 3728 if (ioc->alt_ioc) 3729 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); 3730 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n", 3731 ioc->name, diag0val, diag1val)); 3732 } 3733 3734 /* Do the reset if we are told to ignore the reset history 3735 * or if the reset history is 0 3736 */ 3737 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) { 3738 while ((diag0val & MPI_DIAG_DRWE) == 0) { 3739 /* Write magic sequence to WriteSequence register 3740 * Loop until in diagnostic mode 3741 */ 3742 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3743 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 3744 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); 3745 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); 3746 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); 3747 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); 3748 3749 /* wait 100 msec */ 3750 if (sleepFlag == CAN_SLEEP) { 3751 msleep (100); 3752 } else { 3753 mdelay (100); 3754 } 3755 3756 count++; 3757 if (count > 20) { 3758 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n", 3759 ioc->name, diag0val); 3760 return -2; 3761 3762 } 3763 3764 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3765 3766 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n", 3767 ioc->name, diag0val)); 3768 } 3769 3770 if (ioc->debug_level & MPT_DEBUG) { 3771 if (ioc->alt_ioc) 3772 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); 3773 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n", 3774 ioc->name, diag0val, diag1val)); 3775 } 3776 /* 3777 * Disable the ARM (Bug fix) 3778 * 3779 */ 3780 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM); 3781 mdelay(1); 3782 3783 /* 3784 * Now hit the reset bit in the Diagnostic register 3785 * (THE BIG HAMMER!) (Clears DRWE bit). 3786 */ 3787 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER); 3788 hard_reset_done = 1; 3789 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n", 3790 ioc->name)); 3791 3792 /* 3793 * Call each currently registered protocol IOC reset handler 3794 * with pre-reset indication. 3795 * NOTE: If we're doing _IOC_BRINGUP, there can be no 3796 * MptResetHandlers[] registered yet. 3797 */ 3798 { 3799 u8 cb_idx; 3800 int r = 0; 3801 3802 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 3803 if (MptResetHandlers[cb_idx]) { 3804 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3805 "Calling IOC pre_reset handler #%d\n", 3806 ioc->name, cb_idx)); 3807 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET); 3808 if (ioc->alt_ioc) { 3809 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 3810 "Calling alt-%s pre_reset handler #%d\n", 3811 ioc->name, ioc->alt_ioc->name, cb_idx)); 3812 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET); 3813 } 3814 } 3815 } 3816 /* FIXME? Examine results here? */ 3817 } 3818 3819 if (ioc->cached_fw) 3820 cached_fw = (MpiFwHeader_t *)ioc->cached_fw; 3821 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) 3822 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw; 3823 else 3824 cached_fw = NULL; 3825 if (cached_fw) { 3826 /* If the DownloadBoot operation fails, the 3827 * IOC will be left unusable. This is a fatal error 3828 * case. _diag_reset will return < 0 3829 */ 3830 for (count = 0; count < 30; count ++) { 3831 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3832 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) { 3833 break; 3834 } 3835 3836 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n", 3837 ioc->name, diag0val, count)); 3838 /* wait 1 sec */ 3839 if (sleepFlag == CAN_SLEEP) { 3840 msleep (1000); 3841 } else { 3842 mdelay (1000); 3843 } 3844 } 3845 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) { 3846 printk(MYIOC_s_WARN_FMT 3847 "firmware downloadboot failure (%d)!\n", ioc->name, count); 3848 } 3849 3850 } else { 3851 /* Wait for FW to reload and for board 3852 * to go to the READY state. 3853 * Maximum wait is 60 seconds. 3854 * If fail, no error will check again 3855 * with calling program. 3856 */ 3857 for (count = 0; count < 60; count ++) { 3858 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell); 3859 doorbell &= MPI_IOC_STATE_MASK; 3860 3861 if (doorbell == MPI_IOC_STATE_READY) { 3862 break; 3863 } 3864 3865 /* wait 1 sec */ 3866 if (sleepFlag == CAN_SLEEP) { 3867 msleep (1000); 3868 } else { 3869 mdelay (1000); 3870 } 3871 } 3872 } 3873 } 3874 3875 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3876 if (ioc->debug_level & MPT_DEBUG) { 3877 if (ioc->alt_ioc) 3878 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); 3879 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n", 3880 ioc->name, diag0val, diag1val)); 3881 } 3882 3883 /* Clear RESET_HISTORY bit! Place board in the 3884 * diagnostic mode to update the diag register. 3885 */ 3886 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3887 count = 0; 3888 while ((diag0val & MPI_DIAG_DRWE) == 0) { 3889 /* Write magic sequence to WriteSequence register 3890 * Loop until in diagnostic mode 3891 */ 3892 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF); 3893 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE); 3894 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE); 3895 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE); 3896 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE); 3897 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE); 3898 3899 /* wait 100 msec */ 3900 if (sleepFlag == CAN_SLEEP) { 3901 msleep (100); 3902 } else { 3903 mdelay (100); 3904 } 3905 3906 count++; 3907 if (count > 20) { 3908 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n", 3909 ioc->name, diag0val); 3910 break; 3911 } 3912 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3913 } 3914 diag0val &= ~MPI_DIAG_RESET_HISTORY; 3915 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val); 3916 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3917 if (diag0val & MPI_DIAG_RESET_HISTORY) { 3918 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n", 3919 ioc->name); 3920 } 3921 3922 /* Disable Diagnostic Mode 3923 */ 3924 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF); 3925 3926 /* Check FW reload status flags. 3927 */ 3928 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic); 3929 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) { 3930 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n", 3931 ioc->name, diag0val); 3932 return -3; 3933 } 3934 3935 if (ioc->debug_level & MPT_DEBUG) { 3936 if (ioc->alt_ioc) 3937 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic); 3938 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n", 3939 ioc->name, diag0val, diag1val)); 3940 } 3941 3942 /* 3943 * Reset flag that says we've enabled event notification 3944 */ 3945 ioc->facts.EventState = 0; 3946 3947 if (ioc->alt_ioc) 3948 ioc->alt_ioc->facts.EventState = 0; 3949 3950 return hard_reset_done; 3951 } 3952 3953 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 3954 /** 3955 * SendIocReset - Send IOCReset request to MPT adapter. 3956 * @ioc: Pointer to MPT_ADAPTER structure 3957 * @reset_type: reset type, expected values are 3958 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET 3959 * @sleepFlag: Specifies whether the process can sleep 3960 * 3961 * Send IOCReset request to the MPT adapter. 3962 * 3963 * Returns 0 for success, non-zero for failure. 3964 */ 3965 static int 3966 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag) 3967 { 3968 int r; 3969 u32 state; 3970 int cntdn, count; 3971 3972 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n", 3973 ioc->name, reset_type)); 3974 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT); 3975 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) 3976 return r; 3977 3978 /* FW ACK'd request, wait for READY state 3979 */ 3980 count = 0; 3981 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */ 3982 3983 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) { 3984 cntdn--; 3985 count++; 3986 if (!cntdn) { 3987 if (sleepFlag != CAN_SLEEP) 3988 count *= 10; 3989 3990 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n", 3991 ioc->name, (int)((count+5)/HZ)); 3992 return -ETIME; 3993 } 3994 3995 if (sleepFlag == CAN_SLEEP) { 3996 msleep(1); 3997 } else { 3998 mdelay (1); /* 1 msec delay */ 3999 } 4000 } 4001 4002 /* TODO! 4003 * Cleanup all event stuff for this IOC; re-issue EventNotification 4004 * request if needed. 4005 */ 4006 if (ioc->facts.Function) 4007 ioc->facts.EventState = 0; 4008 4009 return 0; 4010 } 4011 4012 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4013 /** 4014 * initChainBuffers - Allocate memory for and initialize chain buffers 4015 * @ioc: Pointer to MPT_ADAPTER structure 4016 * 4017 * Allocates memory for and initializes chain buffers, 4018 * chain buffer control arrays and spinlock. 4019 */ 4020 static int 4021 initChainBuffers(MPT_ADAPTER *ioc) 4022 { 4023 u8 *mem; 4024 int sz, ii, num_chain; 4025 int scale, num_sge, numSGE; 4026 4027 /* ReqToChain size must equal the req_depth 4028 * index = req_idx 4029 */ 4030 if (ioc->ReqToChain == NULL) { 4031 sz = ioc->req_depth * sizeof(int); 4032 mem = kmalloc(sz, GFP_ATOMIC); 4033 if (mem == NULL) 4034 return -1; 4035 4036 ioc->ReqToChain = (int *) mem; 4037 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n", 4038 ioc->name, mem, sz)); 4039 mem = kmalloc(sz, GFP_ATOMIC); 4040 if (mem == NULL) 4041 return -1; 4042 4043 ioc->RequestNB = (int *) mem; 4044 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n", 4045 ioc->name, mem, sz)); 4046 } 4047 for (ii = 0; ii < ioc->req_depth; ii++) { 4048 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN; 4049 } 4050 4051 /* ChainToChain size must equal the total number 4052 * of chain buffers to be allocated. 4053 * index = chain_idx 4054 * 4055 * Calculate the number of chain buffers needed(plus 1) per I/O 4056 * then multiply the maximum number of simultaneous cmds 4057 * 4058 * num_sge = num sge in request frame + last chain buffer 4059 * scale = num sge per chain buffer if no chain element 4060 */ 4061 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32)); 4062 if (sizeof(dma_addr_t) == sizeof(u64)) 4063 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32)); 4064 else 4065 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32)); 4066 4067 if (sizeof(dma_addr_t) == sizeof(u64)) { 4068 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale + 4069 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32)); 4070 } else { 4071 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale + 4072 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32)); 4073 } 4074 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n", 4075 ioc->name, num_sge, numSGE)); 4076 4077 if ( numSGE > MPT_SCSI_SG_DEPTH ) 4078 numSGE = MPT_SCSI_SG_DEPTH; 4079 4080 num_chain = 1; 4081 while (numSGE - num_sge > 0) { 4082 num_chain++; 4083 num_sge += (scale - 1); 4084 } 4085 num_chain++; 4086 4087 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n", 4088 ioc->name, numSGE, num_sge, num_chain)); 4089 4090 if (ioc->bus_type == SPI) 4091 num_chain *= MPT_SCSI_CAN_QUEUE; 4092 else 4093 num_chain *= MPT_FC_CAN_QUEUE; 4094 4095 ioc->num_chain = num_chain; 4096 4097 sz = num_chain * sizeof(int); 4098 if (ioc->ChainToChain == NULL) { 4099 mem = kmalloc(sz, GFP_ATOMIC); 4100 if (mem == NULL) 4101 return -1; 4102 4103 ioc->ChainToChain = (int *) mem; 4104 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n", 4105 ioc->name, mem, sz)); 4106 } else { 4107 mem = (u8 *) ioc->ChainToChain; 4108 } 4109 memset(mem, 0xFF, sz); 4110 return num_chain; 4111 } 4112 4113 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4114 /** 4115 * PrimeIocFifos - Initialize IOC request and reply FIFOs. 4116 * @ioc: Pointer to MPT_ADAPTER structure 4117 * 4118 * This routine allocates memory for the MPT reply and request frame 4119 * pools (if necessary), and primes the IOC reply FIFO with 4120 * reply frames. 4121 * 4122 * Returns 0 for success, non-zero for failure. 4123 */ 4124 static int 4125 PrimeIocFifos(MPT_ADAPTER *ioc) 4126 { 4127 MPT_FRAME_HDR *mf; 4128 unsigned long flags; 4129 dma_addr_t alloc_dma; 4130 u8 *mem; 4131 int i, reply_sz, sz, total_size, num_chain; 4132 4133 /* Prime reply FIFO... */ 4134 4135 if (ioc->reply_frames == NULL) { 4136 if ( (num_chain = initChainBuffers(ioc)) < 0) 4137 return -1; 4138 4139 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth); 4140 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n", 4141 ioc->name, ioc->reply_sz, ioc->reply_depth)); 4142 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n", 4143 ioc->name, reply_sz, reply_sz)); 4144 4145 sz = (ioc->req_sz * ioc->req_depth); 4146 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n", 4147 ioc->name, ioc->req_sz, ioc->req_depth)); 4148 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n", 4149 ioc->name, sz, sz)); 4150 total_size += sz; 4151 4152 sz = num_chain * ioc->req_sz; /* chain buffer pool size */ 4153 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n", 4154 ioc->name, ioc->req_sz, num_chain)); 4155 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n", 4156 ioc->name, sz, sz, num_chain)); 4157 4158 total_size += sz; 4159 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma); 4160 if (mem == NULL) { 4161 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n", 4162 ioc->name); 4163 goto out_fail; 4164 } 4165 4166 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n", 4167 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size)); 4168 4169 memset(mem, 0, total_size); 4170 ioc->alloc_total += total_size; 4171 ioc->alloc = mem; 4172 ioc->alloc_dma = alloc_dma; 4173 ioc->alloc_sz = total_size; 4174 ioc->reply_frames = (MPT_FRAME_HDR *) mem; 4175 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF); 4176 4177 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n", 4178 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma)); 4179 4180 alloc_dma += reply_sz; 4181 mem += reply_sz; 4182 4183 /* Request FIFO - WE manage this! */ 4184 4185 ioc->req_frames = (MPT_FRAME_HDR *) mem; 4186 ioc->req_frames_dma = alloc_dma; 4187 4188 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n", 4189 ioc->name, mem, (void *)(ulong)alloc_dma)); 4190 4191 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF); 4192 4193 #if defined(CONFIG_MTRR) && 0 4194 /* 4195 * Enable Write Combining MTRR for IOC's memory region. 4196 * (at least as much as we can; "size and base must be 4197 * multiples of 4 kiB" 4198 */ 4199 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma, 4200 sz, 4201 MTRR_TYPE_WRCOMB, 1); 4202 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n", 4203 ioc->name, ioc->req_frames_dma, sz)); 4204 #endif 4205 4206 for (i = 0; i < ioc->req_depth; i++) { 4207 alloc_dma += ioc->req_sz; 4208 mem += ioc->req_sz; 4209 } 4210 4211 ioc->ChainBuffer = mem; 4212 ioc->ChainBufferDMA = alloc_dma; 4213 4214 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n", 4215 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA)); 4216 4217 /* Initialize the free chain Q. 4218 */ 4219 4220 INIT_LIST_HEAD(&ioc->FreeChainQ); 4221 4222 /* Post the chain buffers to the FreeChainQ. 4223 */ 4224 mem = (u8 *)ioc->ChainBuffer; 4225 for (i=0; i < num_chain; i++) { 4226 mf = (MPT_FRAME_HDR *) mem; 4227 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ); 4228 mem += ioc->req_sz; 4229 } 4230 4231 /* Initialize Request frames linked list 4232 */ 4233 alloc_dma = ioc->req_frames_dma; 4234 mem = (u8 *) ioc->req_frames; 4235 4236 spin_lock_irqsave(&ioc->FreeQlock, flags); 4237 INIT_LIST_HEAD(&ioc->FreeQ); 4238 for (i = 0; i < ioc->req_depth; i++) { 4239 mf = (MPT_FRAME_HDR *) mem; 4240 4241 /* Queue REQUESTs *internally*! */ 4242 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ); 4243 4244 mem += ioc->req_sz; 4245 } 4246 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 4247 4248 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); 4249 ioc->sense_buf_pool = 4250 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma); 4251 if (ioc->sense_buf_pool == NULL) { 4252 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n", 4253 ioc->name); 4254 goto out_fail; 4255 } 4256 4257 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF); 4258 ioc->alloc_total += sz; 4259 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n", 4260 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma)); 4261 4262 } 4263 4264 /* Post Reply frames to FIFO 4265 */ 4266 alloc_dma = ioc->alloc_dma; 4267 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n", 4268 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma)); 4269 4270 for (i = 0; i < ioc->reply_depth; i++) { 4271 /* Write each address to the IOC! */ 4272 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma); 4273 alloc_dma += ioc->reply_sz; 4274 } 4275 4276 return 0; 4277 4278 out_fail: 4279 if (ioc->alloc != NULL) { 4280 sz = ioc->alloc_sz; 4281 pci_free_consistent(ioc->pcidev, 4282 sz, 4283 ioc->alloc, ioc->alloc_dma); 4284 ioc->reply_frames = NULL; 4285 ioc->req_frames = NULL; 4286 ioc->alloc_total -= sz; 4287 } 4288 if (ioc->sense_buf_pool != NULL) { 4289 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC); 4290 pci_free_consistent(ioc->pcidev, 4291 sz, 4292 ioc->sense_buf_pool, ioc->sense_buf_pool_dma); 4293 ioc->sense_buf_pool = NULL; 4294 } 4295 return -1; 4296 } 4297 4298 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4299 /** 4300 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply 4301 * from IOC via doorbell handshake method. 4302 * @ioc: Pointer to MPT_ADAPTER structure 4303 * @reqBytes: Size of the request in bytes 4304 * @req: Pointer to MPT request frame 4305 * @replyBytes: Expected size of the reply in bytes 4306 * @u16reply: Pointer to area where reply should be written 4307 * @maxwait: Max wait time for a reply (in seconds) 4308 * @sleepFlag: Specifies whether the process can sleep 4309 * 4310 * NOTES: It is the callers responsibility to byte-swap fields in the 4311 * request which are greater than 1 byte in size. It is also the 4312 * callers responsibility to byte-swap response fields which are 4313 * greater than 1 byte in size. 4314 * 4315 * Returns 0 for success, non-zero for failure. 4316 */ 4317 static int 4318 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req, 4319 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag) 4320 { 4321 MPIDefaultReply_t *mptReply; 4322 int failcnt = 0; 4323 int t; 4324 4325 /* 4326 * Get ready to cache a handshake reply 4327 */ 4328 ioc->hs_reply_idx = 0; 4329 mptReply = (MPIDefaultReply_t *) ioc->hs_reply; 4330 mptReply->MsgLength = 0; 4331 4332 /* 4333 * Make sure there are no doorbells (WRITE 0 to IntStatus reg), 4334 * then tell IOC that we want to handshake a request of N words. 4335 * (WRITE u32val to Doorbell reg). 4336 */ 4337 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4338 CHIPREG_WRITE32(&ioc->chip->Doorbell, 4339 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) | 4340 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT))); 4341 4342 /* 4343 * Wait for IOC's doorbell handshake int 4344 */ 4345 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) 4346 failcnt++; 4347 4348 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n", 4349 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : "")); 4350 4351 /* Read doorbell and check for active bit */ 4352 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE)) 4353 return -1; 4354 4355 /* 4356 * Clear doorbell int (WRITE 0 to IntStatus reg), 4357 * then wait for IOC to ACKnowledge that it's ready for 4358 * our handshake request. 4359 */ 4360 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4361 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) 4362 failcnt++; 4363 4364 if (!failcnt) { 4365 int ii; 4366 u8 *req_as_bytes = (u8 *) req; 4367 4368 /* 4369 * Stuff request words via doorbell handshake, 4370 * with ACK from IOC for each. 4371 */ 4372 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) { 4373 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) | 4374 (req_as_bytes[(ii*4) + 1] << 8) | 4375 (req_as_bytes[(ii*4) + 2] << 16) | 4376 (req_as_bytes[(ii*4) + 3] << 24)); 4377 4378 CHIPREG_WRITE32(&ioc->chip->Doorbell, word); 4379 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) 4380 failcnt++; 4381 } 4382 4383 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req)); 4384 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req); 4385 4386 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n", 4387 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : "")); 4388 4389 /* 4390 * Wait for completion of doorbell handshake reply from the IOC 4391 */ 4392 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0) 4393 failcnt++; 4394 4395 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n", 4396 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : "")); 4397 4398 /* 4399 * Copy out the cached reply... 4400 */ 4401 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++) 4402 u16reply[ii] = ioc->hs_reply[ii]; 4403 } else { 4404 return -99; 4405 } 4406 4407 return -failcnt; 4408 } 4409 4410 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4411 /** 4412 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge 4413 * @ioc: Pointer to MPT_ADAPTER structure 4414 * @howlong: How long to wait (in seconds) 4415 * @sleepFlag: Specifies whether the process can sleep 4416 * 4417 * This routine waits (up to ~2 seconds max) for IOC doorbell 4418 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS 4419 * bit in its IntStatus register being clear. 4420 * 4421 * Returns a negative value on failure, else wait loop count. 4422 */ 4423 static int 4424 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag) 4425 { 4426 int cntdn; 4427 int count = 0; 4428 u32 intstat=0; 4429 4430 cntdn = 1000 * howlong; 4431 4432 if (sleepFlag == CAN_SLEEP) { 4433 while (--cntdn) { 4434 msleep (1); 4435 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4436 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) 4437 break; 4438 count++; 4439 } 4440 } else { 4441 while (--cntdn) { 4442 udelay (1000); 4443 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4444 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS)) 4445 break; 4446 count++; 4447 } 4448 } 4449 4450 if (cntdn) { 4451 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n", 4452 ioc->name, count)); 4453 return count; 4454 } 4455 4456 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n", 4457 ioc->name, count, intstat); 4458 return -1; 4459 } 4460 4461 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4462 /** 4463 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit 4464 * @ioc: Pointer to MPT_ADAPTER structure 4465 * @howlong: How long to wait (in seconds) 4466 * @sleepFlag: Specifies whether the process can sleep 4467 * 4468 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt 4469 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register. 4470 * 4471 * Returns a negative value on failure, else wait loop count. 4472 */ 4473 static int 4474 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag) 4475 { 4476 int cntdn; 4477 int count = 0; 4478 u32 intstat=0; 4479 4480 cntdn = 1000 * howlong; 4481 if (sleepFlag == CAN_SLEEP) { 4482 while (--cntdn) { 4483 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4484 if (intstat & MPI_HIS_DOORBELL_INTERRUPT) 4485 break; 4486 msleep(1); 4487 count++; 4488 } 4489 } else { 4490 while (--cntdn) { 4491 intstat = CHIPREG_READ32(&ioc->chip->IntStatus); 4492 if (intstat & MPI_HIS_DOORBELL_INTERRUPT) 4493 break; 4494 udelay (1000); 4495 count++; 4496 } 4497 } 4498 4499 if (cntdn) { 4500 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n", 4501 ioc->name, count, howlong)); 4502 return count; 4503 } 4504 4505 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n", 4506 ioc->name, count, intstat); 4507 return -1; 4508 } 4509 4510 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4511 /** 4512 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply. 4513 * @ioc: Pointer to MPT_ADAPTER structure 4514 * @howlong: How long to wait (in seconds) 4515 * @sleepFlag: Specifies whether the process can sleep 4516 * 4517 * This routine polls the IOC for a handshake reply, 16 bits at a time. 4518 * Reply is cached to IOC private area large enough to hold a maximum 4519 * of 128 bytes of reply data. 4520 * 4521 * Returns a negative value on failure, else size of reply in WORDS. 4522 */ 4523 static int 4524 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag) 4525 { 4526 int u16cnt = 0; 4527 int failcnt = 0; 4528 int t; 4529 u16 *hs_reply = ioc->hs_reply; 4530 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply; 4531 u16 hword; 4532 4533 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0; 4534 4535 /* 4536 * Get first two u16's so we can look at IOC's intended reply MsgLength 4537 */ 4538 u16cnt=0; 4539 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) { 4540 failcnt++; 4541 } else { 4542 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF); 4543 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4544 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) 4545 failcnt++; 4546 else { 4547 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF); 4548 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4549 } 4550 } 4551 4552 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n", 4553 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply), 4554 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : "")); 4555 4556 /* 4557 * If no error (and IOC said MsgLength is > 0), piece together 4558 * reply 16 bits at a time. 4559 */ 4560 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) { 4561 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) 4562 failcnt++; 4563 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF); 4564 /* don't overflow our IOC hs_reply[] buffer! */ 4565 if (u16cnt < ARRAY_SIZE(ioc->hs_reply)) 4566 hs_reply[u16cnt] = hword; 4567 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4568 } 4569 4570 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) 4571 failcnt++; 4572 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); 4573 4574 if (failcnt) { 4575 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n", 4576 ioc->name); 4577 return -failcnt; 4578 } 4579 #if 0 4580 else if (u16cnt != (2 * mptReply->MsgLength)) { 4581 return -101; 4582 } 4583 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) { 4584 return -102; 4585 } 4586 #endif 4587 4588 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name)); 4589 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply); 4590 4591 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n", 4592 ioc->name, t, u16cnt/2)); 4593 return u16cnt/2; 4594 } 4595 4596 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4597 /** 4598 * GetLanConfigPages - Fetch LANConfig pages. 4599 * @ioc: Pointer to MPT_ADAPTER structure 4600 * 4601 * Return: 0 for success 4602 * -ENOMEM if no memory available 4603 * -EPERM if not allowed due to ISR context 4604 * -EAGAIN if no msg frames currently available 4605 * -EFAULT for non-successful reply or no reply (timeout) 4606 */ 4607 static int 4608 GetLanConfigPages(MPT_ADAPTER *ioc) 4609 { 4610 ConfigPageHeader_t hdr; 4611 CONFIGPARMS cfg; 4612 LANPage0_t *ppage0_alloc; 4613 dma_addr_t page0_dma; 4614 LANPage1_t *ppage1_alloc; 4615 dma_addr_t page1_dma; 4616 int rc = 0; 4617 int data_sz; 4618 int copy_sz; 4619 4620 /* Get LAN Page 0 header */ 4621 hdr.PageVersion = 0; 4622 hdr.PageLength = 0; 4623 hdr.PageNumber = 0; 4624 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN; 4625 cfg.cfghdr.hdr = &hdr; 4626 cfg.physAddr = -1; 4627 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4628 cfg.dir = 0; 4629 cfg.pageAddr = 0; 4630 cfg.timeout = 0; 4631 4632 if ((rc = mpt_config(ioc, &cfg)) != 0) 4633 return rc; 4634 4635 if (hdr.PageLength > 0) { 4636 data_sz = hdr.PageLength * 4; 4637 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma); 4638 rc = -ENOMEM; 4639 if (ppage0_alloc) { 4640 memset((u8 *)ppage0_alloc, 0, data_sz); 4641 cfg.physAddr = page0_dma; 4642 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4643 4644 if ((rc = mpt_config(ioc, &cfg)) == 0) { 4645 /* save the data */ 4646 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz); 4647 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz); 4648 4649 } 4650 4651 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma); 4652 4653 /* FIXME! 4654 * Normalize endianness of structure data, 4655 * by byte-swapping all > 1 byte fields! 4656 */ 4657 4658 } 4659 4660 if (rc) 4661 return rc; 4662 } 4663 4664 /* Get LAN Page 1 header */ 4665 hdr.PageVersion = 0; 4666 hdr.PageLength = 0; 4667 hdr.PageNumber = 1; 4668 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN; 4669 cfg.cfghdr.hdr = &hdr; 4670 cfg.physAddr = -1; 4671 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4672 cfg.dir = 0; 4673 cfg.pageAddr = 0; 4674 4675 if ((rc = mpt_config(ioc, &cfg)) != 0) 4676 return rc; 4677 4678 if (hdr.PageLength == 0) 4679 return 0; 4680 4681 data_sz = hdr.PageLength * 4; 4682 rc = -ENOMEM; 4683 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma); 4684 if (ppage1_alloc) { 4685 memset((u8 *)ppage1_alloc, 0, data_sz); 4686 cfg.physAddr = page1_dma; 4687 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4688 4689 if ((rc = mpt_config(ioc, &cfg)) == 0) { 4690 /* save the data */ 4691 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz); 4692 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz); 4693 } 4694 4695 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma); 4696 4697 /* FIXME! 4698 * Normalize endianness of structure data, 4699 * by byte-swapping all > 1 byte fields! 4700 */ 4701 4702 } 4703 4704 return rc; 4705 } 4706 4707 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4708 /** 4709 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table 4710 * @ioc: Pointer to MPT_ADAPTER structure 4711 * @persist_opcode: see below 4712 * 4713 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for 4714 * devices not currently present. 4715 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings 4716 * 4717 * NOTE: Don't use not this function during interrupt time. 4718 * 4719 * Returns 0 for success, non-zero error 4720 */ 4721 4722 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4723 int 4724 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode) 4725 { 4726 SasIoUnitControlRequest_t *sasIoUnitCntrReq; 4727 SasIoUnitControlReply_t *sasIoUnitCntrReply; 4728 MPT_FRAME_HDR *mf = NULL; 4729 MPIHeader_t *mpi_hdr; 4730 4731 4732 /* insure garbage is not sent to fw */ 4733 switch(persist_opcode) { 4734 4735 case MPI_SAS_OP_CLEAR_NOT_PRESENT: 4736 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT: 4737 break; 4738 4739 default: 4740 return -1; 4741 break; 4742 } 4743 4744 printk("%s: persist_opcode=%x\n",__func__, persist_opcode); 4745 4746 /* Get a MF for this command. 4747 */ 4748 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 4749 printk("%s: no msg frames!\n",__func__); 4750 return -1; 4751 } 4752 4753 mpi_hdr = (MPIHeader_t *) mf; 4754 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf; 4755 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t)); 4756 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL; 4757 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext; 4758 sasIoUnitCntrReq->Operation = persist_opcode; 4759 4760 init_timer(&ioc->persist_timer); 4761 ioc->persist_timer.data = (unsigned long) ioc; 4762 ioc->persist_timer.function = mpt_timer_expired; 4763 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */; 4764 ioc->persist_wait_done=0; 4765 add_timer(&ioc->persist_timer); 4766 mpt_put_msg_frame(mpt_base_index, ioc, mf); 4767 wait_event(mpt_waitq, ioc->persist_wait_done); 4768 4769 sasIoUnitCntrReply = 4770 (SasIoUnitControlReply_t *)ioc->persist_reply_frame; 4771 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) { 4772 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", 4773 __func__, 4774 sasIoUnitCntrReply->IOCStatus, 4775 sasIoUnitCntrReply->IOCLogInfo); 4776 return -1; 4777 } 4778 4779 printk("%s: success\n",__func__); 4780 return 0; 4781 } 4782 4783 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4784 4785 static void 4786 mptbase_raid_process_event_data(MPT_ADAPTER *ioc, 4787 MpiEventDataRaid_t * pRaidEventData) 4788 { 4789 int volume; 4790 int reason; 4791 int disk; 4792 int status; 4793 int flags; 4794 int state; 4795 4796 volume = pRaidEventData->VolumeID; 4797 reason = pRaidEventData->ReasonCode; 4798 disk = pRaidEventData->PhysDiskNum; 4799 status = le32_to_cpu(pRaidEventData->SettingsStatus); 4800 flags = (status >> 0) & 0xff; 4801 state = (status >> 8) & 0xff; 4802 4803 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) { 4804 return; 4805 } 4806 4807 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED && 4808 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) || 4809 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) { 4810 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n", 4811 ioc->name, disk, volume); 4812 } else { 4813 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n", 4814 ioc->name, volume); 4815 } 4816 4817 switch(reason) { 4818 case MPI_EVENT_RAID_RC_VOLUME_CREATED: 4819 printk(MYIOC_s_INFO_FMT " volume has been created\n", 4820 ioc->name); 4821 break; 4822 4823 case MPI_EVENT_RAID_RC_VOLUME_DELETED: 4824 4825 printk(MYIOC_s_INFO_FMT " volume has been deleted\n", 4826 ioc->name); 4827 break; 4828 4829 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED: 4830 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n", 4831 ioc->name); 4832 break; 4833 4834 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED: 4835 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n", 4836 ioc->name, 4837 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL 4838 ? "optimal" 4839 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED 4840 ? "degraded" 4841 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED 4842 ? "failed" 4843 : "state unknown", 4844 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED 4845 ? ", enabled" : "", 4846 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED 4847 ? ", quiesced" : "", 4848 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS 4849 ? ", resync in progress" : "" ); 4850 break; 4851 4852 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED: 4853 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n", 4854 ioc->name, disk); 4855 break; 4856 4857 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED: 4858 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n", 4859 ioc->name); 4860 break; 4861 4862 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED: 4863 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n", 4864 ioc->name); 4865 break; 4866 4867 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED: 4868 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n", 4869 ioc->name); 4870 break; 4871 4872 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED: 4873 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n", 4874 ioc->name, 4875 state == MPI_PHYSDISK0_STATUS_ONLINE 4876 ? "online" 4877 : state == MPI_PHYSDISK0_STATUS_MISSING 4878 ? "missing" 4879 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE 4880 ? "not compatible" 4881 : state == MPI_PHYSDISK0_STATUS_FAILED 4882 ? "failed" 4883 : state == MPI_PHYSDISK0_STATUS_INITIALIZING 4884 ? "initializing" 4885 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED 4886 ? "offline requested" 4887 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED 4888 ? "failed requested" 4889 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE 4890 ? "offline" 4891 : "state unknown", 4892 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC 4893 ? ", out of sync" : "", 4894 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED 4895 ? ", quiesced" : "" ); 4896 break; 4897 4898 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED: 4899 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n", 4900 ioc->name, disk); 4901 break; 4902 4903 case MPI_EVENT_RAID_RC_SMART_DATA: 4904 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n", 4905 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ); 4906 break; 4907 4908 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED: 4909 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n", 4910 ioc->name, disk); 4911 break; 4912 } 4913 } 4914 4915 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4916 /** 4917 * GetIoUnitPage2 - Retrieve BIOS version and boot order information. 4918 * @ioc: Pointer to MPT_ADAPTER structure 4919 * 4920 * Returns: 0 for success 4921 * -ENOMEM if no memory available 4922 * -EPERM if not allowed due to ISR context 4923 * -EAGAIN if no msg frames currently available 4924 * -EFAULT for non-successful reply or no reply (timeout) 4925 */ 4926 static int 4927 GetIoUnitPage2(MPT_ADAPTER *ioc) 4928 { 4929 ConfigPageHeader_t hdr; 4930 CONFIGPARMS cfg; 4931 IOUnitPage2_t *ppage_alloc; 4932 dma_addr_t page_dma; 4933 int data_sz; 4934 int rc; 4935 4936 /* Get the page header */ 4937 hdr.PageVersion = 0; 4938 hdr.PageLength = 0; 4939 hdr.PageNumber = 2; 4940 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT; 4941 cfg.cfghdr.hdr = &hdr; 4942 cfg.physAddr = -1; 4943 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 4944 cfg.dir = 0; 4945 cfg.pageAddr = 0; 4946 cfg.timeout = 0; 4947 4948 if ((rc = mpt_config(ioc, &cfg)) != 0) 4949 return rc; 4950 4951 if (hdr.PageLength == 0) 4952 return 0; 4953 4954 /* Read the config page */ 4955 data_sz = hdr.PageLength * 4; 4956 rc = -ENOMEM; 4957 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma); 4958 if (ppage_alloc) { 4959 memset((u8 *)ppage_alloc, 0, data_sz); 4960 cfg.physAddr = page_dma; 4961 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 4962 4963 /* If Good, save data */ 4964 if ((rc = mpt_config(ioc, &cfg)) == 0) 4965 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion); 4966 4967 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma); 4968 } 4969 4970 return rc; 4971 } 4972 4973 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 4974 /** 4975 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2 4976 * @ioc: Pointer to a Adapter Strucutre 4977 * @portnum: IOC port number 4978 * 4979 * Return: -EFAULT if read of config page header fails 4980 * or if no nvram 4981 * If read of SCSI Port Page 0 fails, 4982 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF) 4983 * Adapter settings: async, narrow 4984 * Return 1 4985 * If read of SCSI Port Page 2 fails, 4986 * Adapter settings valid 4987 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF) 4988 * Return 1 4989 * Else 4990 * Both valid 4991 * Return 0 4992 * CHECK - what type of locking mechanisms should be used???? 4993 */ 4994 static int 4995 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum) 4996 { 4997 u8 *pbuf; 4998 dma_addr_t buf_dma; 4999 CONFIGPARMS cfg; 5000 ConfigPageHeader_t header; 5001 int ii; 5002 int data, rc = 0; 5003 5004 /* Allocate memory 5005 */ 5006 if (!ioc->spi_data.nvram) { 5007 int sz; 5008 u8 *mem; 5009 sz = MPT_MAX_SCSI_DEVICES * sizeof(int); 5010 mem = kmalloc(sz, GFP_ATOMIC); 5011 if (mem == NULL) 5012 return -EFAULT; 5013 5014 ioc->spi_data.nvram = (int *) mem; 5015 5016 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n", 5017 ioc->name, ioc->spi_data.nvram, sz)); 5018 } 5019 5020 /* Invalidate NVRAM information 5021 */ 5022 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 5023 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID; 5024 } 5025 5026 /* Read SPP0 header, allocate memory, then read page. 5027 */ 5028 header.PageVersion = 0; 5029 header.PageLength = 0; 5030 header.PageNumber = 0; 5031 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT; 5032 cfg.cfghdr.hdr = &header; 5033 cfg.physAddr = -1; 5034 cfg.pageAddr = portnum; 5035 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5036 cfg.dir = 0; 5037 cfg.timeout = 0; /* use default */ 5038 if (mpt_config(ioc, &cfg) != 0) 5039 return -EFAULT; 5040 5041 if (header.PageLength > 0) { 5042 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma); 5043 if (pbuf) { 5044 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5045 cfg.physAddr = buf_dma; 5046 if (mpt_config(ioc, &cfg) != 0) { 5047 ioc->spi_data.maxBusWidth = MPT_NARROW; 5048 ioc->spi_data.maxSyncOffset = 0; 5049 ioc->spi_data.minSyncFactor = MPT_ASYNC; 5050 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN; 5051 rc = 1; 5052 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5053 "Unable to read PortPage0 minSyncFactor=%x\n", 5054 ioc->name, ioc->spi_data.minSyncFactor)); 5055 } else { 5056 /* Save the Port Page 0 data 5057 */ 5058 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf; 5059 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities); 5060 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface); 5061 5062 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) { 5063 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS; 5064 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5065 "noQas due to Capabilities=%x\n", 5066 ioc->name, pPP0->Capabilities)); 5067 } 5068 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0; 5069 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK; 5070 if (data) { 5071 ioc->spi_data.maxSyncOffset = (u8) (data >> 16); 5072 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK; 5073 ioc->spi_data.minSyncFactor = (u8) (data >> 8); 5074 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5075 "PortPage0 minSyncFactor=%x\n", 5076 ioc->name, ioc->spi_data.minSyncFactor)); 5077 } else { 5078 ioc->spi_data.maxSyncOffset = 0; 5079 ioc->spi_data.minSyncFactor = MPT_ASYNC; 5080 } 5081 5082 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK; 5083 5084 /* Update the minSyncFactor based on bus type. 5085 */ 5086 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) || 5087 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) { 5088 5089 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) { 5090 ioc->spi_data.minSyncFactor = MPT_ULTRA; 5091 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5092 "HVD or SE detected, minSyncFactor=%x\n", 5093 ioc->name, ioc->spi_data.minSyncFactor)); 5094 } 5095 } 5096 } 5097 if (pbuf) { 5098 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma); 5099 } 5100 } 5101 } 5102 5103 /* SCSI Port Page 2 - Read the header then the page. 5104 */ 5105 header.PageVersion = 0; 5106 header.PageLength = 0; 5107 header.PageNumber = 2; 5108 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT; 5109 cfg.cfghdr.hdr = &header; 5110 cfg.physAddr = -1; 5111 cfg.pageAddr = portnum; 5112 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5113 cfg.dir = 0; 5114 if (mpt_config(ioc, &cfg) != 0) 5115 return -EFAULT; 5116 5117 if (header.PageLength > 0) { 5118 /* Allocate memory and read SCSI Port Page 2 5119 */ 5120 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma); 5121 if (pbuf) { 5122 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM; 5123 cfg.physAddr = buf_dma; 5124 if (mpt_config(ioc, &cfg) != 0) { 5125 /* Nvram data is left with INVALID mark 5126 */ 5127 rc = 1; 5128 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) { 5129 5130 /* This is an ATTO adapter, read Page2 accordingly 5131 */ 5132 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf; 5133 ATTODeviceInfo_t *pdevice = NULL; 5134 u16 ATTOFlags; 5135 5136 /* Save the Port Page 2 data 5137 * (reformat into a 32bit quantity) 5138 */ 5139 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 5140 pdevice = &pPP2->DeviceSettings[ii]; 5141 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags); 5142 data = 0; 5143 5144 /* Translate ATTO device flags to LSI format 5145 */ 5146 if (ATTOFlags & ATTOFLAG_DISC) 5147 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE); 5148 if (ATTOFlags & ATTOFLAG_ID_ENB) 5149 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE); 5150 if (ATTOFlags & ATTOFLAG_LUN_ENB) 5151 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE); 5152 if (ATTOFlags & ATTOFLAG_TAGGED) 5153 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE); 5154 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB)) 5155 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE); 5156 5157 data = (data << 16) | (pdevice->Period << 8) | 10; 5158 ioc->spi_data.nvram[ii] = data; 5159 } 5160 } else { 5161 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf; 5162 MpiDeviceInfo_t *pdevice = NULL; 5163 5164 /* 5165 * Save "Set to Avoid SCSI Bus Resets" flag 5166 */ 5167 ioc->spi_data.bus_reset = 5168 (le32_to_cpu(pPP2->PortFlags) & 5169 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ? 5170 0 : 1 ; 5171 5172 /* Save the Port Page 2 data 5173 * (reformat into a 32bit quantity) 5174 */ 5175 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK; 5176 ioc->spi_data.PortFlags = data; 5177 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) { 5178 pdevice = &pPP2->DeviceSettings[ii]; 5179 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) | 5180 (pdevice->SyncFactor << 8) | pdevice->Timeout; 5181 ioc->spi_data.nvram[ii] = data; 5182 } 5183 } 5184 5185 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma); 5186 } 5187 } 5188 5189 /* Update Adapter limits with those from NVRAM 5190 * Comment: Don't need to do this. Target performance 5191 * parameters will never exceed the adapters limits. 5192 */ 5193 5194 return rc; 5195 } 5196 5197 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5198 /** 5199 * mpt_readScsiDevicePageHeaders - save version and length of SDP1 5200 * @ioc: Pointer to a Adapter Strucutre 5201 * @portnum: IOC port number 5202 * 5203 * Return: -EFAULT if read of config page header fails 5204 * or 0 if success. 5205 */ 5206 static int 5207 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum) 5208 { 5209 CONFIGPARMS cfg; 5210 ConfigPageHeader_t header; 5211 5212 /* Read the SCSI Device Page 1 header 5213 */ 5214 header.PageVersion = 0; 5215 header.PageLength = 0; 5216 header.PageNumber = 1; 5217 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 5218 cfg.cfghdr.hdr = &header; 5219 cfg.physAddr = -1; 5220 cfg.pageAddr = portnum; 5221 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5222 cfg.dir = 0; 5223 cfg.timeout = 0; 5224 if (mpt_config(ioc, &cfg) != 0) 5225 return -EFAULT; 5226 5227 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion; 5228 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength; 5229 5230 header.PageVersion = 0; 5231 header.PageLength = 0; 5232 header.PageNumber = 0; 5233 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE; 5234 if (mpt_config(ioc, &cfg) != 0) 5235 return -EFAULT; 5236 5237 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion; 5238 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength; 5239 5240 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n", 5241 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length)); 5242 5243 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n", 5244 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length)); 5245 return 0; 5246 } 5247 5248 /** 5249 * mpt_inactive_raid_list_free - This clears this link list. 5250 * @ioc : pointer to per adapter structure 5251 **/ 5252 static void 5253 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc) 5254 { 5255 struct inactive_raid_component_info *component_info, *pNext; 5256 5257 if (list_empty(&ioc->raid_data.inactive_list)) 5258 return; 5259 5260 mutex_lock(&ioc->raid_data.inactive_list_mutex); 5261 list_for_each_entry_safe(component_info, pNext, 5262 &ioc->raid_data.inactive_list, list) { 5263 list_del(&component_info->list); 5264 kfree(component_info); 5265 } 5266 mutex_unlock(&ioc->raid_data.inactive_list_mutex); 5267 } 5268 5269 /** 5270 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume 5271 * 5272 * @ioc : pointer to per adapter structure 5273 * @channel : volume channel 5274 * @id : volume target id 5275 **/ 5276 static void 5277 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id) 5278 { 5279 CONFIGPARMS cfg; 5280 ConfigPageHeader_t hdr; 5281 dma_addr_t dma_handle; 5282 pRaidVolumePage0_t buffer = NULL; 5283 int i; 5284 RaidPhysDiskPage0_t phys_disk; 5285 struct inactive_raid_component_info *component_info; 5286 int handle_inactive_volumes; 5287 5288 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5289 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5290 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME; 5291 cfg.pageAddr = (channel << 8) + id; 5292 cfg.cfghdr.hdr = &hdr; 5293 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5294 5295 if (mpt_config(ioc, &cfg) != 0) 5296 goto out; 5297 5298 if (!hdr.PageLength) 5299 goto out; 5300 5301 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, 5302 &dma_handle); 5303 5304 if (!buffer) 5305 goto out; 5306 5307 cfg.physAddr = dma_handle; 5308 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5309 5310 if (mpt_config(ioc, &cfg) != 0) 5311 goto out; 5312 5313 if (!buffer->NumPhysDisks) 5314 goto out; 5315 5316 handle_inactive_volumes = 5317 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE || 5318 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 || 5319 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED || 5320 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0; 5321 5322 if (!handle_inactive_volumes) 5323 goto out; 5324 5325 mutex_lock(&ioc->raid_data.inactive_list_mutex); 5326 for (i = 0; i < buffer->NumPhysDisks; i++) { 5327 if(mpt_raid_phys_disk_pg0(ioc, 5328 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0) 5329 continue; 5330 5331 if ((component_info = kmalloc(sizeof (*component_info), 5332 GFP_KERNEL)) == NULL) 5333 continue; 5334 5335 component_info->volumeID = id; 5336 component_info->volumeBus = channel; 5337 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum; 5338 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus; 5339 component_info->d.PhysDiskID = phys_disk.PhysDiskID; 5340 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC; 5341 5342 list_add_tail(&component_info->list, 5343 &ioc->raid_data.inactive_list); 5344 } 5345 mutex_unlock(&ioc->raid_data.inactive_list_mutex); 5346 5347 out: 5348 if (buffer) 5349 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, 5350 dma_handle); 5351 } 5352 5353 /** 5354 * mpt_raid_phys_disk_pg0 - returns phys disk page zero 5355 * @ioc: Pointer to a Adapter Structure 5356 * @phys_disk_num: io unit unique phys disk num generated by the ioc 5357 * @phys_disk: requested payload data returned 5358 * 5359 * Return: 5360 * 0 on success 5361 * -EFAULT if read of config page header fails or data pointer not NULL 5362 * -ENOMEM if pci_alloc failed 5363 **/ 5364 int 5365 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk) 5366 { 5367 CONFIGPARMS cfg; 5368 ConfigPageHeader_t hdr; 5369 dma_addr_t dma_handle; 5370 pRaidPhysDiskPage0_t buffer = NULL; 5371 int rc; 5372 5373 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5374 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5375 5376 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK; 5377 cfg.cfghdr.hdr = &hdr; 5378 cfg.physAddr = -1; 5379 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5380 5381 if (mpt_config(ioc, &cfg) != 0) { 5382 rc = -EFAULT; 5383 goto out; 5384 } 5385 5386 if (!hdr.PageLength) { 5387 rc = -EFAULT; 5388 goto out; 5389 } 5390 5391 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, 5392 &dma_handle); 5393 5394 if (!buffer) { 5395 rc = -ENOMEM; 5396 goto out; 5397 } 5398 5399 cfg.physAddr = dma_handle; 5400 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5401 cfg.pageAddr = phys_disk_num; 5402 5403 if (mpt_config(ioc, &cfg) != 0) { 5404 rc = -EFAULT; 5405 goto out; 5406 } 5407 5408 rc = 0; 5409 memcpy(phys_disk, buffer, sizeof(*buffer)); 5410 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA); 5411 5412 out: 5413 5414 if (buffer) 5415 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer, 5416 dma_handle); 5417 5418 return rc; 5419 } 5420 5421 /** 5422 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes 5423 * @ioc: Pointer to a Adapter Strucutre 5424 * 5425 * Return: 5426 * 0 on success 5427 * -EFAULT if read of config page header fails or data pointer not NULL 5428 * -ENOMEM if pci_alloc failed 5429 **/ 5430 int 5431 mpt_findImVolumes(MPT_ADAPTER *ioc) 5432 { 5433 IOCPage2_t *pIoc2; 5434 u8 *mem; 5435 dma_addr_t ioc2_dma; 5436 CONFIGPARMS cfg; 5437 ConfigPageHeader_t header; 5438 int rc = 0; 5439 int iocpage2sz; 5440 int i; 5441 5442 if (!ioc->ir_firmware) 5443 return 0; 5444 5445 /* Free the old page 5446 */ 5447 kfree(ioc->raid_data.pIocPg2); 5448 ioc->raid_data.pIocPg2 = NULL; 5449 mpt_inactive_raid_list_free(ioc); 5450 5451 /* Read IOCP2 header then the page. 5452 */ 5453 header.PageVersion = 0; 5454 header.PageLength = 0; 5455 header.PageNumber = 2; 5456 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 5457 cfg.cfghdr.hdr = &header; 5458 cfg.physAddr = -1; 5459 cfg.pageAddr = 0; 5460 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5461 cfg.dir = 0; 5462 cfg.timeout = 0; 5463 if (mpt_config(ioc, &cfg) != 0) 5464 return -EFAULT; 5465 5466 if (header.PageLength == 0) 5467 return -EFAULT; 5468 5469 iocpage2sz = header.PageLength * 4; 5470 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma); 5471 if (!pIoc2) 5472 return -ENOMEM; 5473 5474 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5475 cfg.physAddr = ioc2_dma; 5476 if (mpt_config(ioc, &cfg) != 0) 5477 goto out; 5478 5479 mem = kmalloc(iocpage2sz, GFP_KERNEL); 5480 if (!mem) 5481 goto out; 5482 5483 memcpy(mem, (u8 *)pIoc2, iocpage2sz); 5484 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem; 5485 5486 mpt_read_ioc_pg_3(ioc); 5487 5488 for (i = 0; i < pIoc2->NumActiveVolumes ; i++) 5489 mpt_inactive_raid_volumes(ioc, 5490 pIoc2->RaidVolume[i].VolumeBus, 5491 pIoc2->RaidVolume[i].VolumeID); 5492 5493 out: 5494 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma); 5495 5496 return rc; 5497 } 5498 5499 static int 5500 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc) 5501 { 5502 IOCPage3_t *pIoc3; 5503 u8 *mem; 5504 CONFIGPARMS cfg; 5505 ConfigPageHeader_t header; 5506 dma_addr_t ioc3_dma; 5507 int iocpage3sz = 0; 5508 5509 /* Free the old page 5510 */ 5511 kfree(ioc->raid_data.pIocPg3); 5512 ioc->raid_data.pIocPg3 = NULL; 5513 5514 /* There is at least one physical disk. 5515 * Read and save IOC Page 3 5516 */ 5517 header.PageVersion = 0; 5518 header.PageLength = 0; 5519 header.PageNumber = 3; 5520 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 5521 cfg.cfghdr.hdr = &header; 5522 cfg.physAddr = -1; 5523 cfg.pageAddr = 0; 5524 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5525 cfg.dir = 0; 5526 cfg.timeout = 0; 5527 if (mpt_config(ioc, &cfg) != 0) 5528 return 0; 5529 5530 if (header.PageLength == 0) 5531 return 0; 5532 5533 /* Read Header good, alloc memory 5534 */ 5535 iocpage3sz = header.PageLength * 4; 5536 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma); 5537 if (!pIoc3) 5538 return 0; 5539 5540 /* Read the Page and save the data 5541 * into malloc'd memory. 5542 */ 5543 cfg.physAddr = ioc3_dma; 5544 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5545 if (mpt_config(ioc, &cfg) == 0) { 5546 mem = kmalloc(iocpage3sz, GFP_KERNEL); 5547 if (mem) { 5548 memcpy(mem, (u8 *)pIoc3, iocpage3sz); 5549 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem; 5550 } 5551 } 5552 5553 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma); 5554 5555 return 0; 5556 } 5557 5558 static void 5559 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc) 5560 { 5561 IOCPage4_t *pIoc4; 5562 CONFIGPARMS cfg; 5563 ConfigPageHeader_t header; 5564 dma_addr_t ioc4_dma; 5565 int iocpage4sz; 5566 5567 /* Read and save IOC Page 4 5568 */ 5569 header.PageVersion = 0; 5570 header.PageLength = 0; 5571 header.PageNumber = 4; 5572 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 5573 cfg.cfghdr.hdr = &header; 5574 cfg.physAddr = -1; 5575 cfg.pageAddr = 0; 5576 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5577 cfg.dir = 0; 5578 cfg.timeout = 0; 5579 if (mpt_config(ioc, &cfg) != 0) 5580 return; 5581 5582 if (header.PageLength == 0) 5583 return; 5584 5585 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) { 5586 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */ 5587 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma); 5588 if (!pIoc4) 5589 return; 5590 ioc->alloc_total += iocpage4sz; 5591 } else { 5592 ioc4_dma = ioc->spi_data.IocPg4_dma; 5593 iocpage4sz = ioc->spi_data.IocPg4Sz; 5594 } 5595 5596 /* Read the Page into dma memory. 5597 */ 5598 cfg.physAddr = ioc4_dma; 5599 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5600 if (mpt_config(ioc, &cfg) == 0) { 5601 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4; 5602 ioc->spi_data.IocPg4_dma = ioc4_dma; 5603 ioc->spi_data.IocPg4Sz = iocpage4sz; 5604 } else { 5605 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma); 5606 ioc->spi_data.pIocPg4 = NULL; 5607 ioc->alloc_total -= iocpage4sz; 5608 } 5609 } 5610 5611 static void 5612 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc) 5613 { 5614 IOCPage1_t *pIoc1; 5615 CONFIGPARMS cfg; 5616 ConfigPageHeader_t header; 5617 dma_addr_t ioc1_dma; 5618 int iocpage1sz = 0; 5619 u32 tmp; 5620 5621 /* Check the Coalescing Timeout in IOC Page 1 5622 */ 5623 header.PageVersion = 0; 5624 header.PageLength = 0; 5625 header.PageNumber = 1; 5626 header.PageType = MPI_CONFIG_PAGETYPE_IOC; 5627 cfg.cfghdr.hdr = &header; 5628 cfg.physAddr = -1; 5629 cfg.pageAddr = 0; 5630 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5631 cfg.dir = 0; 5632 cfg.timeout = 0; 5633 if (mpt_config(ioc, &cfg) != 0) 5634 return; 5635 5636 if (header.PageLength == 0) 5637 return; 5638 5639 /* Read Header good, alloc memory 5640 */ 5641 iocpage1sz = header.PageLength * 4; 5642 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma); 5643 if (!pIoc1) 5644 return; 5645 5646 /* Read the Page and check coalescing timeout 5647 */ 5648 cfg.physAddr = ioc1_dma; 5649 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5650 if (mpt_config(ioc, &cfg) == 0) { 5651 5652 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING; 5653 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) { 5654 tmp = le32_to_cpu(pIoc1->CoalescingTimeout); 5655 5656 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n", 5657 ioc->name, tmp)); 5658 5659 if (tmp > MPT_COALESCING_TIMEOUT) { 5660 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT); 5661 5662 /* Write NVRAM and current 5663 */ 5664 cfg.dir = 1; 5665 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT; 5666 if (mpt_config(ioc, &cfg) == 0) { 5667 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n", 5668 ioc->name, MPT_COALESCING_TIMEOUT)); 5669 5670 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM; 5671 if (mpt_config(ioc, &cfg) == 0) { 5672 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5673 "Reset NVRAM Coalescing Timeout to = %d\n", 5674 ioc->name, MPT_COALESCING_TIMEOUT)); 5675 } else { 5676 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5677 "Reset NVRAM Coalescing Timeout Failed\n", 5678 ioc->name)); 5679 } 5680 5681 } else { 5682 dprintk(ioc, printk(MYIOC_s_WARN_FMT 5683 "Reset of Current Coalescing Timeout Failed!\n", 5684 ioc->name)); 5685 } 5686 } 5687 5688 } else { 5689 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name)); 5690 } 5691 } 5692 5693 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma); 5694 5695 return; 5696 } 5697 5698 static void 5699 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc) 5700 { 5701 CONFIGPARMS cfg; 5702 ConfigPageHeader_t hdr; 5703 dma_addr_t buf_dma; 5704 ManufacturingPage0_t *pbuf = NULL; 5705 5706 memset(&cfg, 0 , sizeof(CONFIGPARMS)); 5707 memset(&hdr, 0 , sizeof(ConfigPageHeader_t)); 5708 5709 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING; 5710 cfg.cfghdr.hdr = &hdr; 5711 cfg.physAddr = -1; 5712 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; 5713 cfg.timeout = 10; 5714 5715 if (mpt_config(ioc, &cfg) != 0) 5716 goto out; 5717 5718 if (!cfg.cfghdr.hdr->PageLength) 5719 goto out; 5720 5721 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; 5722 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma); 5723 if (!pbuf) 5724 goto out; 5725 5726 cfg.physAddr = buf_dma; 5727 5728 if (mpt_config(ioc, &cfg) != 0) 5729 goto out; 5730 5731 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name)); 5732 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly)); 5733 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer)); 5734 5735 out: 5736 5737 if (pbuf) 5738 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma); 5739 } 5740 5741 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5742 /** 5743 * SendEventNotification - Send EventNotification (on or off) request to adapter 5744 * @ioc: Pointer to MPT_ADAPTER structure 5745 * @EvSwitch: Event switch flags 5746 */ 5747 static int 5748 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch) 5749 { 5750 EventNotification_t *evnp; 5751 5752 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc); 5753 if (evnp == NULL) { 5754 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n", 5755 ioc->name)); 5756 return 0; 5757 } 5758 memset(evnp, 0, sizeof(*evnp)); 5759 5760 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp)); 5761 5762 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION; 5763 evnp->ChainOffset = 0; 5764 evnp->MsgFlags = 0; 5765 evnp->Switch = EvSwitch; 5766 5767 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp); 5768 5769 return 0; 5770 } 5771 5772 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5773 /** 5774 * SendEventAck - Send EventAck request to MPT adapter. 5775 * @ioc: Pointer to MPT_ADAPTER structure 5776 * @evnp: Pointer to original EventNotification request 5777 */ 5778 static int 5779 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp) 5780 { 5781 EventAck_t *pAck; 5782 5783 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 5784 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n", 5785 ioc->name,__func__)); 5786 return -1; 5787 } 5788 5789 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name)); 5790 5791 pAck->Function = MPI_FUNCTION_EVENT_ACK; 5792 pAck->ChainOffset = 0; 5793 pAck->Reserved[0] = pAck->Reserved[1] = 0; 5794 pAck->MsgFlags = 0; 5795 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0; 5796 pAck->Event = evnp->Event; 5797 pAck->EventContext = evnp->EventContext; 5798 5799 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck); 5800 5801 return 0; 5802 } 5803 5804 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5805 /** 5806 * mpt_config - Generic function to issue config message 5807 * @ioc: Pointer to an adapter structure 5808 * @pCfg: Pointer to a configuration structure. Struct contains 5809 * action, page address, direction, physical address 5810 * and pointer to a configuration page header 5811 * Page header is updated. 5812 * 5813 * Returns 0 for success 5814 * -EPERM if not allowed due to ISR context 5815 * -EAGAIN if no msg frames currently available 5816 * -EFAULT for non-successful reply or no reply (timeout) 5817 */ 5818 int 5819 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg) 5820 { 5821 Config_t *pReq; 5822 ConfigExtendedPageHeader_t *pExtHdr = NULL; 5823 MPT_FRAME_HDR *mf; 5824 unsigned long flags; 5825 int ii, rc; 5826 int flagsLength; 5827 int in_isr; 5828 5829 /* Prevent calling wait_event() (below), if caller happens 5830 * to be in ISR context, because that is fatal! 5831 */ 5832 in_isr = in_interrupt(); 5833 if (in_isr) { 5834 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n", 5835 ioc->name)); 5836 return -EPERM; 5837 } 5838 5839 /* Get and Populate a free Frame 5840 */ 5841 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) { 5842 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n", 5843 ioc->name)); 5844 return -EAGAIN; 5845 } 5846 pReq = (Config_t *)mf; 5847 pReq->Action = pCfg->action; 5848 pReq->Reserved = 0; 5849 pReq->ChainOffset = 0; 5850 pReq->Function = MPI_FUNCTION_CONFIG; 5851 5852 /* Assume page type is not extended and clear "reserved" fields. */ 5853 pReq->ExtPageLength = 0; 5854 pReq->ExtPageType = 0; 5855 pReq->MsgFlags = 0; 5856 5857 for (ii=0; ii < 8; ii++) 5858 pReq->Reserved2[ii] = 0; 5859 5860 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion; 5861 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength; 5862 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber; 5863 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK); 5864 5865 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) { 5866 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr; 5867 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength); 5868 pReq->ExtPageType = pExtHdr->ExtPageType; 5869 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; 5870 5871 /* Page Length must be treated as a reserved field for the extended header. */ 5872 pReq->Header.PageLength = 0; 5873 } 5874 5875 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr); 5876 5877 /* Add a SGE to the config request. 5878 */ 5879 if (pCfg->dir) 5880 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE; 5881 else 5882 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ; 5883 5884 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) { 5885 flagsLength |= pExtHdr->ExtPageLength * 4; 5886 5887 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n", 5888 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action)); 5889 } 5890 else { 5891 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4; 5892 5893 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n", 5894 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action)); 5895 } 5896 5897 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr); 5898 5899 /* Append pCfg pointer to end of mf 5900 */ 5901 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg; 5902 5903 /* Initalize the timer 5904 */ 5905 init_timer(&pCfg->timer); 5906 pCfg->timer.data = (unsigned long) ioc; 5907 pCfg->timer.function = mpt_timer_expired; 5908 pCfg->wait_done = 0; 5909 5910 /* Set the timer; ensure 10 second minimum */ 5911 if (pCfg->timeout < 10) 5912 pCfg->timer.expires = jiffies + HZ*10; 5913 else 5914 pCfg->timer.expires = jiffies + HZ*pCfg->timeout; 5915 5916 /* Add to end of Q, set timer and then issue this command */ 5917 spin_lock_irqsave(&ioc->FreeQlock, flags); 5918 list_add_tail(&pCfg->linkage, &ioc->configQ); 5919 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 5920 5921 add_timer(&pCfg->timer); 5922 mpt_put_msg_frame(mpt_base_index, ioc, mf); 5923 wait_event(mpt_waitq, pCfg->wait_done); 5924 5925 /* mf has been freed - do not access */ 5926 5927 rc = pCfg->status; 5928 5929 return rc; 5930 } 5931 5932 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5933 /** 5934 * mpt_timer_expired - Callback for timer process. 5935 * Used only internal config functionality. 5936 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long 5937 */ 5938 static void 5939 mpt_timer_expired(unsigned long data) 5940 { 5941 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data; 5942 5943 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name)); 5944 5945 /* Perform a FW reload */ 5946 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) 5947 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name); 5948 5949 /* No more processing. 5950 * Hard reset clean-up will wake up 5951 * process and free all resources. 5952 */ 5953 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name)); 5954 5955 return; 5956 } 5957 5958 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 5959 /** 5960 * mpt_ioc_reset - Base cleanup for hard reset 5961 * @ioc: Pointer to the adapter structure 5962 * @reset_phase: Indicates pre- or post-reset functionality 5963 * 5964 * Remark: Frees resources with internally generated commands. 5965 */ 5966 static int 5967 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) 5968 { 5969 CONFIGPARMS *pCfg; 5970 unsigned long flags; 5971 5972 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT 5973 ": IOC %s_reset routed to MPT base driver!\n", 5974 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( 5975 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); 5976 5977 if (reset_phase == MPT_IOC_SETUP_RESET) { 5978 ; 5979 } else if (reset_phase == MPT_IOC_PRE_RESET) { 5980 /* If the internal config Q is not empty - 5981 * delete timer. MF resources will be freed when 5982 * the FIFO's are primed. 5983 */ 5984 spin_lock_irqsave(&ioc->FreeQlock, flags); 5985 list_for_each_entry(pCfg, &ioc->configQ, linkage) 5986 del_timer(&pCfg->timer); 5987 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 5988 5989 } else { 5990 CONFIGPARMS *pNext; 5991 5992 /* Search the configQ for internal commands. 5993 * Flush the Q, and wake up all suspended threads. 5994 */ 5995 spin_lock_irqsave(&ioc->FreeQlock, flags); 5996 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) { 5997 list_del(&pCfg->linkage); 5998 5999 pCfg->status = MPT_CONFIG_ERROR; 6000 pCfg->wait_done = 1; 6001 wake_up(&mpt_waitq); 6002 } 6003 spin_unlock_irqrestore(&ioc->FreeQlock, flags); 6004 } 6005 6006 return 1; /* currently means nothing really */ 6007 } 6008 6009 6010 #ifdef CONFIG_PROC_FS /* { */ 6011 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6012 /* 6013 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff... 6014 */ 6015 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6016 /** 6017 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries. 6018 * 6019 * Returns 0 for success, non-zero for failure. 6020 */ 6021 static int 6022 procmpt_create(void) 6023 { 6024 struct proc_dir_entry *ent; 6025 6026 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL); 6027 if (mpt_proc_root_dir == NULL) 6028 return -ENOTDIR; 6029 6030 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir); 6031 if (ent) 6032 ent->read_proc = procmpt_summary_read; 6033 6034 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir); 6035 if (ent) 6036 ent->read_proc = procmpt_version_read; 6037 6038 return 0; 6039 } 6040 6041 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6042 /** 6043 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries. 6044 * 6045 * Returns 0 for success, non-zero for failure. 6046 */ 6047 static void 6048 procmpt_destroy(void) 6049 { 6050 remove_proc_entry("version", mpt_proc_root_dir); 6051 remove_proc_entry("summary", mpt_proc_root_dir); 6052 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL); 6053 } 6054 6055 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6056 /** 6057 * procmpt_summary_read - Handle read request of a summary file 6058 * @buf: Pointer to area to write information 6059 * @start: Pointer to start pointer 6060 * @offset: Offset to start writing 6061 * @request: Amount of read data requested 6062 * @eof: Pointer to EOF integer 6063 * @data: Pointer 6064 * 6065 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary. 6066 * Returns number of characters written to process performing the read. 6067 */ 6068 static int 6069 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) 6070 { 6071 MPT_ADAPTER *ioc; 6072 char *out = buf; 6073 int len; 6074 6075 if (data) { 6076 int more = 0; 6077 6078 ioc = data; 6079 mpt_print_ioc_summary(ioc, out, &more, 0, 1); 6080 6081 out += more; 6082 } else { 6083 list_for_each_entry(ioc, &ioc_list, list) { 6084 int more = 0; 6085 6086 mpt_print_ioc_summary(ioc, out, &more, 0, 1); 6087 6088 out += more; 6089 if ((out-buf) >= request) 6090 break; 6091 } 6092 } 6093 6094 len = out - buf; 6095 6096 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); 6097 } 6098 6099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6100 /** 6101 * procmpt_version_read - Handle read request from /proc/mpt/version. 6102 * @buf: Pointer to area to write information 6103 * @start: Pointer to start pointer 6104 * @offset: Offset to start writing 6105 * @request: Amount of read data requested 6106 * @eof: Pointer to EOF integer 6107 * @data: Pointer 6108 * 6109 * Returns number of characters written to process performing the read. 6110 */ 6111 static int 6112 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) 6113 { 6114 u8 cb_idx; 6115 int scsi, fc, sas, lan, ctl, targ, dmp; 6116 char *drvname; 6117 int len; 6118 6119 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON); 6120 len += sprintf(buf+len, " Fusion MPT base driver\n"); 6121 6122 scsi = fc = sas = lan = ctl = targ = dmp = 0; 6123 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 6124 drvname = NULL; 6125 if (MptCallbacks[cb_idx]) { 6126 switch (MptDriverClass[cb_idx]) { 6127 case MPTSPI_DRIVER: 6128 if (!scsi++) drvname = "SPI host"; 6129 break; 6130 case MPTFC_DRIVER: 6131 if (!fc++) drvname = "FC host"; 6132 break; 6133 case MPTSAS_DRIVER: 6134 if (!sas++) drvname = "SAS host"; 6135 break; 6136 case MPTLAN_DRIVER: 6137 if (!lan++) drvname = "LAN"; 6138 break; 6139 case MPTSTM_DRIVER: 6140 if (!targ++) drvname = "SCSI target"; 6141 break; 6142 case MPTCTL_DRIVER: 6143 if (!ctl++) drvname = "ioctl"; 6144 break; 6145 } 6146 6147 if (drvname) 6148 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname); 6149 } 6150 } 6151 6152 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); 6153 } 6154 6155 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6156 /** 6157 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info. 6158 * @buf: Pointer to area to write information 6159 * @start: Pointer to start pointer 6160 * @offset: Offset to start writing 6161 * @request: Amount of read data requested 6162 * @eof: Pointer to EOF integer 6163 * @data: Pointer 6164 * 6165 * Returns number of characters written to process performing the read. 6166 */ 6167 static int 6168 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data) 6169 { 6170 MPT_ADAPTER *ioc = data; 6171 int len; 6172 char expVer[32]; 6173 int sz; 6174 int p; 6175 6176 mpt_get_fw_exp_ver(expVer, ioc); 6177 6178 len = sprintf(buf, "%s:", ioc->name); 6179 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) 6180 len += sprintf(buf+len, " (f/w download boot flag set)"); 6181 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL) 6182 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!"); 6183 6184 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n", 6185 ioc->facts.ProductID, 6186 ioc->prod_name); 6187 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer); 6188 if (ioc->facts.FWImageSize) 6189 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize); 6190 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion); 6191 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit); 6192 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState); 6193 6194 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n", 6195 ioc->facts.CurrentHostMfaHighAddr); 6196 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n", 6197 ioc->facts.CurrentSenseBufferHighAddr); 6198 6199 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth); 6200 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize); 6201 6202 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n", 6203 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma); 6204 /* 6205 * Rounding UP to nearest 4-kB boundary here... 6206 */ 6207 sz = (ioc->req_sz * ioc->req_depth) + 128; 6208 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000; 6209 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n", 6210 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz); 6211 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n", 6212 4*ioc->facts.RequestFrameSize, 6213 ioc->facts.GlobalCredits); 6214 6215 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n", 6216 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma); 6217 sz = (ioc->reply_sz * ioc->reply_depth) + 128; 6218 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n", 6219 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz); 6220 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n", 6221 ioc->facts.CurReplyFrameSize, 6222 ioc->facts.ReplyQueueDepth); 6223 6224 len += sprintf(buf+len, " MaxDevices = %d\n", 6225 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices); 6226 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses); 6227 6228 /* per-port info */ 6229 for (p=0; p < ioc->facts.NumberOfPorts; p++) { 6230 len += sprintf(buf+len, " PortNumber = %d (of %d)\n", 6231 p+1, 6232 ioc->facts.NumberOfPorts); 6233 if (ioc->bus_type == FC) { 6234 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) { 6235 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; 6236 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", 6237 a[5], a[4], a[3], a[2], a[1], a[0]); 6238 } 6239 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n", 6240 ioc->fc_port_page0[p].WWNN.High, 6241 ioc->fc_port_page0[p].WWNN.Low, 6242 ioc->fc_port_page0[p].WWPN.High, 6243 ioc->fc_port_page0[p].WWPN.Low); 6244 } 6245 } 6246 6247 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len); 6248 } 6249 6250 #endif /* CONFIG_PROC_FS } */ 6251 6252 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6253 static void 6254 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc) 6255 { 6256 buf[0] ='\0'; 6257 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) { 6258 sprintf(buf, " (Exp %02d%02d)", 6259 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */ 6260 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */ 6261 6262 /* insider hack! */ 6263 if ((ioc->facts.FWVersion.Word >> 8) & 0x80) 6264 strcat(buf, " [MDBG]"); 6265 } 6266 } 6267 6268 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6269 /** 6270 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer. 6271 * @ioc: Pointer to MPT_ADAPTER structure 6272 * @buffer: Pointer to buffer where IOC summary info should be written 6273 * @size: Pointer to number of bytes we wrote (set by this routine) 6274 * @len: Offset at which to start writing in buffer 6275 * @showlan: Display LAN stuff? 6276 * 6277 * This routine writes (english readable) ASCII text, which represents 6278 * a summary of IOC information, to a buffer. 6279 */ 6280 void 6281 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan) 6282 { 6283 char expVer[32]; 6284 int y; 6285 6286 mpt_get_fw_exp_ver(expVer, ioc); 6287 6288 /* 6289 * Shorter summary of attached ioc's... 6290 */ 6291 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d", 6292 ioc->name, 6293 ioc->prod_name, 6294 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */ 6295 ioc->facts.FWVersion.Word, 6296 expVer, 6297 ioc->facts.NumberOfPorts, 6298 ioc->req_depth); 6299 6300 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) { 6301 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow; 6302 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X", 6303 a[5], a[4], a[3], a[2], a[1], a[0]); 6304 } 6305 6306 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq); 6307 6308 if (!ioc->active) 6309 y += sprintf(buffer+len+y, " (disabled)"); 6310 6311 y += sprintf(buffer+len+y, "\n"); 6312 6313 *size = y; 6314 } 6315 6316 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6317 /* 6318 * Reset Handling 6319 */ 6320 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6321 /** 6322 * mpt_HardResetHandler - Generic reset handler 6323 * @ioc: Pointer to MPT_ADAPTER structure 6324 * @sleepFlag: Indicates if sleep or schedule must be called. 6325 * 6326 * Issues SCSI Task Management call based on input arg values. 6327 * If TaskMgmt fails, returns associated SCSI request. 6328 * 6329 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer) 6330 * or a non-interrupt thread. In the former, must not call schedule(). 6331 * 6332 * Note: A return of -1 is a FATAL error case, as it means a 6333 * FW reload/initialization failed. 6334 * 6335 * Returns 0 for SUCCESS or -1 if FAILED. 6336 */ 6337 int 6338 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag) 6339 { 6340 int rc; 6341 unsigned long flags; 6342 6343 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name)); 6344 #ifdef MFCNT 6345 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name); 6346 printk("MF count 0x%x !\n", ioc->mfcnt); 6347 #endif 6348 6349 /* Reset the adapter. Prevent more than 1 call to 6350 * mpt_do_ioc_recovery at any instant in time. 6351 */ 6352 spin_lock_irqsave(&ioc->diagLock, flags); 6353 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){ 6354 spin_unlock_irqrestore(&ioc->diagLock, flags); 6355 return 0; 6356 } else { 6357 ioc->diagPending = 1; 6358 } 6359 spin_unlock_irqrestore(&ioc->diagLock, flags); 6360 6361 /* FIXME: If do_ioc_recovery fails, repeat.... 6362 */ 6363 6364 /* The SCSI driver needs to adjust timeouts on all current 6365 * commands prior to the diagnostic reset being issued. 6366 * Prevents timeouts occurring during a diagnostic reset...very bad. 6367 * For all other protocol drivers, this is a no-op. 6368 */ 6369 { 6370 u8 cb_idx; 6371 int r = 0; 6372 6373 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 6374 if (MptResetHandlers[cb_idx]) { 6375 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n", 6376 ioc->name, cb_idx)); 6377 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET); 6378 if (ioc->alt_ioc) { 6379 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n", 6380 ioc->name, ioc->alt_ioc->name, cb_idx)); 6381 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET); 6382 } 6383 } 6384 } 6385 } 6386 6387 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) { 6388 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc); 6389 } 6390 ioc->reload_fw = 0; 6391 if (ioc->alt_ioc) 6392 ioc->alt_ioc->reload_fw = 0; 6393 6394 spin_lock_irqsave(&ioc->diagLock, flags); 6395 ioc->diagPending = 0; 6396 if (ioc->alt_ioc) 6397 ioc->alt_ioc->diagPending = 0; 6398 spin_unlock_irqrestore(&ioc->diagLock, flags); 6399 6400 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc)); 6401 6402 return rc; 6403 } 6404 6405 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6406 static void 6407 EventDescriptionStr(u8 event, u32 evData0, char *evStr) 6408 { 6409 char *ds = NULL; 6410 6411 switch(event) { 6412 case MPI_EVENT_NONE: 6413 ds = "None"; 6414 break; 6415 case MPI_EVENT_LOG_DATA: 6416 ds = "Log Data"; 6417 break; 6418 case MPI_EVENT_STATE_CHANGE: 6419 ds = "State Change"; 6420 break; 6421 case MPI_EVENT_UNIT_ATTENTION: 6422 ds = "Unit Attention"; 6423 break; 6424 case MPI_EVENT_IOC_BUS_RESET: 6425 ds = "IOC Bus Reset"; 6426 break; 6427 case MPI_EVENT_EXT_BUS_RESET: 6428 ds = "External Bus Reset"; 6429 break; 6430 case MPI_EVENT_RESCAN: 6431 ds = "Bus Rescan Event"; 6432 break; 6433 case MPI_EVENT_LINK_STATUS_CHANGE: 6434 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE) 6435 ds = "Link Status(FAILURE) Change"; 6436 else 6437 ds = "Link Status(ACTIVE) Change"; 6438 break; 6439 case MPI_EVENT_LOOP_STATE_CHANGE: 6440 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP) 6441 ds = "Loop State(LIP) Change"; 6442 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE) 6443 ds = "Loop State(LPE) Change"; /* ??? */ 6444 else 6445 ds = "Loop State(LPB) Change"; /* ??? */ 6446 break; 6447 case MPI_EVENT_LOGOUT: 6448 ds = "Logout"; 6449 break; 6450 case MPI_EVENT_EVENT_CHANGE: 6451 if (evData0) 6452 ds = "Events ON"; 6453 else 6454 ds = "Events OFF"; 6455 break; 6456 case MPI_EVENT_INTEGRATED_RAID: 6457 { 6458 u8 ReasonCode = (u8)(evData0 >> 16); 6459 switch (ReasonCode) { 6460 case MPI_EVENT_RAID_RC_VOLUME_CREATED : 6461 ds = "Integrated Raid: Volume Created"; 6462 break; 6463 case MPI_EVENT_RAID_RC_VOLUME_DELETED : 6464 ds = "Integrated Raid: Volume Deleted"; 6465 break; 6466 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED : 6467 ds = "Integrated Raid: Volume Settings Changed"; 6468 break; 6469 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED : 6470 ds = "Integrated Raid: Volume Status Changed"; 6471 break; 6472 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED : 6473 ds = "Integrated Raid: Volume Physdisk Changed"; 6474 break; 6475 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED : 6476 ds = "Integrated Raid: Physdisk Created"; 6477 break; 6478 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED : 6479 ds = "Integrated Raid: Physdisk Deleted"; 6480 break; 6481 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED : 6482 ds = "Integrated Raid: Physdisk Settings Changed"; 6483 break; 6484 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED : 6485 ds = "Integrated Raid: Physdisk Status Changed"; 6486 break; 6487 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED : 6488 ds = "Integrated Raid: Domain Validation Needed"; 6489 break; 6490 case MPI_EVENT_RAID_RC_SMART_DATA : 6491 ds = "Integrated Raid; Smart Data"; 6492 break; 6493 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED : 6494 ds = "Integrated Raid: Replace Action Started"; 6495 break; 6496 default: 6497 ds = "Integrated Raid"; 6498 break; 6499 } 6500 break; 6501 } 6502 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE: 6503 ds = "SCSI Device Status Change"; 6504 break; 6505 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE: 6506 { 6507 u8 id = (u8)(evData0); 6508 u8 channel = (u8)(evData0 >> 8); 6509 u8 ReasonCode = (u8)(evData0 >> 16); 6510 switch (ReasonCode) { 6511 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED: 6512 snprintf(evStr, EVENT_DESCR_STR_SZ, 6513 "SAS Device Status Change: Added: " 6514 "id=%d channel=%d", id, channel); 6515 break; 6516 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING: 6517 snprintf(evStr, EVENT_DESCR_STR_SZ, 6518 "SAS Device Status Change: Deleted: " 6519 "id=%d channel=%d", id, channel); 6520 break; 6521 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA: 6522 snprintf(evStr, EVENT_DESCR_STR_SZ, 6523 "SAS Device Status Change: SMART Data: " 6524 "id=%d channel=%d", id, channel); 6525 break; 6526 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED: 6527 snprintf(evStr, EVENT_DESCR_STR_SZ, 6528 "SAS Device Status Change: No Persistancy: " 6529 "id=%d channel=%d", id, channel); 6530 break; 6531 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED: 6532 snprintf(evStr, EVENT_DESCR_STR_SZ, 6533 "SAS Device Status Change: Unsupported Device " 6534 "Discovered : id=%d channel=%d", id, channel); 6535 break; 6536 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET: 6537 snprintf(evStr, EVENT_DESCR_STR_SZ, 6538 "SAS Device Status Change: Internal Device " 6539 "Reset : id=%d channel=%d", id, channel); 6540 break; 6541 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL: 6542 snprintf(evStr, EVENT_DESCR_STR_SZ, 6543 "SAS Device Status Change: Internal Task " 6544 "Abort : id=%d channel=%d", id, channel); 6545 break; 6546 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL: 6547 snprintf(evStr, EVENT_DESCR_STR_SZ, 6548 "SAS Device Status Change: Internal Abort " 6549 "Task Set : id=%d channel=%d", id, channel); 6550 break; 6551 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL: 6552 snprintf(evStr, EVENT_DESCR_STR_SZ, 6553 "SAS Device Status Change: Internal Clear " 6554 "Task Set : id=%d channel=%d", id, channel); 6555 break; 6556 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL: 6557 snprintf(evStr, EVENT_DESCR_STR_SZ, 6558 "SAS Device Status Change: Internal Query " 6559 "Task : id=%d channel=%d", id, channel); 6560 break; 6561 default: 6562 snprintf(evStr, EVENT_DESCR_STR_SZ, 6563 "SAS Device Status Change: Unknown: " 6564 "id=%d channel=%d", id, channel); 6565 break; 6566 } 6567 break; 6568 } 6569 case MPI_EVENT_ON_BUS_TIMER_EXPIRED: 6570 ds = "Bus Timer Expired"; 6571 break; 6572 case MPI_EVENT_QUEUE_FULL: 6573 { 6574 u16 curr_depth = (u16)(evData0 >> 16); 6575 u8 channel = (u8)(evData0 >> 8); 6576 u8 id = (u8)(evData0); 6577 6578 snprintf(evStr, EVENT_DESCR_STR_SZ, 6579 "Queue Full: channel=%d id=%d depth=%d", 6580 channel, id, curr_depth); 6581 break; 6582 } 6583 case MPI_EVENT_SAS_SES: 6584 ds = "SAS SES Event"; 6585 break; 6586 case MPI_EVENT_PERSISTENT_TABLE_FULL: 6587 ds = "Persistent Table Full"; 6588 break; 6589 case MPI_EVENT_SAS_PHY_LINK_STATUS: 6590 { 6591 u8 LinkRates = (u8)(evData0 >> 8); 6592 u8 PhyNumber = (u8)(evData0); 6593 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >> 6594 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT; 6595 switch (LinkRates) { 6596 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN: 6597 snprintf(evStr, EVENT_DESCR_STR_SZ, 6598 "SAS PHY Link Status: Phy=%d:" 6599 " Rate Unknown",PhyNumber); 6600 break; 6601 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED: 6602 snprintf(evStr, EVENT_DESCR_STR_SZ, 6603 "SAS PHY Link Status: Phy=%d:" 6604 " Phy Disabled",PhyNumber); 6605 break; 6606 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION: 6607 snprintf(evStr, EVENT_DESCR_STR_SZ, 6608 "SAS PHY Link Status: Phy=%d:" 6609 " Failed Speed Nego",PhyNumber); 6610 break; 6611 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE: 6612 snprintf(evStr, EVENT_DESCR_STR_SZ, 6613 "SAS PHY Link Status: Phy=%d:" 6614 " Sata OOB Completed",PhyNumber); 6615 break; 6616 case MPI_EVENT_SAS_PLS_LR_RATE_1_5: 6617 snprintf(evStr, EVENT_DESCR_STR_SZ, 6618 "SAS PHY Link Status: Phy=%d:" 6619 " Rate 1.5 Gbps",PhyNumber); 6620 break; 6621 case MPI_EVENT_SAS_PLS_LR_RATE_3_0: 6622 snprintf(evStr, EVENT_DESCR_STR_SZ, 6623 "SAS PHY Link Status: Phy=%d:" 6624 " Rate 3.0 Gpbs",PhyNumber); 6625 break; 6626 default: 6627 snprintf(evStr, EVENT_DESCR_STR_SZ, 6628 "SAS PHY Link Status: Phy=%d", PhyNumber); 6629 break; 6630 } 6631 break; 6632 } 6633 case MPI_EVENT_SAS_DISCOVERY_ERROR: 6634 ds = "SAS Discovery Error"; 6635 break; 6636 case MPI_EVENT_IR_RESYNC_UPDATE: 6637 { 6638 u8 resync_complete = (u8)(evData0 >> 16); 6639 snprintf(evStr, EVENT_DESCR_STR_SZ, 6640 "IR Resync Update: Complete = %d:",resync_complete); 6641 break; 6642 } 6643 case MPI_EVENT_IR2: 6644 { 6645 u8 ReasonCode = (u8)(evData0 >> 16); 6646 switch (ReasonCode) { 6647 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED: 6648 ds = "IR2: LD State Changed"; 6649 break; 6650 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED: 6651 ds = "IR2: PD State Changed"; 6652 break; 6653 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL: 6654 ds = "IR2: Bad Block Table Full"; 6655 break; 6656 case MPI_EVENT_IR2_RC_PD_INSERTED: 6657 ds = "IR2: PD Inserted"; 6658 break; 6659 case MPI_EVENT_IR2_RC_PD_REMOVED: 6660 ds = "IR2: PD Removed"; 6661 break; 6662 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED: 6663 ds = "IR2: Foreign CFG Detected"; 6664 break; 6665 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR: 6666 ds = "IR2: Rebuild Medium Error"; 6667 break; 6668 default: 6669 ds = "IR2"; 6670 break; 6671 } 6672 break; 6673 } 6674 case MPI_EVENT_SAS_DISCOVERY: 6675 { 6676 if (evData0) 6677 ds = "SAS Discovery: Start"; 6678 else 6679 ds = "SAS Discovery: Stop"; 6680 break; 6681 } 6682 case MPI_EVENT_LOG_ENTRY_ADDED: 6683 ds = "SAS Log Entry Added"; 6684 break; 6685 6686 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE: 6687 { 6688 u8 phy_num = (u8)(evData0); 6689 u8 port_num = (u8)(evData0 >> 8); 6690 u8 port_width = (u8)(evData0 >> 16); 6691 u8 primative = (u8)(evData0 >> 24); 6692 snprintf(evStr, EVENT_DESCR_STR_SZ, 6693 "SAS Broadcase Primative: phy=%d port=%d " 6694 "width=%d primative=0x%02x", 6695 phy_num, port_num, port_width, primative); 6696 break; 6697 } 6698 6699 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE: 6700 { 6701 u8 reason = (u8)(evData0); 6702 u8 port_num = (u8)(evData0 >> 8); 6703 u16 handle = le16_to_cpu(evData0 >> 16); 6704 6705 snprintf(evStr, EVENT_DESCR_STR_SZ, 6706 "SAS Initiator Device Status Change: reason=0x%02x " 6707 "port=%d handle=0x%04x", 6708 reason, port_num, handle); 6709 break; 6710 } 6711 6712 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW: 6713 { 6714 u8 max_init = (u8)(evData0); 6715 u8 current_init = (u8)(evData0 >> 8); 6716 6717 snprintf(evStr, EVENT_DESCR_STR_SZ, 6718 "SAS Initiator Device Table Overflow: max initiators=%02d " 6719 "current initators=%02d", 6720 max_init, current_init); 6721 break; 6722 } 6723 case MPI_EVENT_SAS_SMP_ERROR: 6724 { 6725 u8 status = (u8)(evData0); 6726 u8 port_num = (u8)(evData0 >> 8); 6727 u8 result = (u8)(evData0 >> 16); 6728 6729 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID) 6730 snprintf(evStr, EVENT_DESCR_STR_SZ, 6731 "SAS SMP Error: port=%d result=0x%02x", 6732 port_num, result); 6733 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR) 6734 snprintf(evStr, EVENT_DESCR_STR_SZ, 6735 "SAS SMP Error: port=%d : CRC Error", 6736 port_num); 6737 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT) 6738 snprintf(evStr, EVENT_DESCR_STR_SZ, 6739 "SAS SMP Error: port=%d : Timeout", 6740 port_num); 6741 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION) 6742 snprintf(evStr, EVENT_DESCR_STR_SZ, 6743 "SAS SMP Error: port=%d : No Destination", 6744 port_num); 6745 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION) 6746 snprintf(evStr, EVENT_DESCR_STR_SZ, 6747 "SAS SMP Error: port=%d : Bad Destination", 6748 port_num); 6749 else 6750 snprintf(evStr, EVENT_DESCR_STR_SZ, 6751 "SAS SMP Error: port=%d : status=0x%02x", 6752 port_num, status); 6753 break; 6754 } 6755 6756 /* 6757 * MPT base "custom" events may be added here... 6758 */ 6759 default: 6760 ds = "Unknown"; 6761 break; 6762 } 6763 if (ds) 6764 strncpy(evStr, ds, EVENT_DESCR_STR_SZ); 6765 } 6766 6767 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6768 /** 6769 * ProcessEventNotification - Route EventNotificationReply to all event handlers 6770 * @ioc: Pointer to MPT_ADAPTER structure 6771 * @pEventReply: Pointer to EventNotification reply frame 6772 * @evHandlers: Pointer to integer, number of event handlers 6773 * 6774 * Routes a received EventNotificationReply to all currently registered 6775 * event handlers. 6776 * Returns sum of event handlers return values. 6777 */ 6778 static int 6779 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers) 6780 { 6781 u16 evDataLen; 6782 u32 evData0 = 0; 6783 // u32 evCtx; 6784 int ii; 6785 u8 cb_idx; 6786 int r = 0; 6787 int handlers = 0; 6788 char evStr[EVENT_DESCR_STR_SZ]; 6789 u8 event; 6790 6791 /* 6792 * Do platform normalization of values 6793 */ 6794 event = le32_to_cpu(pEventReply->Event) & 0xFF; 6795 // evCtx = le32_to_cpu(pEventReply->EventContext); 6796 evDataLen = le16_to_cpu(pEventReply->EventDataLength); 6797 if (evDataLen) { 6798 evData0 = le32_to_cpu(pEventReply->Data[0]); 6799 } 6800 6801 EventDescriptionStr(event, evData0, evStr); 6802 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n", 6803 ioc->name, 6804 event, 6805 evStr)); 6806 6807 #ifdef CONFIG_FUSION_LOGGING 6808 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6809 ": Event data:\n", ioc->name)); 6810 for (ii = 0; ii < evDataLen; ii++) 6811 devtverboseprintk(ioc, printk(" %08x", 6812 le32_to_cpu(pEventReply->Data[ii]))); 6813 devtverboseprintk(ioc, printk("\n")); 6814 #endif 6815 6816 /* 6817 * Do general / base driver event processing 6818 */ 6819 switch(event) { 6820 case MPI_EVENT_EVENT_CHANGE: /* 0A */ 6821 if (evDataLen) { 6822 u8 evState = evData0 & 0xFF; 6823 6824 /* CHECKME! What if evState unexpectedly says OFF (0)? */ 6825 6826 /* Update EventState field in cached IocFacts */ 6827 if (ioc->facts.Function) { 6828 ioc->facts.EventState = evState; 6829 } 6830 } 6831 break; 6832 case MPI_EVENT_INTEGRATED_RAID: 6833 mptbase_raid_process_event_data(ioc, 6834 (MpiEventDataRaid_t *)pEventReply->Data); 6835 break; 6836 default: 6837 break; 6838 } 6839 6840 /* 6841 * Should this event be logged? Events are written sequentially. 6842 * When buffer is full, start again at the top. 6843 */ 6844 if (ioc->events && (ioc->eventTypes & ( 1 << event))) { 6845 int idx; 6846 6847 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE; 6848 6849 ioc->events[idx].event = event; 6850 ioc->events[idx].eventContext = ioc->eventContext; 6851 6852 for (ii = 0; ii < 2; ii++) { 6853 if (ii < evDataLen) 6854 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]); 6855 else 6856 ioc->events[idx].data[ii] = 0; 6857 } 6858 6859 ioc->eventContext++; 6860 } 6861 6862 6863 /* 6864 * Call each currently registered protocol event handler. 6865 */ 6866 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) { 6867 if (MptEvHandlers[cb_idx]) { 6868 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n", 6869 ioc->name, cb_idx)); 6870 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply); 6871 handlers++; 6872 } 6873 } 6874 /* FIXME? Examine results here? */ 6875 6876 /* 6877 * If needed, send (a single) EventAck. 6878 */ 6879 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) { 6880 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT 6881 "EventAck required\n",ioc->name)); 6882 if ((ii = SendEventAck(ioc, pEventReply)) != 0) { 6883 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n", 6884 ioc->name, ii)); 6885 } 6886 } 6887 6888 *evHandlers = handlers; 6889 return r; 6890 } 6891 6892 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6893 /** 6894 * mpt_fc_log_info - Log information returned from Fibre Channel IOC. 6895 * @ioc: Pointer to MPT_ADAPTER structure 6896 * @log_info: U32 LogInfo reply word from the IOC 6897 * 6898 * Refer to lsi/mpi_log_fc.h. 6899 */ 6900 static void 6901 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info) 6902 { 6903 char *desc = "unknown"; 6904 6905 switch (log_info & 0xFF000000) { 6906 case MPI_IOCLOGINFO_FC_INIT_BASE: 6907 desc = "FCP Initiator"; 6908 break; 6909 case MPI_IOCLOGINFO_FC_TARGET_BASE: 6910 desc = "FCP Target"; 6911 break; 6912 case MPI_IOCLOGINFO_FC_LAN_BASE: 6913 desc = "LAN"; 6914 break; 6915 case MPI_IOCLOGINFO_FC_MSG_BASE: 6916 desc = "MPI Message Layer"; 6917 break; 6918 case MPI_IOCLOGINFO_FC_LINK_BASE: 6919 desc = "FC Link"; 6920 break; 6921 case MPI_IOCLOGINFO_FC_CTX_BASE: 6922 desc = "Context Manager"; 6923 break; 6924 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET: 6925 desc = "Invalid Field Offset"; 6926 break; 6927 case MPI_IOCLOGINFO_FC_STATE_CHANGE: 6928 desc = "State Change Info"; 6929 break; 6930 } 6931 6932 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n", 6933 ioc->name, log_info, desc, (log_info & 0xFFFFFF)); 6934 } 6935 6936 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 6937 /** 6938 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC. 6939 * @ioc: Pointer to MPT_ADAPTER structure 6940 * @log_info: U32 LogInfo word from the IOC 6941 * 6942 * Refer to lsi/sp_log.h. 6943 */ 6944 static void 6945 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info) 6946 { 6947 u32 info = log_info & 0x00FF0000; 6948 char *desc = "unknown"; 6949 6950 switch (info) { 6951 case 0x00010000: 6952 desc = "bug! MID not found"; 6953 if (ioc->reload_fw == 0) 6954 ioc->reload_fw++; 6955 break; 6956 6957 case 0x00020000: 6958 desc = "Parity Error"; 6959 break; 6960 6961 case 0x00030000: 6962 desc = "ASYNC Outbound Overrun"; 6963 break; 6964 6965 case 0x00040000: 6966 desc = "SYNC Offset Error"; 6967 break; 6968 6969 case 0x00050000: 6970 desc = "BM Change"; 6971 break; 6972 6973 case 0x00060000: 6974 desc = "Msg In Overflow"; 6975 break; 6976 6977 case 0x00070000: 6978 desc = "DMA Error"; 6979 break; 6980 6981 case 0x00080000: 6982 desc = "Outbound DMA Overrun"; 6983 break; 6984 6985 case 0x00090000: 6986 desc = "Task Management"; 6987 break; 6988 6989 case 0x000A0000: 6990 desc = "Device Problem"; 6991 break; 6992 6993 case 0x000B0000: 6994 desc = "Invalid Phase Change"; 6995 break; 6996 6997 case 0x000C0000: 6998 desc = "Untagged Table Size"; 6999 break; 7000 7001 } 7002 7003 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc); 7004 } 7005 7006 /* strings for sas loginfo */ 7007 static char *originator_str[] = { 7008 "IOP", /* 00h */ 7009 "PL", /* 01h */ 7010 "IR" /* 02h */ 7011 }; 7012 static char *iop_code_str[] = { 7013 NULL, /* 00h */ 7014 "Invalid SAS Address", /* 01h */ 7015 NULL, /* 02h */ 7016 "Invalid Page", /* 03h */ 7017 "Diag Message Error", /* 04h */ 7018 "Task Terminated", /* 05h */ 7019 "Enclosure Management", /* 06h */ 7020 "Target Mode" /* 07h */ 7021 }; 7022 static char *pl_code_str[] = { 7023 NULL, /* 00h */ 7024 "Open Failure", /* 01h */ 7025 "Invalid Scatter Gather List", /* 02h */ 7026 "Wrong Relative Offset or Frame Length", /* 03h */ 7027 "Frame Transfer Error", /* 04h */ 7028 "Transmit Frame Connected Low", /* 05h */ 7029 "SATA Non-NCQ RW Error Bit Set", /* 06h */ 7030 "SATA Read Log Receive Data Error", /* 07h */ 7031 "SATA NCQ Fail All Commands After Error", /* 08h */ 7032 "SATA Error in Receive Set Device Bit FIS", /* 09h */ 7033 "Receive Frame Invalid Message", /* 0Ah */ 7034 "Receive Context Message Valid Error", /* 0Bh */ 7035 "Receive Frame Current Frame Error", /* 0Ch */ 7036 "SATA Link Down", /* 0Dh */ 7037 "Discovery SATA Init W IOS", /* 0Eh */ 7038 "Config Invalid Page", /* 0Fh */ 7039 "Discovery SATA Init Timeout", /* 10h */ 7040 "Reset", /* 11h */ 7041 "Abort", /* 12h */ 7042 "IO Not Yet Executed", /* 13h */ 7043 "IO Executed", /* 14h */ 7044 "Persistent Reservation Out Not Affiliation " 7045 "Owner", /* 15h */ 7046 "Open Transmit DMA Abort", /* 16h */ 7047 "IO Device Missing Delay Retry", /* 17h */ 7048 "IO Cancelled Due to Recieve Error", /* 18h */ 7049 NULL, /* 19h */ 7050 NULL, /* 1Ah */ 7051 NULL, /* 1Bh */ 7052 NULL, /* 1Ch */ 7053 NULL, /* 1Dh */ 7054 NULL, /* 1Eh */ 7055 NULL, /* 1Fh */ 7056 "Enclosure Management" /* 20h */ 7057 }; 7058 static char *ir_code_str[] = { 7059 "Raid Action Error", /* 00h */ 7060 NULL, /* 00h */ 7061 NULL, /* 01h */ 7062 NULL, /* 02h */ 7063 NULL, /* 03h */ 7064 NULL, /* 04h */ 7065 NULL, /* 05h */ 7066 NULL, /* 06h */ 7067 NULL /* 07h */ 7068 }; 7069 static char *raid_sub_code_str[] = { 7070 NULL, /* 00h */ 7071 "Volume Creation Failed: Data Passed too " 7072 "Large", /* 01h */ 7073 "Volume Creation Failed: Duplicate Volumes " 7074 "Attempted", /* 02h */ 7075 "Volume Creation Failed: Max Number " 7076 "Supported Volumes Exceeded", /* 03h */ 7077 "Volume Creation Failed: DMA Error", /* 04h */ 7078 "Volume Creation Failed: Invalid Volume Type", /* 05h */ 7079 "Volume Creation Failed: Error Reading " 7080 "MFG Page 4", /* 06h */ 7081 "Volume Creation Failed: Creating Internal " 7082 "Structures", /* 07h */ 7083 NULL, /* 08h */ 7084 NULL, /* 09h */ 7085 NULL, /* 0Ah */ 7086 NULL, /* 0Bh */ 7087 NULL, /* 0Ch */ 7088 NULL, /* 0Dh */ 7089 NULL, /* 0Eh */ 7090 NULL, /* 0Fh */ 7091 "Activation failed: Already Active Volume", /* 10h */ 7092 "Activation failed: Unsupported Volume Type", /* 11h */ 7093 "Activation failed: Too Many Active Volumes", /* 12h */ 7094 "Activation failed: Volume ID in Use", /* 13h */ 7095 "Activation failed: Reported Failure", /* 14h */ 7096 "Activation failed: Importing a Volume", /* 15h */ 7097 NULL, /* 16h */ 7098 NULL, /* 17h */ 7099 NULL, /* 18h */ 7100 NULL, /* 19h */ 7101 NULL, /* 1Ah */ 7102 NULL, /* 1Bh */ 7103 NULL, /* 1Ch */ 7104 NULL, /* 1Dh */ 7105 NULL, /* 1Eh */ 7106 NULL, /* 1Fh */ 7107 "Phys Disk failed: Too Many Phys Disks", /* 20h */ 7108 "Phys Disk failed: Data Passed too Large", /* 21h */ 7109 "Phys Disk failed: DMA Error", /* 22h */ 7110 "Phys Disk failed: Invalid <channel:id>", /* 23h */ 7111 "Phys Disk failed: Creating Phys Disk Config " 7112 "Page", /* 24h */ 7113 NULL, /* 25h */ 7114 NULL, /* 26h */ 7115 NULL, /* 27h */ 7116 NULL, /* 28h */ 7117 NULL, /* 29h */ 7118 NULL, /* 2Ah */ 7119 NULL, /* 2Bh */ 7120 NULL, /* 2Ch */ 7121 NULL, /* 2Dh */ 7122 NULL, /* 2Eh */ 7123 NULL, /* 2Fh */ 7124 "Compatibility Error: IR Disabled", /* 30h */ 7125 "Compatibility Error: Inquiry Comand Failed", /* 31h */ 7126 "Compatibility Error: Device not Direct Access " 7127 "Device ", /* 32h */ 7128 "Compatibility Error: Removable Device Found", /* 33h */ 7129 "Compatibility Error: Device SCSI Version not " 7130 "2 or Higher", /* 34h */ 7131 "Compatibility Error: SATA Device, 48 BIT LBA " 7132 "not Supported", /* 35h */ 7133 "Compatibility Error: Device doesn't have " 7134 "512 Byte Block Sizes", /* 36h */ 7135 "Compatibility Error: Volume Type Check Failed", /* 37h */ 7136 "Compatibility Error: Volume Type is " 7137 "Unsupported by FW", /* 38h */ 7138 "Compatibility Error: Disk Drive too Small for " 7139 "use in Volume", /* 39h */ 7140 "Compatibility Error: Phys Disk for Create " 7141 "Volume not Found", /* 3Ah */ 7142 "Compatibility Error: Too Many or too Few " 7143 "Disks for Volume Type", /* 3Bh */ 7144 "Compatibility Error: Disk stripe Sizes " 7145 "Must be 64KB", /* 3Ch */ 7146 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */ 7147 }; 7148 7149 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7150 /** 7151 * mpt_sas_log_info - Log information returned from SAS IOC. 7152 * @ioc: Pointer to MPT_ADAPTER structure 7153 * @log_info: U32 LogInfo reply word from the IOC 7154 * 7155 * Refer to lsi/mpi_log_sas.h. 7156 **/ 7157 static void 7158 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info) 7159 { 7160 union loginfo_type { 7161 u32 loginfo; 7162 struct { 7163 u32 subcode:16; 7164 u32 code:8; 7165 u32 originator:4; 7166 u32 bus_type:4; 7167 }dw; 7168 }; 7169 union loginfo_type sas_loginfo; 7170 char *originator_desc = NULL; 7171 char *code_desc = NULL; 7172 char *sub_code_desc = NULL; 7173 7174 sas_loginfo.loginfo = log_info; 7175 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) && 7176 (sas_loginfo.dw.originator < ARRAY_SIZE(originator_str))) 7177 return; 7178 7179 originator_desc = originator_str[sas_loginfo.dw.originator]; 7180 7181 switch (sas_loginfo.dw.originator) { 7182 7183 case 0: /* IOP */ 7184 if (sas_loginfo.dw.code < 7185 ARRAY_SIZE(iop_code_str)) 7186 code_desc = iop_code_str[sas_loginfo.dw.code]; 7187 break; 7188 case 1: /* PL */ 7189 if (sas_loginfo.dw.code < 7190 ARRAY_SIZE(pl_code_str)) 7191 code_desc = pl_code_str[sas_loginfo.dw.code]; 7192 break; 7193 case 2: /* IR */ 7194 if (sas_loginfo.dw.code >= 7195 ARRAY_SIZE(ir_code_str)) 7196 break; 7197 code_desc = ir_code_str[sas_loginfo.dw.code]; 7198 if (sas_loginfo.dw.subcode >= 7199 ARRAY_SIZE(raid_sub_code_str)) 7200 break; 7201 if (sas_loginfo.dw.code == 0) 7202 sub_code_desc = 7203 raid_sub_code_str[sas_loginfo.dw.subcode]; 7204 break; 7205 default: 7206 return; 7207 } 7208 7209 if (sub_code_desc != NULL) 7210 printk(MYIOC_s_INFO_FMT 7211 "LogInfo(0x%08x): Originator={%s}, Code={%s}," 7212 " SubCode={%s}\n", 7213 ioc->name, log_info, originator_desc, code_desc, 7214 sub_code_desc); 7215 else if (code_desc != NULL) 7216 printk(MYIOC_s_INFO_FMT 7217 "LogInfo(0x%08x): Originator={%s}, Code={%s}," 7218 " SubCode(0x%04x)\n", 7219 ioc->name, log_info, originator_desc, code_desc, 7220 sas_loginfo.dw.subcode); 7221 else 7222 printk(MYIOC_s_INFO_FMT 7223 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x)," 7224 " SubCode(0x%04x)\n", 7225 ioc->name, log_info, originator_desc, 7226 sas_loginfo.dw.code, sas_loginfo.dw.subcode); 7227 } 7228 7229 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7230 /** 7231 * mpt_iocstatus_info_config - IOCSTATUS information for config pages 7232 * @ioc: Pointer to MPT_ADAPTER structure 7233 * @ioc_status: U32 IOCStatus word from IOC 7234 * @mf: Pointer to MPT request frame 7235 * 7236 * Refer to lsi/mpi.h. 7237 **/ 7238 static void 7239 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) 7240 { 7241 Config_t *pReq = (Config_t *)mf; 7242 char extend_desc[EVENT_DESCR_STR_SZ]; 7243 char *desc = NULL; 7244 u32 form; 7245 u8 page_type; 7246 7247 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED) 7248 page_type = pReq->ExtPageType; 7249 else 7250 page_type = pReq->Header.PageType; 7251 7252 /* 7253 * ignore invalid page messages for GET_NEXT_HANDLE 7254 */ 7255 form = le32_to_cpu(pReq->PageAddress); 7256 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) { 7257 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE || 7258 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER || 7259 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) { 7260 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) == 7261 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE) 7262 return; 7263 } 7264 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE) 7265 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) == 7266 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID) 7267 return; 7268 } 7269 7270 snprintf(extend_desc, EVENT_DESCR_STR_SZ, 7271 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh", 7272 page_type, pReq->Header.PageNumber, pReq->Action, form); 7273 7274 switch (ioc_status) { 7275 7276 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */ 7277 desc = "Config Page Invalid Action"; 7278 break; 7279 7280 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */ 7281 desc = "Config Page Invalid Type"; 7282 break; 7283 7284 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */ 7285 desc = "Config Page Invalid Page"; 7286 break; 7287 7288 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */ 7289 desc = "Config Page Invalid Data"; 7290 break; 7291 7292 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */ 7293 desc = "Config Page No Defaults"; 7294 break; 7295 7296 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */ 7297 desc = "Config Page Can't Commit"; 7298 break; 7299 } 7300 7301 if (!desc) 7302 return; 7303 7304 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n", 7305 ioc->name, ioc_status, desc, extend_desc)); 7306 } 7307 7308 /** 7309 * mpt_iocstatus_info - IOCSTATUS information returned from IOC. 7310 * @ioc: Pointer to MPT_ADAPTER structure 7311 * @ioc_status: U32 IOCStatus word from IOC 7312 * @mf: Pointer to MPT request frame 7313 * 7314 * Refer to lsi/mpi.h. 7315 **/ 7316 static void 7317 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf) 7318 { 7319 u32 status = ioc_status & MPI_IOCSTATUS_MASK; 7320 char *desc = NULL; 7321 7322 switch (status) { 7323 7324 /****************************************************************************/ 7325 /* Common IOCStatus values for all replies */ 7326 /****************************************************************************/ 7327 7328 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */ 7329 desc = "Invalid Function"; 7330 break; 7331 7332 case MPI_IOCSTATUS_BUSY: /* 0x0002 */ 7333 desc = "Busy"; 7334 break; 7335 7336 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */ 7337 desc = "Invalid SGL"; 7338 break; 7339 7340 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */ 7341 desc = "Internal Error"; 7342 break; 7343 7344 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */ 7345 desc = "Reserved"; 7346 break; 7347 7348 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */ 7349 desc = "Insufficient Resources"; 7350 break; 7351 7352 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */ 7353 desc = "Invalid Field"; 7354 break; 7355 7356 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */ 7357 desc = "Invalid State"; 7358 break; 7359 7360 /****************************************************************************/ 7361 /* Config IOCStatus values */ 7362 /****************************************************************************/ 7363 7364 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */ 7365 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */ 7366 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */ 7367 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */ 7368 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */ 7369 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */ 7370 mpt_iocstatus_info_config(ioc, status, mf); 7371 break; 7372 7373 /****************************************************************************/ 7374 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */ 7375 /* */ 7376 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */ 7377 /* */ 7378 /****************************************************************************/ 7379 7380 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */ 7381 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */ 7382 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */ 7383 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */ 7384 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */ 7385 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */ 7386 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */ 7387 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */ 7388 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */ 7389 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */ 7390 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */ 7391 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */ 7392 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */ 7393 break; 7394 7395 /****************************************************************************/ 7396 /* SCSI Target values */ 7397 /****************************************************************************/ 7398 7399 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */ 7400 desc = "Target: Priority IO"; 7401 break; 7402 7403 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */ 7404 desc = "Target: Invalid Port"; 7405 break; 7406 7407 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */ 7408 desc = "Target Invalid IO Index:"; 7409 break; 7410 7411 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */ 7412 desc = "Target: Aborted"; 7413 break; 7414 7415 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */ 7416 desc = "Target: No Conn Retryable"; 7417 break; 7418 7419 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */ 7420 desc = "Target: No Connection"; 7421 break; 7422 7423 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */ 7424 desc = "Target: Transfer Count Mismatch"; 7425 break; 7426 7427 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */ 7428 desc = "Target: STS Data not Sent"; 7429 break; 7430 7431 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */ 7432 desc = "Target: Data Offset Error"; 7433 break; 7434 7435 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */ 7436 desc = "Target: Too Much Write Data"; 7437 break; 7438 7439 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */ 7440 desc = "Target: IU Too Short"; 7441 break; 7442 7443 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */ 7444 desc = "Target: ACK NAK Timeout"; 7445 break; 7446 7447 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */ 7448 desc = "Target: Nak Received"; 7449 break; 7450 7451 /****************************************************************************/ 7452 /* Fibre Channel Direct Access values */ 7453 /****************************************************************************/ 7454 7455 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */ 7456 desc = "FC: Aborted"; 7457 break; 7458 7459 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */ 7460 desc = "FC: RX ID Invalid"; 7461 break; 7462 7463 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */ 7464 desc = "FC: DID Invalid"; 7465 break; 7466 7467 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */ 7468 desc = "FC: Node Logged Out"; 7469 break; 7470 7471 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */ 7472 desc = "FC: Exchange Canceled"; 7473 break; 7474 7475 /****************************************************************************/ 7476 /* LAN values */ 7477 /****************************************************************************/ 7478 7479 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */ 7480 desc = "LAN: Device not Found"; 7481 break; 7482 7483 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */ 7484 desc = "LAN: Device Failure"; 7485 break; 7486 7487 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */ 7488 desc = "LAN: Transmit Error"; 7489 break; 7490 7491 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */ 7492 desc = "LAN: Transmit Aborted"; 7493 break; 7494 7495 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */ 7496 desc = "LAN: Receive Error"; 7497 break; 7498 7499 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */ 7500 desc = "LAN: Receive Aborted"; 7501 break; 7502 7503 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */ 7504 desc = "LAN: Partial Packet"; 7505 break; 7506 7507 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */ 7508 desc = "LAN: Canceled"; 7509 break; 7510 7511 /****************************************************************************/ 7512 /* Serial Attached SCSI values */ 7513 /****************************************************************************/ 7514 7515 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */ 7516 desc = "SAS: SMP Request Failed"; 7517 break; 7518 7519 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */ 7520 desc = "SAS: SMP Data Overrun"; 7521 break; 7522 7523 default: 7524 desc = "Others"; 7525 break; 7526 } 7527 7528 if (!desc) 7529 return; 7530 7531 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n", 7532 ioc->name, status, desc)); 7533 } 7534 7535 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7536 EXPORT_SYMBOL(mpt_attach); 7537 EXPORT_SYMBOL(mpt_detach); 7538 #ifdef CONFIG_PM 7539 EXPORT_SYMBOL(mpt_resume); 7540 EXPORT_SYMBOL(mpt_suspend); 7541 #endif 7542 EXPORT_SYMBOL(ioc_list); 7543 EXPORT_SYMBOL(mpt_register); 7544 EXPORT_SYMBOL(mpt_deregister); 7545 EXPORT_SYMBOL(mpt_event_register); 7546 EXPORT_SYMBOL(mpt_event_deregister); 7547 EXPORT_SYMBOL(mpt_reset_register); 7548 EXPORT_SYMBOL(mpt_reset_deregister); 7549 EXPORT_SYMBOL(mpt_device_driver_register); 7550 EXPORT_SYMBOL(mpt_device_driver_deregister); 7551 EXPORT_SYMBOL(mpt_get_msg_frame); 7552 EXPORT_SYMBOL(mpt_put_msg_frame); 7553 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri); 7554 EXPORT_SYMBOL(mpt_free_msg_frame); 7555 EXPORT_SYMBOL(mpt_add_sge); 7556 EXPORT_SYMBOL(mpt_send_handshake_request); 7557 EXPORT_SYMBOL(mpt_verify_adapter); 7558 EXPORT_SYMBOL(mpt_GetIocState); 7559 EXPORT_SYMBOL(mpt_print_ioc_summary); 7560 EXPORT_SYMBOL(mpt_HardResetHandler); 7561 EXPORT_SYMBOL(mpt_config); 7562 EXPORT_SYMBOL(mpt_findImVolumes); 7563 EXPORT_SYMBOL(mpt_alloc_fw_memory); 7564 EXPORT_SYMBOL(mpt_free_fw_memory); 7565 EXPORT_SYMBOL(mptbase_sas_persist_operation); 7566 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0); 7567 7568 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7569 /** 7570 * fusion_init - Fusion MPT base driver initialization routine. 7571 * 7572 * Returns 0 for success, non-zero for failure. 7573 */ 7574 static int __init 7575 fusion_init(void) 7576 { 7577 u8 cb_idx; 7578 7579 show_mptmod_ver(my_NAME, my_VERSION); 7580 printk(KERN_INFO COPYRIGHT "\n"); 7581 7582 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) { 7583 MptCallbacks[cb_idx] = NULL; 7584 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER; 7585 MptEvHandlers[cb_idx] = NULL; 7586 MptResetHandlers[cb_idx] = NULL; 7587 } 7588 7589 /* Register ourselves (mptbase) in order to facilitate 7590 * EventNotification handling. 7591 */ 7592 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER); 7593 7594 /* Register for hard reset handling callbacks. 7595 */ 7596 mpt_reset_register(mpt_base_index, mpt_ioc_reset); 7597 7598 #ifdef CONFIG_PROC_FS 7599 (void) procmpt_create(); 7600 #endif 7601 return 0; 7602 } 7603 7604 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 7605 /** 7606 * fusion_exit - Perform driver unload cleanup. 7607 * 7608 * This routine frees all resources associated with each MPT adapter 7609 * and removes all %MPT_PROCFS_MPTBASEDIR entries. 7610 */ 7611 static void __exit 7612 fusion_exit(void) 7613 { 7614 7615 mpt_reset_deregister(mpt_base_index); 7616 7617 #ifdef CONFIG_PROC_FS 7618 procmpt_destroy(); 7619 #endif 7620 } 7621 7622 module_init(fusion_init); 7623 module_exit(fusion_exit); 7624