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