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