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