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