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