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