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