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