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