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