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