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