2 * linux/drivers/message/fusion/mptbase.c
3 * This is the Fusion MPT base driver which supports multiple
4 * (SCSI + LAN) specialized protocol drivers.
5 * For use with LSI PCI chip/adapter(s)
6 * running LSI Fusion MPT (Message Passing Technology) firmware.
8 * Copyright (c) 1999-2008 LSI Corporation
9 * (mailto:DL-MPTFusionLinux@lsi.com)
12 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
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.
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.
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.
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
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
47 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
49 #include <linux/kernel.h>
50 #include <linux/module.h>
51 #include <linux/errno.h>
52 #include <linux/init.h>
53 #include <linux/slab.h>
54 #include <linux/types.h>
55 #include <linux/pci.h>
56 #include <linux/kdev_t.h>
57 #include <linux/blkdev.h>
58 #include <linux/delay.h>
59 #include <linux/interrupt.h> /* needed for in_interrupt() proto */
60 #include <linux/dma-mapping.h>
67 #include "lsi/mpi_log_fc.h"
69 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
70 #define my_NAME "Fusion MPT base driver"
71 #define my_VERSION MPT_LINUX_VERSION_COMMON
72 #define MYNAM "mptbase"
74 MODULE_AUTHOR(MODULEAUTHOR);
75 MODULE_DESCRIPTION(my_NAME);
76 MODULE_LICENSE("GPL");
77 MODULE_VERSION(my_VERSION);
82 static int mpt_msi_enable = -1;
83 module_param(mpt_msi_enable, int, 0);
84 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
86 static int mpt_channel_mapping;
87 module_param(mpt_channel_mapping, int, 0);
88 MODULE_PARM_DESC(mpt_channel_mapping, " Mapping id's to channels (default=0)");
90 static int mpt_debug_level;
91 static int mpt_set_debug_level(const char *val, struct kernel_param *kp);
92 module_param_call(mpt_debug_level, mpt_set_debug_level, param_get_int,
93 &mpt_debug_level, 0600);
94 MODULE_PARM_DESC(mpt_debug_level, " debug level - refer to mptdebug.h - (default=0)");
97 static int mfcounter = 0;
98 #define PRINT_MF_COUNT 20000
101 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
106 static struct proc_dir_entry *mpt_proc_root_dir;
108 #define WHOINIT_UNKNOWN 0xAA
110 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
114 /* Adapter link list */
116 /* Callback lookup table */
117 static MPT_CALLBACK MptCallbacks[MPT_MAX_PROTOCOL_DRIVERS];
118 /* Protocol driver class lookup table */
119 static int MptDriverClass[MPT_MAX_PROTOCOL_DRIVERS];
120 /* Event handler lookup table */
121 static MPT_EVHANDLER MptEvHandlers[MPT_MAX_PROTOCOL_DRIVERS];
122 /* Reset handler lookup table */
123 static MPT_RESETHANDLER MptResetHandlers[MPT_MAX_PROTOCOL_DRIVERS];
124 static struct mpt_pci_driver *MptDeviceDriverHandlers[MPT_MAX_PROTOCOL_DRIVERS];
126 static DECLARE_WAIT_QUEUE_HEAD(mpt_waitq);
129 * Driver Callback Index's
131 static u8 mpt_base_index = MPT_MAX_PROTOCOL_DRIVERS;
132 static u8 last_drv_idx;
134 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
138 static irqreturn_t mpt_interrupt(int irq, void *bus_id);
139 static int mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply);
140 static int mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes,
141 u32 *req, int replyBytes, u16 *u16reply, int maxwait,
143 static int mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag);
144 static void mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev);
145 static void mpt_adapter_disable(MPT_ADAPTER *ioc);
146 static void mpt_adapter_dispose(MPT_ADAPTER *ioc);
148 static void MptDisplayIocCapabilities(MPT_ADAPTER *ioc);
149 static int MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag);
150 static int GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason);
151 static int GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
152 static int SendIocInit(MPT_ADAPTER *ioc, int sleepFlag);
153 static int SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag);
154 static int mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag);
155 static int mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag);
156 static int mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
157 static int KickStart(MPT_ADAPTER *ioc, int ignore, int sleepFlag);
158 static int SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag);
159 static int PrimeIocFifos(MPT_ADAPTER *ioc);
160 static int WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
161 static int WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
162 static int WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag);
163 static int GetLanConfigPages(MPT_ADAPTER *ioc);
164 static int GetIoUnitPage2(MPT_ADAPTER *ioc);
165 int mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode);
166 static int mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum);
167 static int mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum);
168 static void mpt_read_ioc_pg_1(MPT_ADAPTER *ioc);
169 static void mpt_read_ioc_pg_4(MPT_ADAPTER *ioc);
170 static void mpt_timer_expired(unsigned long data);
171 static void mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc);
172 static int SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch);
173 static int SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp);
174 static int mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag);
175 static int mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init);
177 #ifdef CONFIG_PROC_FS
178 static int procmpt_summary_read(char *buf, char **start, off_t offset,
179 int request, int *eof, void *data);
180 static int procmpt_version_read(char *buf, char **start, off_t offset,
181 int request, int *eof, void *data);
182 static int procmpt_iocinfo_read(char *buf, char **start, off_t offset,
183 int request, int *eof, void *data);
185 static void mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc);
187 //int mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag);
188 static int ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *evReply, int *evHandlers);
189 static void mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf);
190 static void mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info);
191 static void mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info);
192 static void mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info);
193 static int mpt_read_ioc_pg_3(MPT_ADAPTER *ioc);
194 static void mpt_inactive_raid_list_free(MPT_ADAPTER *ioc);
196 /* module entry point */
197 static int __init fusion_init (void);
198 static void __exit fusion_exit (void);
200 #define CHIPREG_READ32(addr) readl_relaxed(addr)
201 #define CHIPREG_READ32_dmasync(addr) readl(addr)
202 #define CHIPREG_WRITE32(addr,val) writel(val, addr)
203 #define CHIPREG_PIO_WRITE32(addr,val) outl(val, (unsigned long)addr)
204 #define CHIPREG_PIO_READ32(addr) inl((unsigned long)addr)
207 pci_disable_io_access(struct pci_dev *pdev)
211 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
213 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
217 pci_enable_io_access(struct pci_dev *pdev)
221 pci_read_config_word(pdev, PCI_COMMAND, &command_reg);
223 pci_write_config_word(pdev, PCI_COMMAND, command_reg);
226 static int mpt_set_debug_level(const char *val, struct kernel_param *kp)
228 int ret = param_set_int(val, kp);
234 list_for_each_entry(ioc, &ioc_list, list)
235 ioc->debug_level = mpt_debug_level;
240 * mpt_get_cb_idx - obtain cb_idx for registered driver
241 * @dclass: class driver enum
243 * Returns cb_idx, or zero means it wasn't found
246 mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
250 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--)
251 if (MptDriverClass[cb_idx] == dclass)
257 * mpt_fault_reset_work - work performed on workq after ioc fault
258 * @work: input argument, used to derive ioc
262 mpt_fault_reset_work(struct work_struct *work)
265 container_of(work, MPT_ADAPTER, fault_reset_work.work);
270 if (ioc->diagPending || !ioc->active)
273 ioc_raw_state = mpt_GetIocState(ioc, 0);
274 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
275 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
276 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
277 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
278 ioc->name, __FUNCTION__);
279 rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
280 printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
281 __FUNCTION__, (rc == 0) ? "success" : "failed");
282 ioc_raw_state = mpt_GetIocState(ioc, 0);
283 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
284 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
285 "reset (%04xh)\n", ioc->name, ioc_raw_state &
286 MPI_DOORBELL_DATA_MASK);
291 * Take turns polling alternate controller
296 /* rearm the timer */
297 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags);
298 if (ioc->reset_work_q)
299 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
300 msecs_to_jiffies(MPT_POLLING_INTERVAL));
301 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags);
306 * Process turbo (context) reply...
309 mpt_turbo_reply(MPT_ADAPTER *ioc, u32 pa)
311 MPT_FRAME_HDR *mf = NULL;
312 MPT_FRAME_HDR *mr = NULL;
316 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got TURBO reply req_idx=%08x\n",
319 switch (pa >> MPI_CONTEXT_REPLY_TYPE_SHIFT) {
320 case MPI_CONTEXT_REPLY_TYPE_SCSI_INIT:
321 req_idx = pa & 0x0000FFFF;
322 cb_idx = (pa & 0x00FF0000) >> 16;
323 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
325 case MPI_CONTEXT_REPLY_TYPE_LAN:
326 cb_idx = mpt_get_cb_idx(MPTLAN_DRIVER);
328 * Blind set of mf to NULL here was fatal
329 * after lan_reply says "freeme"
330 * Fix sort of combined with an optimization here;
331 * added explicit check for case where lan_reply
332 * was just returning 1 and doing nothing else.
333 * For this case skip the callback, but set up
334 * proper mf value first here:-)
336 if ((pa & 0x58000000) == 0x58000000) {
337 req_idx = pa & 0x0000FFFF;
338 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
339 mpt_free_msg_frame(ioc, mf);
344 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
346 case MPI_CONTEXT_REPLY_TYPE_SCSI_TARGET:
347 cb_idx = mpt_get_cb_idx(MPTSTM_DRIVER);
348 mr = (MPT_FRAME_HDR *) CAST_U32_TO_PTR(pa);
355 /* Check for (valid) IO callback! */
356 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
357 MptCallbacks[cb_idx] == NULL) {
358 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
359 __FUNCTION__, ioc->name, cb_idx);
363 if (MptCallbacks[cb_idx](ioc, mf, mr))
364 mpt_free_msg_frame(ioc, mf);
370 mpt_reply(MPT_ADAPTER *ioc, u32 pa)
381 /* non-TURBO reply! Hmmm, something may be up...
382 * Newest turbo reply mechanism; get address
383 * via left shift 1 (get rid of MPI_ADDRESS_REPLY_A_BIT)!
386 /* Map DMA address of reply header to cpu address.
387 * pa is 32 bits - but the dma address may be 32 or 64 bits
388 * get offset based only only the low addresses
391 reply_dma_low = (pa <<= 1);
392 mr = (MPT_FRAME_HDR *)((u8 *)ioc->reply_frames +
393 (reply_dma_low - ioc->reply_frames_low_dma));
395 req_idx = le16_to_cpu(mr->u.frame.hwhdr.msgctxu.fld.req_idx);
396 cb_idx = mr->u.frame.hwhdr.msgctxu.fld.cb_idx;
397 mf = MPT_INDEX_2_MFPTR(ioc, req_idx);
399 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got non-TURBO reply=%p req_idx=%x cb_idx=%x Function=%x\n",
400 ioc->name, mr, req_idx, cb_idx, mr->u.hdr.Function));
401 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mr);
403 /* Check/log IOC log info
405 ioc_stat = le16_to_cpu(mr->u.reply.IOCStatus);
406 if (ioc_stat & MPI_IOCSTATUS_FLAG_LOG_INFO_AVAILABLE) {
407 u32 log_info = le32_to_cpu(mr->u.reply.IOCLogInfo);
408 if (ioc->bus_type == FC)
409 mpt_fc_log_info(ioc, log_info);
410 else if (ioc->bus_type == SPI)
411 mpt_spi_log_info(ioc, log_info);
412 else if (ioc->bus_type == SAS)
413 mpt_sas_log_info(ioc, log_info);
416 if (ioc_stat & MPI_IOCSTATUS_MASK)
417 mpt_iocstatus_info(ioc, (u32)ioc_stat, mf);
419 /* Check for (valid) IO callback! */
420 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS ||
421 MptCallbacks[cb_idx] == NULL) {
422 printk(MYIOC_s_WARN_FMT "%s: Invalid cb_idx (%d)!\n",
423 __FUNCTION__, ioc->name, cb_idx);
428 freeme = MptCallbacks[cb_idx](ioc, mf, mr);
431 /* Flush (non-TURBO) reply with a WRITE! */
432 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, pa);
435 mpt_free_msg_frame(ioc, mf);
439 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
441 * mpt_interrupt - MPT adapter (IOC) specific interrupt handler.
442 * @irq: irq number (not used)
443 * @bus_id: bus identifier cookie == pointer to MPT_ADAPTER structure
445 * This routine is registered via the request_irq() kernel API call,
446 * and handles all interrupts generated from a specific MPT adapter
447 * (also referred to as a IO Controller or IOC).
448 * This routine must clear the interrupt from the adapter and does
449 * so by reading the reply FIFO. Multiple replies may be processed
450 * per single call to this routine.
452 * This routine handles register-level access of the adapter but
453 * dispatches (calls) a protocol-specific callback routine to handle
454 * the protocol-specific details of the MPT request completion.
457 mpt_interrupt(int irq, void *bus_id)
459 MPT_ADAPTER *ioc = bus_id;
460 u32 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
462 if (pa == 0xFFFFFFFF)
466 * Drain the reply FIFO!
469 if (pa & MPI_ADDRESS_REPLY_A_BIT)
472 mpt_turbo_reply(ioc, pa);
473 pa = CHIPREG_READ32_dmasync(&ioc->chip->ReplyFifo);
474 } while (pa != 0xFFFFFFFF);
479 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
481 * mpt_base_reply - MPT base driver's callback routine
482 * @ioc: Pointer to MPT_ADAPTER structure
483 * @mf: Pointer to original MPT request frame
484 * @reply: Pointer to MPT reply frame (NULL if TurboReply)
486 * MPT base driver's callback routine; all base driver
487 * "internal" request/reply processing is routed here.
488 * Currently used for EventNotification and EventAck handling.
490 * Returns 1 indicating original alloc'd request frame ptr
491 * should be freed, or 0 if it shouldn't.
494 mpt_base_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *reply)
499 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply() called\n", ioc->name));
500 #ifdef CONFIG_FUSION_LOGGING
501 if ((ioc->debug_level & MPT_DEBUG_MSG_FRAME) &&
502 !(reply->u.hdr.MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY)) {
503 dmfprintk(ioc, printk(MYIOC_s_INFO_FMT ": Original request frame (@%p) header\n",
505 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)mf);
509 func = reply->u.hdr.Function;
510 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, Function=%02Xh\n",
513 if (func == MPI_FUNCTION_EVENT_NOTIFICATION) {
514 EventNotificationReply_t *pEvReply = (EventNotificationReply_t *) reply;
518 results = ProcessEventNotification(ioc, pEvReply, &evHandlers);
519 if (results != evHandlers) {
520 /* CHECKME! Any special handling needed here? */
521 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Called %d event handlers, sum results = %d\n",
522 ioc->name, evHandlers, results));
526 * Hmmm... It seems that EventNotificationReply is an exception
527 * to the rule of one reply per request.
529 if (pEvReply->MsgFlags & MPI_MSGFLAGS_CONTINUATION_REPLY) {
532 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "EVENT_NOTIFICATION reply %p returns Request frame\n",
533 ioc->name, pEvReply));
536 #ifdef CONFIG_PROC_FS
537 // LogEvent(ioc, pEvReply);
540 } else if (func == MPI_FUNCTION_EVENT_ACK) {
541 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_base_reply, EventAck reply received\n",
543 } else if (func == MPI_FUNCTION_CONFIG) {
547 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "config_complete (mf=%p,mr=%p)\n",
548 ioc->name, mf, reply));
550 pCfg = * ((CONFIGPARMS **)((u8 *) mf + ioc->req_sz - sizeof(void *)));
553 /* disable timer and remove from linked list */
554 del_timer(&pCfg->timer);
556 spin_lock_irqsave(&ioc->FreeQlock, flags);
557 list_del(&pCfg->linkage);
558 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
561 * If IOC Status is SUCCESS, save the header
562 * and set the status code to GOOD.
564 pCfg->status = MPT_CONFIG_ERROR;
566 ConfigReply_t *pReply = (ConfigReply_t *)reply;
569 status = le16_to_cpu(pReply->IOCStatus) & MPI_IOCSTATUS_MASK;
570 dcprintk(ioc, printk(MYIOC_s_NOTE_FMT " IOCStatus=%04xh, IOCLogInfo=%08xh\n",
571 ioc->name, status, le32_to_cpu(pReply->IOCLogInfo)));
573 pCfg->status = status;
574 if (status == MPI_IOCSTATUS_SUCCESS) {
575 if ((pReply->Header.PageType &
576 MPI_CONFIG_PAGETYPE_MASK) ==
577 MPI_CONFIG_PAGETYPE_EXTENDED) {
578 pCfg->cfghdr.ehdr->ExtPageLength =
579 le16_to_cpu(pReply->ExtPageLength);
580 pCfg->cfghdr.ehdr->ExtPageType =
583 pCfg->cfghdr.hdr->PageVersion = pReply->Header.PageVersion;
585 /* If this is a regular header, save PageLength. */
586 /* LMP Do this better so not using a reserved field! */
587 pCfg->cfghdr.hdr->PageLength = pReply->Header.PageLength;
588 pCfg->cfghdr.hdr->PageNumber = pReply->Header.PageNumber;
589 pCfg->cfghdr.hdr->PageType = pReply->Header.PageType;
594 * Wake up the original calling thread
599 } else if (func == MPI_FUNCTION_SAS_IO_UNIT_CONTROL) {
600 /* we should be always getting a reply frame */
601 memcpy(ioc->persist_reply_frame, reply,
602 min(MPT_DEFAULT_FRAME_SIZE,
603 4*reply->u.reply.MsgLength));
604 del_timer(&ioc->persist_timer);
605 ioc->persist_wait_done = 1;
608 printk(MYIOC_s_ERR_FMT "Unexpected msg function (=%02Xh) reply received!\n",
613 * Conditionally tell caller to free the original
614 * EventNotification/EventAck/unexpected request frame!
619 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
621 * mpt_register - Register protocol-specific main callback handler.
622 * @cbfunc: callback function pointer
623 * @dclass: Protocol driver's class (%MPT_DRIVER_CLASS enum value)
625 * This routine is called by a protocol-specific driver (SCSI host,
626 * LAN, SCSI target) to register its reply callback routine. Each
627 * protocol-specific driver must do this before it will be able to
628 * use any IOC resources, such as obtaining request frames.
630 * NOTES: The SCSI protocol driver currently calls this routine thrice
631 * in order to register separate callbacks; one for "normal" SCSI IO;
632 * one for MptScsiTaskMgmt requests; one for Scan/DV requests.
634 * Returns u8 valued "handle" in the range (and S.O.D. order)
635 * {N,...,7,6,5,...,1} if successful.
636 * A return value of MPT_MAX_PROTOCOL_DRIVERS (including zero!) should be
637 * considered an error by the caller.
640 mpt_register(MPT_CALLBACK cbfunc, MPT_DRIVER_CLASS dclass)
643 last_drv_idx = MPT_MAX_PROTOCOL_DRIVERS;
646 * Search for empty callback slot in this order: {N,...,7,6,5,...,1}
647 * (slot/handle 0 is reserved!)
649 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
650 if (MptCallbacks[cb_idx] == NULL) {
651 MptCallbacks[cb_idx] = cbfunc;
652 MptDriverClass[cb_idx] = dclass;
653 MptEvHandlers[cb_idx] = NULL;
654 last_drv_idx = cb_idx;
662 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
664 * mpt_deregister - Deregister a protocol drivers resources.
665 * @cb_idx: previously registered callback handle
667 * Each protocol-specific driver should call this routine when its
668 * module is unloaded.
671 mpt_deregister(u8 cb_idx)
673 if (cb_idx && (cb_idx < MPT_MAX_PROTOCOL_DRIVERS)) {
674 MptCallbacks[cb_idx] = NULL;
675 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
676 MptEvHandlers[cb_idx] = NULL;
682 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
684 * mpt_event_register - Register protocol-specific event callback handler.
685 * @cb_idx: previously registered (via mpt_register) callback handle
686 * @ev_cbfunc: callback function
688 * This routine can be called by one or more protocol-specific drivers
689 * if/when they choose to be notified of MPT events.
691 * Returns 0 for success.
694 mpt_event_register(u8 cb_idx, MPT_EVHANDLER ev_cbfunc)
696 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
699 MptEvHandlers[cb_idx] = ev_cbfunc;
703 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
705 * mpt_event_deregister - Deregister protocol-specific event callback handler
706 * @cb_idx: previously registered callback handle
708 * Each protocol-specific driver should call this routine
709 * when it does not (or can no longer) handle events,
710 * or when its module is unloaded.
713 mpt_event_deregister(u8 cb_idx)
715 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
718 MptEvHandlers[cb_idx] = NULL;
721 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
723 * mpt_reset_register - Register protocol-specific IOC reset handler.
724 * @cb_idx: previously registered (via mpt_register) callback handle
725 * @reset_func: reset function
727 * This routine can be called by one or more protocol-specific drivers
728 * if/when they choose to be notified of IOC resets.
730 * Returns 0 for success.
733 mpt_reset_register(u8 cb_idx, MPT_RESETHANDLER reset_func)
735 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
738 MptResetHandlers[cb_idx] = reset_func;
742 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
744 * mpt_reset_deregister - Deregister protocol-specific IOC reset handler.
745 * @cb_idx: previously registered callback handle
747 * Each protocol-specific driver should call this routine
748 * when it does not (or can no longer) handle IOC reset handling,
749 * or when its module is unloaded.
752 mpt_reset_deregister(u8 cb_idx)
754 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
757 MptResetHandlers[cb_idx] = NULL;
760 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
762 * mpt_device_driver_register - Register device driver hooks
763 * @dd_cbfunc: driver callbacks struct
764 * @cb_idx: MPT protocol driver index
767 mpt_device_driver_register(struct mpt_pci_driver * dd_cbfunc, u8 cb_idx)
770 const struct pci_device_id *id;
772 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
775 MptDeviceDriverHandlers[cb_idx] = dd_cbfunc;
777 /* call per pci device probe entry point */
778 list_for_each_entry(ioc, &ioc_list, list) {
779 id = ioc->pcidev->driver ?
780 ioc->pcidev->driver->id_table : NULL;
781 if (dd_cbfunc->probe)
782 dd_cbfunc->probe(ioc->pcidev, id);
788 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
790 * mpt_device_driver_deregister - DeRegister device driver hooks
791 * @cb_idx: MPT protocol driver index
794 mpt_device_driver_deregister(u8 cb_idx)
796 struct mpt_pci_driver *dd_cbfunc;
799 if (!cb_idx || cb_idx >= MPT_MAX_PROTOCOL_DRIVERS)
802 dd_cbfunc = MptDeviceDriverHandlers[cb_idx];
804 list_for_each_entry(ioc, &ioc_list, list) {
805 if (dd_cbfunc->remove)
806 dd_cbfunc->remove(ioc->pcidev);
809 MptDeviceDriverHandlers[cb_idx] = NULL;
813 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
815 * mpt_get_msg_frame - Obtain an MPT request frame from the pool
816 * @cb_idx: Handle of registered MPT protocol driver
817 * @ioc: Pointer to MPT adapter structure
819 * Obtain an MPT request frame from the pool (of 1024) that are
820 * allocated per MPT adapter.
822 * Returns pointer to a MPT request frame or %NULL if none are available
823 * or IOC is not active.
826 mpt_get_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc)
830 u16 req_idx; /* Request index */
832 /* validate handle and ioc identifier */
836 printk(MYIOC_s_WARN_FMT "IOC Not Active! mpt_get_msg_frame "
837 "returning NULL!\n", ioc->name);
840 /* If interrupts are not attached, do not return a request frame */
844 spin_lock_irqsave(&ioc->FreeQlock, flags);
845 if (!list_empty(&ioc->FreeQ)) {
848 mf = list_entry(ioc->FreeQ.next, MPT_FRAME_HDR,
849 u.frame.linkage.list);
850 list_del(&mf->u.frame.linkage.list);
851 mf->u.frame.linkage.arg1 = 0;
852 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
853 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
855 req_idx = req_offset / ioc->req_sz;
856 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
857 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
858 /* Default, will be changed if necessary in SG generation */
859 ioc->RequestNB[req_idx] = ioc->NB_for_64_byte_frame;
866 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
870 printk(MYIOC_s_WARN_FMT "IOC Active. No free Msg Frames! "
871 "Count 0x%x Max 0x%x\n", ioc->name, ioc->mfcnt,
874 if (mfcounter == PRINT_MF_COUNT)
875 printk(MYIOC_s_INFO_FMT "MF Count 0x%x Max 0x%x \n", ioc->name,
876 ioc->mfcnt, ioc->req_depth);
879 dmfprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_get_msg_frame(%d,%d), got mf=%p\n",
880 ioc->name, cb_idx, ioc->id, mf));
884 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
886 * mpt_put_msg_frame - Send a protocol-specific MPT request frame to an IOC
887 * @cb_idx: Handle of registered MPT protocol driver
888 * @ioc: Pointer to MPT adapter structure
889 * @mf: Pointer to MPT request frame
891 * This routine posts an MPT request frame to the request post FIFO of a
892 * specific MPT adapter.
895 mpt_put_msg_frame(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
899 u16 req_idx; /* Request index */
901 /* ensure values are reset properly! */
902 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx; /* byte */
903 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
905 req_idx = req_offset / ioc->req_sz;
906 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
907 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
909 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
911 mf_dma_addr = (ioc->req_frames_low_dma + req_offset) | ioc->RequestNB[req_idx];
912 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d "
913 "RequestNB=%x\n", ioc->name, mf_dma_addr, req_idx,
914 ioc->RequestNB[req_idx]));
915 CHIPREG_WRITE32(&ioc->chip->RequestFifo, mf_dma_addr);
919 * mpt_put_msg_frame_hi_pri - Send a hi-pri protocol-specific MPT request frame
920 * @cb_idx: Handle of registered MPT protocol driver
921 * @ioc: Pointer to MPT adapter structure
922 * @mf: Pointer to MPT request frame
924 * Send a protocol-specific MPT request frame to an IOC using
925 * hi-priority request queue.
927 * This routine posts an MPT request frame to the request post FIFO of a
928 * specific MPT adapter.
931 mpt_put_msg_frame_hi_pri(u8 cb_idx, MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
935 u16 req_idx; /* Request index */
937 /* ensure values are reset properly! */
938 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
939 req_offset = (u8 *)mf - (u8 *)ioc->req_frames;
940 req_idx = req_offset / ioc->req_sz;
941 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(req_idx);
942 mf->u.frame.hwhdr.msgctxu.fld.rsvd = 0;
944 DBG_DUMP_PUT_MSG_FRAME(ioc, (u32 *)mf);
946 mf_dma_addr = (ioc->req_frames_low_dma + req_offset);
947 dsgprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mf_dma_addr=%x req_idx=%d\n",
948 ioc->name, mf_dma_addr, req_idx));
949 CHIPREG_WRITE32(&ioc->chip->RequestHiPriFifo, mf_dma_addr);
952 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
954 * mpt_free_msg_frame - Place MPT request frame back on FreeQ.
955 * @handle: Handle of registered MPT protocol driver
956 * @ioc: Pointer to MPT adapter structure
957 * @mf: Pointer to MPT request frame
959 * This routine places a MPT request frame back on the MPT adapter's
963 mpt_free_msg_frame(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
967 /* Put Request back on FreeQ! */
968 spin_lock_irqsave(&ioc->FreeQlock, flags);
969 mf->u.frame.linkage.arg1 = 0xdeadbeaf; /* signature to know if this mf is freed */
970 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
974 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
977 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
979 * mpt_add_sge - Place a simple SGE at address pAddr.
980 * @pAddr: virtual address for SGE
981 * @flagslength: SGE flags and data transfer length
982 * @dma_addr: Physical address
984 * This routine places a MPT request frame back on the MPT adapter's
988 mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
990 if (sizeof(dma_addr_t) == sizeof(u64)) {
991 SGESimple64_t *pSge = (SGESimple64_t *) pAddr;
992 u32 tmp = dma_addr & 0xFFFFFFFF;
994 pSge->FlagsLength = cpu_to_le32(flagslength);
995 pSge->Address.Low = cpu_to_le32(tmp);
996 tmp = (u32) ((u64)dma_addr >> 32);
997 pSge->Address.High = cpu_to_le32(tmp);
1000 SGESimple32_t *pSge = (SGESimple32_t *) pAddr;
1001 pSge->FlagsLength = cpu_to_le32(flagslength);
1002 pSge->Address = cpu_to_le32(dma_addr);
1006 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1008 * mpt_send_handshake_request - Send MPT request via doorbell handshake method.
1009 * @cb_idx: Handle of registered MPT protocol driver
1010 * @ioc: Pointer to MPT adapter structure
1011 * @reqBytes: Size of the request in bytes
1012 * @req: Pointer to MPT request frame
1013 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
1015 * This routine is used exclusively to send MptScsiTaskMgmt
1016 * requests since they are required to be sent via doorbell handshake.
1018 * NOTE: It is the callers responsibility to byte-swap fields in the
1019 * request which are greater than 1 byte in size.
1021 * Returns 0 for success, non-zero for failure.
1024 mpt_send_handshake_request(u8 cb_idx, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
1030 /* State is known to be good upon entering
1031 * this function so issue the bus reset
1036 * Emulate what mpt_put_msg_frame() does /wrt to sanity
1037 * setting cb_idx/req_idx. But ONLY if this request
1038 * is in proper (pre-alloc'd) request buffer range...
1040 ii = MFPTR_2_MPT_INDEX(ioc,(MPT_FRAME_HDR*)req);
1041 if (reqBytes >= 12 && ii >= 0 && ii < ioc->req_depth) {
1042 MPT_FRAME_HDR *mf = (MPT_FRAME_HDR*)req;
1043 mf->u.frame.hwhdr.msgctxu.fld.req_idx = cpu_to_le16(ii);
1044 mf->u.frame.hwhdr.msgctxu.fld.cb_idx = cb_idx;
1047 /* Make sure there are no doorbells */
1048 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1050 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1051 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
1052 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
1054 /* Wait for IOC doorbell int */
1055 if ((ii = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0) {
1059 /* Read doorbell and check for active bit */
1060 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
1063 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_send_handshake_request start, WaitCnt=%d\n",
1066 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1068 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1072 /* Send request via doorbell handshake */
1073 req_as_bytes = (u8 *) req;
1074 for (ii = 0; ii < reqBytes/4; ii++) {
1077 word = ((req_as_bytes[(ii*4) + 0] << 0) |
1078 (req_as_bytes[(ii*4) + 1] << 8) |
1079 (req_as_bytes[(ii*4) + 2] << 16) |
1080 (req_as_bytes[(ii*4) + 3] << 24));
1081 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
1082 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1088 if (r >= 0 && WaitForDoorbellInt(ioc, 10, sleepFlag) >= 0)
1093 /* Make sure there are no doorbells */
1094 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1099 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1101 * mpt_host_page_access_control - control the IOC's Host Page Buffer access
1102 * @ioc: Pointer to MPT adapter structure
1103 * @access_control_value: define bits below
1104 * @sleepFlag: Specifies whether the process can sleep
1106 * Provides mechanism for the host driver to control the IOC's
1107 * Host Page Buffer access.
1109 * Access Control Value - bits[15:12]
1111 * 1h Enable Access { MPI_DB_HPBAC_ENABLE_ACCESS }
1112 * 2h Disable Access { MPI_DB_HPBAC_DISABLE_ACCESS }
1113 * 3h Free Buffer { MPI_DB_HPBAC_FREE_BUFFER }
1115 * Returns 0 for success, non-zero for failure.
1119 mpt_host_page_access_control(MPT_ADAPTER *ioc, u8 access_control_value, int sleepFlag)
1123 /* return if in use */
1124 if (CHIPREG_READ32(&ioc->chip->Doorbell)
1125 & MPI_DOORBELL_ACTIVE)
1128 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1130 CHIPREG_WRITE32(&ioc->chip->Doorbell,
1131 ((MPI_FUNCTION_HOST_PAGEBUF_ACCESS_CONTROL
1132 <<MPI_DOORBELL_FUNCTION_SHIFT) |
1133 (access_control_value<<12)));
1135 /* Wait for IOC to clear Doorbell Status bit */
1136 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0) {
1142 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1144 * mpt_host_page_alloc - allocate system memory for the fw
1145 * @ioc: Pointer to pointer to IOC adapter
1146 * @ioc_init: Pointer to ioc init config page
1148 * If we already allocated memory in past, then resend the same pointer.
1149 * Returns 0 for success, non-zero for failure.
1152 mpt_host_page_alloc(MPT_ADAPTER *ioc, pIOCInit_t ioc_init)
1156 u32 host_page_buffer_sz=0;
1158 if(!ioc->HostPageBuffer) {
1160 host_page_buffer_sz =
1161 le32_to_cpu(ioc->facts.HostPageBufferSGE.FlagsLength) & 0xFFFFFF;
1163 if(!host_page_buffer_sz)
1164 return 0; /* fw doesn't need any host buffers */
1166 /* spin till we get enough memory */
1167 while(host_page_buffer_sz > 0) {
1169 if((ioc->HostPageBuffer = pci_alloc_consistent(
1171 host_page_buffer_sz,
1172 &ioc->HostPageBuffer_dma)) != NULL) {
1174 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
1175 "host_page_buffer @ %p, dma @ %x, sz=%d bytes\n",
1176 ioc->name, ioc->HostPageBuffer,
1177 (u32)ioc->HostPageBuffer_dma,
1178 host_page_buffer_sz));
1179 ioc->alloc_total += host_page_buffer_sz;
1180 ioc->HostPageBuffer_sz = host_page_buffer_sz;
1184 host_page_buffer_sz -= (4*1024);
1188 if(!ioc->HostPageBuffer) {
1189 printk(MYIOC_s_ERR_FMT
1190 "Failed to alloc memory for host_page_buffer!\n",
1195 psge = (char *)&ioc_init->HostPageBufferSGE;
1196 flags_length = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
1197 MPI_SGE_FLAGS_SYSTEM_ADDRESS |
1198 MPI_SGE_FLAGS_32_BIT_ADDRESSING |
1199 MPI_SGE_FLAGS_HOST_TO_IOC |
1200 MPI_SGE_FLAGS_END_OF_BUFFER;
1201 if (sizeof(dma_addr_t) == sizeof(u64)) {
1202 flags_length |= MPI_SGE_FLAGS_64_BIT_ADDRESSING;
1204 flags_length = flags_length << MPI_SGE_FLAGS_SHIFT;
1205 flags_length |= ioc->HostPageBuffer_sz;
1206 mpt_add_sge(psge, flags_length, ioc->HostPageBuffer_dma);
1207 ioc->facts.HostPageBufferSGE = ioc_init->HostPageBufferSGE;
1212 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1214 * mpt_verify_adapter - Given IOC identifier, set pointer to its adapter structure.
1215 * @iocid: IOC unique identifier (integer)
1216 * @iocpp: Pointer to pointer to IOC adapter
1218 * Given a unique IOC identifier, set pointer to the associated MPT
1219 * adapter structure.
1221 * Returns iocid and sets iocpp if iocid is found.
1222 * Returns -1 if iocid is not found.
1225 mpt_verify_adapter(int iocid, MPT_ADAPTER **iocpp)
1229 list_for_each_entry(ioc,&ioc_list,list) {
1230 if (ioc->id == iocid) {
1241 * mpt_get_product_name - returns product string
1242 * @vendor: pci vendor id
1243 * @device: pci device id
1244 * @revision: pci revision id
1245 * @prod_name: string returned
1247 * Returns product string displayed when driver loads,
1248 * in /proc/mpt/summary and /sysfs/class/scsi_host/host<X>/version_product
1252 mpt_get_product_name(u16 vendor, u16 device, u8 revision, char *prod_name)
1254 char *product_str = NULL;
1256 if (vendor == PCI_VENDOR_ID_BROCADE) {
1259 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1263 product_str = "BRE040 A0";
1266 product_str = "BRE040 A1";
1269 product_str = "BRE040";
1279 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1280 product_str = "LSIFC909 B1";
1282 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1283 product_str = "LSIFC919 B0";
1285 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1286 product_str = "LSIFC929 B0";
1288 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1289 if (revision < 0x80)
1290 product_str = "LSIFC919X A0";
1292 product_str = "LSIFC919XL A1";
1294 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1295 if (revision < 0x80)
1296 product_str = "LSIFC929X A0";
1298 product_str = "LSIFC929XL A1";
1300 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1301 product_str = "LSIFC939X A1";
1303 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1304 product_str = "LSIFC949X A1";
1306 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1310 product_str = "LSIFC949E A0";
1313 product_str = "LSIFC949E A1";
1316 product_str = "LSIFC949E";
1320 case MPI_MANUFACTPAGE_DEVID_53C1030:
1324 product_str = "LSI53C1030 A0";
1327 product_str = "LSI53C1030 B0";
1330 product_str = "LSI53C1030 B1";
1333 product_str = "LSI53C1030 B2";
1336 product_str = "LSI53C1030 C0";
1339 product_str = "LSI53C1030T A0";
1342 product_str = "LSI53C1030T A2";
1345 product_str = "LSI53C1030T A3";
1348 product_str = "LSI53C1020A A1";
1351 product_str = "LSI53C1030";
1355 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1359 product_str = "LSI53C1035 A2";
1362 product_str = "LSI53C1035 B0";
1365 product_str = "LSI53C1035";
1369 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1373 product_str = "LSISAS1064 A1";
1376 product_str = "LSISAS1064 A2";
1379 product_str = "LSISAS1064 A3";
1382 product_str = "LSISAS1064 A4";
1385 product_str = "LSISAS1064";
1389 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1393 product_str = "LSISAS1064E A0";
1396 product_str = "LSISAS1064E B0";
1399 product_str = "LSISAS1064E B1";
1402 product_str = "LSISAS1064E B2";
1405 product_str = "LSISAS1064E B3";
1408 product_str = "LSISAS1064E";
1412 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1416 product_str = "LSISAS1068 A0";
1419 product_str = "LSISAS1068 B0";
1422 product_str = "LSISAS1068 B1";
1425 product_str = "LSISAS1068";
1429 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1433 product_str = "LSISAS1068E A0";
1436 product_str = "LSISAS1068E B0";
1439 product_str = "LSISAS1068E B1";
1442 product_str = "LSISAS1068E B2";
1445 product_str = "LSISAS1068E B3";
1448 product_str = "LSISAS1068E";
1452 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1456 product_str = "LSISAS1078 A0";
1459 product_str = "LSISAS1078 B0";
1462 product_str = "LSISAS1078 C0";
1465 product_str = "LSISAS1078 C1";
1468 product_str = "LSISAS1078 C2";
1471 product_str = "LSISAS1078";
1479 sprintf(prod_name, "%s", product_str);
1483 * mpt_mapresources - map in memory mapped io
1484 * @ioc: Pointer to pointer to IOC adapter
1488 mpt_mapresources(MPT_ADAPTER *ioc)
1492 unsigned long mem_phys;
1498 struct pci_dev *pdev;
1501 ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM);
1502 if (pci_enable_device_mem(pdev)) {
1503 printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() "
1504 "failed\n", ioc->name);
1507 if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) {
1508 printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with "
1509 "MEM failed\n", ioc->name);
1513 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1515 if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)
1516 && !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK)) {
1517 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1518 ": 64 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1520 } else if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)
1521 && !pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK)) {
1522 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
1523 ": 32 BIT PCI BUS DMA ADDRESSING SUPPORTED\n",
1526 printk(MYIOC_s_WARN_FMT "no suitable DMA mask for %s\n",
1527 ioc->name, pci_name(pdev));
1528 pci_release_selected_regions(pdev, ioc->bars);
1532 mem_phys = msize = 0;
1534 for (ii = 0; ii < DEVICE_COUNT_RESOURCE; ii++) {
1535 if (pci_resource_flags(pdev, ii) & PCI_BASE_ADDRESS_SPACE_IO) {
1538 /* Get I/O space! */
1539 port = pci_resource_start(pdev, ii);
1540 psize = pci_resource_len(pdev, ii);
1545 mem_phys = pci_resource_start(pdev, ii);
1546 msize = pci_resource_len(pdev, ii);
1549 ioc->mem_size = msize;
1552 /* Get logical ptr for PciMem0 space */
1553 /*mem = ioremap(mem_phys, msize);*/
1554 mem = ioremap(mem_phys, msize);
1556 printk(MYIOC_s_ERR_FMT ": ERROR - Unable to map adapter"
1557 " memory!\n", ioc->name);
1561 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "mem = %p, mem_phys = %lx\n",
1562 ioc->name, mem, mem_phys));
1564 ioc->mem_phys = mem_phys;
1565 ioc->chip = (SYSIF_REGS __iomem *)mem;
1567 /* Save Port IO values in case we need to do downloadboot */
1568 ioc->pio_mem_phys = port;
1569 ioc->pio_chip = (SYSIF_REGS __iomem *)port;
1574 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1576 * mpt_attach - Install a PCI intelligent MPT adapter.
1577 * @pdev: Pointer to pci_dev structure
1578 * @id: PCI device ID information
1580 * This routine performs all the steps necessary to bring the IOC of
1581 * a MPT adapter to a OPERATIONAL state. This includes registering
1582 * memory regions, registering the interrupt, and allocating request
1583 * and reply memory pools.
1585 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
1588 * Returns 0 for success, non-zero for failure.
1590 * TODO: Add support for polled controllers
1593 mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
1600 static int mpt_ids = 0;
1601 #ifdef CONFIG_PROC_FS
1602 struct proc_dir_entry *dent, *ent;
1605 ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC);
1607 printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n");
1611 ioc->id = mpt_ids++;
1612 sprintf(ioc->name, "ioc%d", ioc->id);
1615 * set initial debug level
1616 * (refer to mptdebug.h)
1619 ioc->debug_level = mpt_debug_level;
1620 if (mpt_debug_level)
1621 printk(KERN_INFO "mpt_debug_level=%xh\n", mpt_debug_level);
1623 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name));
1626 if (mpt_mapresources(ioc)) {
1631 ioc->alloc_total = sizeof(MPT_ADAPTER);
1632 ioc->req_sz = MPT_DEFAULT_FRAME_SIZE; /* avoid div by zero! */
1633 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
1636 ioc->diagPending = 0;
1637 spin_lock_init(&ioc->diagLock);
1638 spin_lock_init(&ioc->initializing_hba_lock);
1640 /* Initialize the event logging.
1642 ioc->eventTypes = 0; /* None */
1643 ioc->eventContext = 0;
1644 ioc->eventLogSize = 0;
1651 ioc->cached_fw = NULL;
1653 /* Initilize SCSI Config Data structure
1655 memset(&ioc->spi_data, 0, sizeof(SpiCfgData));
1657 /* Initialize the running configQ head.
1659 INIT_LIST_HEAD(&ioc->configQ);
1661 /* Initialize the fc rport list head.
1663 INIT_LIST_HEAD(&ioc->fc_rports);
1665 /* Find lookup slot. */
1666 INIT_LIST_HEAD(&ioc->list);
1669 /* Initialize workqueue */
1670 INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
1671 spin_lock_init(&ioc->fault_reset_work_lock);
1673 snprintf(ioc->reset_work_q_name, KOBJ_NAME_LEN, "mpt_poll_%d", ioc->id);
1675 create_singlethread_workqueue(ioc->reset_work_q_name);
1676 if (!ioc->reset_work_q) {
1677 printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
1679 pci_release_selected_regions(pdev, ioc->bars);
1684 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
1685 ioc->name, &ioc->facts, &ioc->pfacts[0]));
1687 pci_read_config_byte(pdev, PCI_CLASS_REVISION, &revision);
1688 mpt_get_product_name(pdev->vendor, pdev->device, revision, ioc->prod_name);
1690 switch (pdev->device)
1692 case MPI_MANUFACTPAGE_DEVICEID_FC939X:
1693 case MPI_MANUFACTPAGE_DEVICEID_FC949X:
1694 ioc->errata_flag_1064 = 1;
1695 case MPI_MANUFACTPAGE_DEVICEID_FC909:
1696 case MPI_MANUFACTPAGE_DEVICEID_FC929:
1697 case MPI_MANUFACTPAGE_DEVICEID_FC919:
1698 case MPI_MANUFACTPAGE_DEVICEID_FC949E:
1702 case MPI_MANUFACTPAGE_DEVICEID_FC929X:
1703 if (revision < XL_929) {
1704 /* 929X Chip Fix. Set Split transactions level
1705 * for PCIX. Set MOST bits to zero.
1707 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1709 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1711 /* 929XL Chip Fix. Set MMRBC to 0x08.
1713 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1715 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1720 case MPI_MANUFACTPAGE_DEVICEID_FC919X:
1721 /* 919X Chip Fix. Set Split transactions level
1722 * for PCIX. Set MOST bits to zero.
1724 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1726 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1730 case MPI_MANUFACTPAGE_DEVID_53C1030:
1731 /* 1030 Chip Fix. Disable Split transactions
1732 * for PCIX. Set MOST bits to zero if Rev < C0( = 8).
1734 if (revision < C0_1030) {
1735 pci_read_config_byte(pdev, 0x6a, &pcixcmd);
1737 pci_write_config_byte(pdev, 0x6a, pcixcmd);
1740 case MPI_MANUFACTPAGE_DEVID_1030_53C1035:
1741 ioc->bus_type = SPI;
1744 case MPI_MANUFACTPAGE_DEVID_SAS1064:
1745 case MPI_MANUFACTPAGE_DEVID_SAS1068:
1746 ioc->errata_flag_1064 = 1;
1748 case MPI_MANUFACTPAGE_DEVID_SAS1064E:
1749 case MPI_MANUFACTPAGE_DEVID_SAS1068E:
1750 case MPI_MANUFACTPAGE_DEVID_SAS1078:
1751 ioc->bus_type = SAS;
1754 if (ioc->bus_type == SAS && mpt_msi_enable == -1)
1755 ioc->msi_enable = 1;
1757 ioc->msi_enable = mpt_msi_enable;
1759 if (ioc->errata_flag_1064)
1760 pci_disable_io_access(pdev);
1762 spin_lock_init(&ioc->FreeQlock);
1765 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1767 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1769 /* Set IOC ptr in the pcidev's driver data. */
1770 pci_set_drvdata(ioc->pcidev, ioc);
1772 /* Set lookup ptr. */
1773 list_add_tail(&ioc->list, &ioc_list);
1775 /* Check for "bound ports" (929, 929X, 1030, 1035) to reduce redundant resets.
1777 mpt_detect_bound_ports(ioc, pdev);
1779 if ((r = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1781 printk(MYIOC_s_ERR_FMT "didn't initialize properly! (%d)\n",
1784 list_del(&ioc->list);
1786 ioc->alt_ioc->alt_ioc = NULL;
1787 iounmap(ioc->memmap);
1789 pci_release_selected_regions(pdev, ioc->bars);
1791 destroy_workqueue(ioc->reset_work_q);
1792 ioc->reset_work_q = NULL;
1795 pci_set_drvdata(pdev, NULL);
1799 /* call per device driver probe entry point */
1800 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1801 if(MptDeviceDriverHandlers[cb_idx] &&
1802 MptDeviceDriverHandlers[cb_idx]->probe) {
1803 MptDeviceDriverHandlers[cb_idx]->probe(pdev,id);
1807 #ifdef CONFIG_PROC_FS
1809 * Create "/proc/mpt/iocN" subdirectory entry for each MPT adapter.
1811 dent = proc_mkdir(ioc->name, mpt_proc_root_dir);
1813 ent = create_proc_entry("info", S_IFREG|S_IRUGO, dent);
1815 ent->read_proc = procmpt_iocinfo_read;
1818 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, dent);
1820 ent->read_proc = procmpt_summary_read;
1827 queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
1828 msecs_to_jiffies(MPT_POLLING_INTERVAL));
1833 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1835 * mpt_detach - Remove a PCI intelligent MPT adapter.
1836 * @pdev: Pointer to pci_dev structure
1840 mpt_detach(struct pci_dev *pdev)
1842 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1845 unsigned long flags;
1846 struct workqueue_struct *wq;
1849 * Stop polling ioc for fault condition
1851 spin_lock_irqsave(&ioc->fault_reset_work_lock, flags);
1852 wq = ioc->reset_work_q;
1853 ioc->reset_work_q = NULL;
1854 spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags);
1855 cancel_delayed_work(&ioc->fault_reset_work);
1856 destroy_workqueue(wq);
1859 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
1860 remove_proc_entry(pname, NULL);
1861 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/info", ioc->name);
1862 remove_proc_entry(pname, NULL);
1863 sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s", ioc->name);
1864 remove_proc_entry(pname, NULL);
1866 /* call per device driver remove entry point */
1867 for(cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
1868 if(MptDeviceDriverHandlers[cb_idx] &&
1869 MptDeviceDriverHandlers[cb_idx]->remove) {
1870 MptDeviceDriverHandlers[cb_idx]->remove(pdev);
1874 /* Disable interrupts! */
1875 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1878 synchronize_irq(pdev->irq);
1880 /* Clear any lingering interrupt */
1881 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1883 CHIPREG_READ32(&ioc->chip->IntStatus);
1885 mpt_adapter_dispose(ioc);
1887 pci_set_drvdata(pdev, NULL);
1890 /**************************************************************************
1894 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1896 * mpt_suspend - Fusion MPT base driver suspend routine.
1897 * @pdev: Pointer to pci_dev structure
1898 * @state: new state to enter
1901 mpt_suspend(struct pci_dev *pdev, pm_message_t state)
1904 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1906 device_state = pci_choose_state(pdev, state);
1907 printk(MYIOC_s_INFO_FMT "pci-suspend: pdev=0x%p, slot=%s, Entering "
1908 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
1911 /* put ioc into READY_STATE */
1912 if(SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, CAN_SLEEP)) {
1913 printk(MYIOC_s_ERR_FMT
1914 "pci-suspend: IOC msg unit reset failed!\n", ioc->name);
1917 /* disable interrupts */
1918 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
1921 /* Clear any lingering interrupt */
1922 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
1924 free_irq(ioc->pci_irq, ioc);
1925 if (ioc->msi_enable)
1926 pci_disable_msi(ioc->pcidev);
1928 pci_save_state(pdev);
1929 pci_disable_device(pdev);
1930 pci_release_selected_regions(pdev, ioc->bars);
1931 pci_set_power_state(pdev, device_state);
1935 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
1937 * mpt_resume - Fusion MPT base driver resume routine.
1938 * @pdev: Pointer to pci_dev structure
1941 mpt_resume(struct pci_dev *pdev)
1943 MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
1944 u32 device_state = pdev->current_state;
1948 printk(MYIOC_s_INFO_FMT "pci-resume: pdev=0x%p, slot=%s, Previous "
1949 "operating state [D%d]\n", ioc->name, pdev, pci_name(pdev),
1952 pci_set_power_state(pdev, PCI_D0);
1953 pci_enable_wake(pdev, PCI_D0, 0);
1954 pci_restore_state(pdev);
1956 err = mpt_mapresources(ioc);
1960 printk(MYIOC_s_INFO_FMT "pci-resume: ioc-state=0x%x,doorbell=0x%x\n",
1961 ioc->name, (mpt_GetIocState(ioc, 1) >> MPI_IOC_STATE_SHIFT),
1962 CHIPREG_READ32(&ioc->chip->Doorbell));
1965 * Errata workaround for SAS pci express:
1966 * Upon returning to the D0 state, the contents of the doorbell will be
1967 * stale data, and this will incorrectly signal to the host driver that
1968 * the firmware is ready to process mpt commands. The workaround is
1969 * to issue a diagnostic reset.
1971 if (ioc->bus_type == SAS && (pdev->device ==
1972 MPI_MANUFACTPAGE_DEVID_SAS1068E || pdev->device ==
1973 MPI_MANUFACTPAGE_DEVID_SAS1064E)) {
1974 if (KickStart(ioc, 1, CAN_SLEEP) < 0) {
1975 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover\n",
1981 /* bring ioc to operational state */
1982 printk(MYIOC_s_INFO_FMT "Sending mpt_do_ioc_recovery\n", ioc->name);
1983 recovery_state = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_BRINGUP,
1985 if (recovery_state != 0)
1986 printk(MYIOC_s_WARN_FMT "pci-resume: Cannot recover, "
1987 "error:[%x]\n", ioc->name, recovery_state);
1989 printk(MYIOC_s_INFO_FMT
1990 "pci-resume: success\n", ioc->name);
1998 mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase)
2000 if ((MptDriverClass[index] == MPTSPI_DRIVER &&
2001 ioc->bus_type != SPI) ||
2002 (MptDriverClass[index] == MPTFC_DRIVER &&
2003 ioc->bus_type != FC) ||
2004 (MptDriverClass[index] == MPTSAS_DRIVER &&
2005 ioc->bus_type != SAS))
2006 /* make sure we only call the relevant reset handler
2009 return (MptResetHandlers[index])(ioc, reset_phase);
2012 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2014 * mpt_do_ioc_recovery - Initialize or recover MPT adapter.
2015 * @ioc: Pointer to MPT adapter structure
2016 * @reason: Event word / reason
2017 * @sleepFlag: Use schedule if CAN_SLEEP else use udelay.
2019 * This routine performs all the steps necessary to bring the IOC
2020 * to a OPERATIONAL state.
2022 * This routine also pre-fetches the LAN MAC address of a Fibre Channel
2027 * -1 if failed to get board READY
2028 * -2 if READY but IOCFacts Failed
2029 * -3 if READY but PrimeIOCFifos Failed
2030 * -4 if READY but IOCInit Failed
2031 * -5 if failed to enable_device and/or request_selected_regions
2032 * -6 if failed to upload firmware
2035 mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
2037 int hard_reset_done = 0;
2038 int alt_ioc_ready = 0;
2045 int reset_alt_ioc_active = 0;
2046 int irq_allocated = 0;
2049 printk(MYIOC_s_INFO_FMT "Initiating %s\n", ioc->name,
2050 reason == MPT_HOSTEVENT_IOC_BRINGUP ? "bringup" : "recovery");
2052 /* Disable reply interrupts (also blocks FreeQ) */
2053 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2057 if (ioc->alt_ioc->active)
2058 reset_alt_ioc_active = 1;
2060 /* Disable alt-IOC's reply interrupts (and FreeQ) for a bit ... */
2061 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, 0xFFFFFFFF);
2062 ioc->alt_ioc->active = 0;
2066 if (reason == MPT_HOSTEVENT_IOC_BRINGUP)
2069 if ((hard_reset_done = MakeIocReady(ioc, hard, sleepFlag)) < 0) {
2070 if (hard_reset_done == -4) {
2071 printk(MYIOC_s_WARN_FMT "Owned by PEER..skipping!\n",
2074 if (reset_alt_ioc_active && ioc->alt_ioc) {
2075 /* (re)Enable alt-IOC! (reply interrupt, FreeQ) */
2076 dprintk(ioc, printk(MYIOC_s_INFO_FMT
2077 "alt_ioc reply irq re-enabled\n", ioc->alt_ioc->name));
2078 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2079 ioc->alt_ioc->active = 1;
2083 printk(MYIOC_s_WARN_FMT "NOT READY!\n", ioc->name);
2088 /* hard_reset_done = 0 if a soft reset was performed
2089 * and 1 if a hard reset was performed.
2091 if (hard_reset_done && reset_alt_ioc_active && ioc->alt_ioc) {
2092 if ((rc = MakeIocReady(ioc->alt_ioc, 0, sleepFlag)) == 0)
2095 printk(MYIOC_s_WARN_FMT "alt_ioc not ready!\n", ioc->alt_ioc->name);
2098 for (ii=0; ii<5; ii++) {
2099 /* Get IOC facts! Allow 5 retries */
2100 if ((rc = GetIocFacts(ioc, sleepFlag, reason)) == 0)
2106 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2107 "Retry IocFacts failed rc=%x\n", ioc->name, rc));
2109 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2110 MptDisplayIocCapabilities(ioc);
2113 if (alt_ioc_ready) {
2114 if ((rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason)) != 0) {
2115 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2116 "Initial Alt IocFacts failed rc=%x\n", ioc->name, rc));
2117 /* Retry - alt IOC was initialized once
2119 rc = GetIocFacts(ioc->alt_ioc, sleepFlag, reason);
2122 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2123 "Retry Alt IocFacts failed rc=%x\n", ioc->name, rc));
2125 reset_alt_ioc_active = 0;
2126 } else if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2127 MptDisplayIocCapabilities(ioc->alt_ioc);
2131 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) &&
2132 (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) {
2133 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2134 ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM |
2136 if (pci_enable_device(ioc->pcidev))
2138 if (pci_request_selected_regions(ioc->pcidev, ioc->bars,
2144 * Device is reset now. It must have de-asserted the interrupt line
2145 * (if it was asserted) and it should be safe to register for the
2148 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2150 if (ioc->pcidev->irq) {
2151 if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
2152 printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
2155 ioc->msi_enable = 0;
2156 rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
2157 IRQF_SHARED, ioc->name, ioc);
2159 printk(MYIOC_s_ERR_FMT "Unable to allocate "
2160 "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
2161 if (ioc->msi_enable)
2162 pci_disable_msi(ioc->pcidev);
2166 ioc->pci_irq = ioc->pcidev->irq;
2167 pci_set_master(ioc->pcidev); /* ?? */
2168 dprintk(ioc, printk(MYIOC_s_INFO_FMT "installed at interrupt "
2169 "%d\n", ioc->name, ioc->pcidev->irq));
2173 /* Prime reply & request queues!
2174 * (mucho alloc's) Must be done prior to
2175 * init as upper addresses are needed for init.
2176 * If fails, continue with alt-ioc processing
2178 if ((ret == 0) && ((rc = PrimeIocFifos(ioc)) != 0))
2181 /* May need to check/upload firmware & data here!
2182 * If fails, continue with alt-ioc processing
2184 if ((ret == 0) && ((rc = SendIocInit(ioc, sleepFlag)) != 0))
2187 if (alt_ioc_ready && ((rc = PrimeIocFifos(ioc->alt_ioc)) != 0)) {
2188 printk(MYIOC_s_WARN_FMT ": alt_ioc (%d) FIFO mgmt alloc!\n",
2189 ioc->alt_ioc->name, rc);
2191 reset_alt_ioc_active = 0;
2194 if (alt_ioc_ready) {
2195 if ((rc = SendIocInit(ioc->alt_ioc, sleepFlag)) != 0) {
2197 reset_alt_ioc_active = 0;
2198 printk(MYIOC_s_WARN_FMT "alt_ioc (%d) init failure!\n",
2199 ioc->alt_ioc->name, rc);
2203 if (reason == MPT_HOSTEVENT_IOC_BRINGUP){
2204 if (ioc->upload_fw) {
2205 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2206 "firmware upload required!\n", ioc->name));
2208 /* Controller is not operational, cannot do upload
2211 rc = mpt_do_upload(ioc, sleepFlag);
2213 if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
2215 * Maintain only one pointer to FW memory
2216 * so there will not be two attempt to
2217 * downloadboot onboard dual function
2218 * chips (mpt_adapter_disable,
2221 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2222 "mpt_upload: alt_%s has cached_fw=%p \n",
2223 ioc->name, ioc->alt_ioc->name, ioc->alt_ioc->cached_fw));
2224 ioc->cached_fw = NULL;
2227 printk(MYIOC_s_WARN_FMT
2228 "firmware upload failure!\n", ioc->name);
2236 /* Enable! (reply interrupt) */
2237 CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM);
2241 if (reset_alt_ioc_active && ioc->alt_ioc) {
2242 /* (re)Enable alt-IOC! (reply interrupt) */
2243 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "alt_ioc reply irq re-enabled\n",
2244 ioc->alt_ioc->name));
2245 CHIPREG_WRITE32(&ioc->alt_ioc->chip->IntMask, MPI_HIM_DIM);
2246 ioc->alt_ioc->active = 1;
2249 /* Enable MPT base driver management of EventNotification
2250 * and EventAck handling.
2252 if ((ret == 0) && (!ioc->facts.EventState))
2253 (void) SendEventNotification(ioc, 1); /* 1=Enable EventNotification */
2255 if (ioc->alt_ioc && alt_ioc_ready && !ioc->alt_ioc->facts.EventState)
2256 (void) SendEventNotification(ioc->alt_ioc, 1); /* 1=Enable EventNotification */
2258 /* Add additional "reason" check before call to GetLanConfigPages
2259 * (combined with GetIoUnitPage2 call). This prevents a somewhat
2260 * recursive scenario; GetLanConfigPages times out, timer expired
2261 * routine calls HardResetHandler, which calls into here again,
2262 * and we try GetLanConfigPages again...
2264 if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
2267 * Initalize link list for inactive raid volumes.
2269 mutex_init(&ioc->raid_data.inactive_list_mutex);
2270 INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
2272 if (ioc->bus_type == SAS) {
2274 /* clear persistency table */
2275 if(ioc->facts.IOCExceptions &
2276 MPI_IOCFACTS_EXCEPT_PERSISTENT_TABLE_FULL) {
2277 ret = mptbase_sas_persist_operation(ioc,
2278 MPI_SAS_OP_CLEAR_NOT_PRESENT);
2285 mpt_findImVolumes(ioc);
2287 } else if (ioc->bus_type == FC) {
2288 if ((ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) &&
2289 (ioc->lan_cnfg_page0.Header.PageLength == 0)) {
2291 * Pre-fetch the ports LAN MAC address!
2292 * (LANPage1_t stuff)
2294 (void) GetLanConfigPages(ioc);
2295 a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
2296 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2297 "LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
2298 ioc->name, a[5], a[4], a[3], a[2], a[1], a[0]));
2302 /* Get NVRAM and adapter maximums from SPP 0 and 2
2304 mpt_GetScsiPortSettings(ioc, 0);
2306 /* Get version and length of SDP 1
2308 mpt_readScsiDevicePageHeaders(ioc, 0);
2312 if (ioc->facts.MsgVersion >= MPI_VERSION_01_02)
2313 mpt_findImVolumes(ioc);
2315 /* Check, and possibly reset, the coalescing value
2317 mpt_read_ioc_pg_1(ioc);
2319 mpt_read_ioc_pg_4(ioc);
2322 GetIoUnitPage2(ioc);
2323 mpt_get_manufacturing_pg_0(ioc);
2327 * Call each currently registered protocol IOC reset handler
2328 * with post-reset indication.
2329 * NOTE: If we're doing _IOC_BRINGUP, there can be no
2330 * MptResetHandlers[] registered yet.
2332 if (hard_reset_done) {
2334 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
2335 if ((ret == 0) && MptResetHandlers[cb_idx]) {
2336 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2337 "Calling IOC post_reset handler #%d\n",
2338 ioc->name, cb_idx));
2339 rc += mpt_signal_reset(cb_idx, ioc, MPT_IOC_POST_RESET);
2343 if (alt_ioc_ready && MptResetHandlers[cb_idx]) {
2344 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2345 "Calling IOC post_reset handler #%d\n",
2346 ioc->alt_ioc->name, cb_idx));
2347 rc += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_POST_RESET);
2351 /* FIXME? Examine results here? */
2355 if ((ret != 0) && irq_allocated) {
2356 free_irq(ioc->pci_irq, ioc);
2357 if (ioc->msi_enable)
2358 pci_disable_msi(ioc->pcidev);
2363 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2365 * mpt_detect_bound_ports - Search for matching PCI bus/dev_function
2366 * @ioc: Pointer to MPT adapter structure
2367 * @pdev: Pointer to (struct pci_dev) structure
2369 * Search for PCI bus/dev_function which matches
2370 * PCI bus/dev_function (+/-1) for newly discovered 929,
2371 * 929X, 1030 or 1035.
2373 * If match on PCI dev_function +/-1 is found, bind the two MPT adapters
2374 * using alt_ioc pointer fields in their %MPT_ADAPTER structures.
2377 mpt_detect_bound_ports(MPT_ADAPTER *ioc, struct pci_dev *pdev)
2379 struct pci_dev *peer=NULL;
2380 unsigned int slot = PCI_SLOT(pdev->devfn);
2381 unsigned int func = PCI_FUNC(pdev->devfn);
2382 MPT_ADAPTER *ioc_srch;
2384 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "PCI device %s devfn=%x/%x,"
2385 " searching for devfn match on %x or %x\n",
2386 ioc->name, pci_name(pdev), pdev->bus->number,
2387 pdev->devfn, func-1, func+1));
2389 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func-1));
2391 peer = pci_get_slot(pdev->bus, PCI_DEVFN(slot,func+1));
2396 list_for_each_entry(ioc_srch, &ioc_list, list) {
2397 struct pci_dev *_pcidev = ioc_srch->pcidev;
2398 if (_pcidev == peer) {
2399 /* Paranoia checks */
2400 if (ioc->alt_ioc != NULL) {
2401 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2402 ioc->name, ioc->alt_ioc->name);
2404 } else if (ioc_srch->alt_ioc != NULL) {
2405 printk(MYIOC_s_WARN_FMT "Oops, already bound to %s!\n",
2406 ioc_srch->name, ioc_srch->alt_ioc->name);
2409 dprintk(ioc, printk(MYIOC_s_INFO_FMT "FOUND! binding to %s\n",
2410 ioc->name, ioc_srch->name));
2411 ioc_srch->alt_ioc = ioc;
2412 ioc->alt_ioc = ioc_srch;
2418 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2420 * mpt_adapter_disable - Disable misbehaving MPT adapter.
2421 * @ioc: Pointer to MPT adapter structure
2424 mpt_adapter_disable(MPT_ADAPTER *ioc)
2429 if (ioc->cached_fw != NULL) {
2430 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "%s: Pushing FW onto "
2431 "adapter\n", __FUNCTION__, ioc->name));
2432 if ((ret = mpt_downloadboot(ioc, (MpiFwHeader_t *)
2433 ioc->cached_fw, CAN_SLEEP)) < 0) {
2434 printk(MYIOC_s_WARN_FMT
2435 ": firmware downloadboot failure (%d)!\n",
2440 /* Disable adapter interrupts! */
2441 CHIPREG_WRITE32(&ioc->chip->IntMask, 0xFFFFFFFF);
2443 /* Clear any lingering interrupt */
2444 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
2446 if (ioc->alloc != NULL) {
2448 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "free @ %p, sz=%d bytes\n",
2449 ioc->name, ioc->alloc, ioc->alloc_sz));
2450 pci_free_consistent(ioc->pcidev, sz,
2451 ioc->alloc, ioc->alloc_dma);
2452 ioc->reply_frames = NULL;
2453 ioc->req_frames = NULL;
2455 ioc->alloc_total -= sz;
2458 if (ioc->sense_buf_pool != NULL) {
2459 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
2460 pci_free_consistent(ioc->pcidev, sz,
2461 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
2462 ioc->sense_buf_pool = NULL;
2463 ioc->alloc_total -= sz;
2466 if (ioc->events != NULL){
2467 sz = MPTCTL_EVENT_LOG_SIZE * sizeof(MPT_IOCTL_EVENTS);
2470 ioc->alloc_total -= sz;
2473 mpt_free_fw_memory(ioc);
2475 kfree(ioc->spi_data.nvram);
2476 mpt_inactive_raid_list_free(ioc);
2477 kfree(ioc->raid_data.pIocPg2);
2478 kfree(ioc->raid_data.pIocPg3);
2479 ioc->spi_data.nvram = NULL;
2480 ioc->raid_data.pIocPg3 = NULL;
2482 if (ioc->spi_data.pIocPg4 != NULL) {
2483 sz = ioc->spi_data.IocPg4Sz;
2484 pci_free_consistent(ioc->pcidev, sz,
2485 ioc->spi_data.pIocPg4,
2486 ioc->spi_data.IocPg4_dma);
2487 ioc->spi_data.pIocPg4 = NULL;
2488 ioc->alloc_total -= sz;
2491 if (ioc->ReqToChain != NULL) {
2492 kfree(ioc->ReqToChain);
2493 kfree(ioc->RequestNB);
2494 ioc->ReqToChain = NULL;
2497 kfree(ioc->ChainToChain);
2498 ioc->ChainToChain = NULL;
2500 if (ioc->HostPageBuffer != NULL) {
2501 if((ret = mpt_host_page_access_control(ioc,
2502 MPI_DB_HPBAC_FREE_BUFFER, NO_SLEEP)) != 0) {
2503 printk(MYIOC_s_ERR_FMT
2504 "host page buffers free failed (%d)!\n",
2507 dexitprintk(ioc, printk(MYIOC_s_INFO_FMT "HostPageBuffer free @ %p, sz=%d bytes\n",
2508 ioc->name, ioc->HostPageBuffer, ioc->HostPageBuffer_sz));
2509 pci_free_consistent(ioc->pcidev, ioc->HostPageBuffer_sz,
2510 ioc->HostPageBuffer, ioc->HostPageBuffer_dma);
2511 ioc->HostPageBuffer = NULL;
2512 ioc->HostPageBuffer_sz = 0;
2513 ioc->alloc_total -= ioc->HostPageBuffer_sz;
2517 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2519 * mpt_adapter_dispose - Free all resources associated with an MPT adapter
2520 * @ioc: Pointer to MPT adapter structure
2522 * This routine unregisters h/w resources and frees all alloc'd memory
2523 * associated with a MPT adapter structure.
2526 mpt_adapter_dispose(MPT_ADAPTER *ioc)
2528 int sz_first, sz_last;
2533 sz_first = ioc->alloc_total;
2535 mpt_adapter_disable(ioc);
2537 if (ioc->pci_irq != -1) {
2538 free_irq(ioc->pci_irq, ioc);
2539 if (ioc->msi_enable)
2540 pci_disable_msi(ioc->pcidev);
2544 if (ioc->memmap != NULL) {
2545 iounmap(ioc->memmap);
2549 pci_disable_device(ioc->pcidev);
2550 pci_release_selected_regions(ioc->pcidev, ioc->bars);
2552 #if defined(CONFIG_MTRR) && 0
2553 if (ioc->mtrr_reg > 0) {
2554 mtrr_del(ioc->mtrr_reg, 0, 0);
2555 dprintk(ioc, printk(MYIOC_s_INFO_FMT "MTRR region de-registered\n", ioc->name));
2559 /* Zap the adapter lookup ptr! */
2560 list_del(&ioc->list);
2562 sz_last = ioc->alloc_total;
2563 dprintk(ioc, printk(MYIOC_s_INFO_FMT "free'd %d of %d bytes\n",
2564 ioc->name, sz_first-sz_last+(int)sizeof(*ioc), sz_first));
2567 ioc->alt_ioc->alt_ioc = NULL;
2572 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2574 * MptDisplayIocCapabilities - Disply IOC's capabilities.
2575 * @ioc: Pointer to MPT adapter structure
2578 MptDisplayIocCapabilities(MPT_ADAPTER *ioc)
2582 printk(KERN_INFO "%s: ", ioc->name);
2584 printk("%s: ", ioc->prod_name);
2585 printk("Capabilities={");
2587 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) {
2588 printk("Initiator");
2592 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2593 printk("%sTarget", i ? "," : "");
2597 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
2598 printk("%sLAN", i ? "," : "");
2604 * This would probably evoke more questions than it's worth
2606 if (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) {
2607 printk("%sLogBusAddr", i ? "," : "");
2615 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2617 * MakeIocReady - Get IOC to a READY state, using KickStart if needed.
2618 * @ioc: Pointer to MPT_ADAPTER structure
2619 * @force: Force hard KickStart of IOC
2620 * @sleepFlag: Specifies whether the process can sleep
2623 * 1 - DIAG reset and READY
2624 * 0 - READY initially OR soft reset and READY
2625 * -1 - Any failure on KickStart
2626 * -2 - Msg Unit Reset Failed
2627 * -3 - IO Unit Reset Failed
2628 * -4 - IOC owned by a PEER
2631 MakeIocReady(MPT_ADAPTER *ioc, int force, int sleepFlag)
2636 int hard_reset_done = 0;
2641 /* Get current [raw] IOC state */
2642 ioc_state = mpt_GetIocState(ioc, 0);
2643 dhsprintk(ioc, printk(MYIOC_s_INFO_FMT "MakeIocReady [raw] state=%08x\n", ioc->name, ioc_state));
2646 * Check to see if IOC got left/stuck in doorbell handshake
2647 * grip of death. If so, hard reset the IOC.
2649 if (ioc_state & MPI_DOORBELL_ACTIVE) {
2651 printk(MYIOC_s_WARN_FMT "Unexpected doorbell active!\n",
2655 /* Is it already READY? */
2656 if (!statefault && (ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_READY)
2660 * Check to see if IOC is in FAULT state.
2662 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
2664 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state!!!\n",
2666 printk(MYIOC_s_WARN_FMT " FAULT code = %04xh\n",
2667 ioc->name, ioc_state & MPI_DOORBELL_DATA_MASK);
2671 * Hmmm... Did it get left operational?
2673 if ((ioc_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL) {
2674 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOC operational unexpected\n",
2678 * If PCI Peer, exit.
2679 * Else, if no fault conditions are present, issue a MessageUnitReset
2680 * Else, fall through to KickStart case
2682 whoinit = (ioc_state & MPI_DOORBELL_WHO_INIT_MASK) >> MPI_DOORBELL_WHO_INIT_SHIFT;
2683 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT
2684 "whoinit 0x%x statefault %d force %d\n",
2685 ioc->name, whoinit, statefault, force));
2686 if (whoinit == MPI_WHOINIT_PCI_PEER)
2689 if ((statefault == 0 ) && (force == 0)) {
2690 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) == 0)
2697 hard_reset_done = KickStart(ioc, statefault||force, sleepFlag);
2698 if (hard_reset_done < 0)
2702 * Loop here waiting for IOC to come READY.
2705 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 5; /* 5 seconds */
2707 while ((ioc_state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
2708 if (ioc_state == MPI_IOC_STATE_OPERATIONAL) {
2710 * BIOS or previous driver load left IOC in OP state.
2711 * Reset messaging FIFOs.
2713 if ((r = SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag)) != 0) {
2714 printk(MYIOC_s_ERR_FMT "IOC msg unit reset failed!\n", ioc->name);
2717 } else if (ioc_state == MPI_IOC_STATE_RESET) {
2719 * Something is wrong. Try to get IOC back
2722 if ((r = SendIocReset(ioc, MPI_FUNCTION_IO_UNIT_RESET, sleepFlag)) != 0) {
2723 printk(MYIOC_s_ERR_FMT "IO unit reset failed!\n", ioc->name);
2730 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
2731 ioc->name, (int)((ii+5)/HZ));
2735 if (sleepFlag == CAN_SLEEP) {
2738 mdelay (1); /* 1 msec delay */
2743 if (statefault < 3) {
2744 printk(MYIOC_s_INFO_FMT "Recovered from %s\n",
2746 statefault==1 ? "stuck handshake" : "IOC FAULT");
2749 return hard_reset_done;
2752 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2754 * mpt_GetIocState - Get the current state of a MPT adapter.
2755 * @ioc: Pointer to MPT_ADAPTER structure
2756 * @cooked: Request raw or cooked IOC state
2758 * Returns all IOC Doorbell register bits if cooked==0, else just the
2759 * Doorbell bits in MPI_IOC_STATE_MASK.
2762 mpt_GetIocState(MPT_ADAPTER *ioc, int cooked)
2767 s = CHIPREG_READ32(&ioc->chip->Doorbell);
2768 sc = s & MPI_IOC_STATE_MASK;
2771 ioc->last_state = sc;
2773 return cooked ? sc : s;
2776 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2778 * GetIocFacts - Send IOCFacts request to MPT adapter.
2779 * @ioc: Pointer to MPT_ADAPTER structure
2780 * @sleepFlag: Specifies whether the process can sleep
2781 * @reason: If recovery, only update facts.
2783 * Returns 0 for success, non-zero for failure.
2786 GetIocFacts(MPT_ADAPTER *ioc, int sleepFlag, int reason)
2788 IOCFacts_t get_facts;
2789 IOCFactsReply_t *facts;
2797 /* IOC *must* NOT be in RESET state! */
2798 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2799 printk(MYIOC_s_ERR_FMT "Can't get IOCFacts NOT READY! (%08x)\n",
2800 ioc->name, ioc->last_state );
2804 facts = &ioc->facts;
2806 /* Destination (reply area)... */
2807 reply_sz = sizeof(*facts);
2808 memset(facts, 0, reply_sz);
2810 /* Request area (get_facts on the stack right now!) */
2811 req_sz = sizeof(get_facts);
2812 memset(&get_facts, 0, req_sz);
2814 get_facts.Function = MPI_FUNCTION_IOC_FACTS;
2815 /* Assert: All other get_facts fields are zero! */
2817 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2818 "Sending get IocFacts request req_sz=%d reply_sz=%d\n",
2819 ioc->name, req_sz, reply_sz));
2821 /* No non-zero fields in the get_facts request are greater than
2822 * 1 byte in size, so we can just fire it off as is.
2824 r = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_facts,
2825 reply_sz, (u16*)facts, 5 /*seconds*/, sleepFlag);
2830 * Now byte swap (GRRR) the necessary fields before any further
2831 * inspection of reply contents.
2833 * But need to do some sanity checks on MsgLength (byte) field
2834 * to make sure we don't zero IOC's req_sz!
2836 /* Did we get a valid reply? */
2837 if (facts->MsgLength > offsetof(IOCFactsReply_t, RequestFrameSize)/sizeof(u32)) {
2838 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2840 * If not been here, done that, save off first WhoInit value
2842 if (ioc->FirstWhoInit == WHOINIT_UNKNOWN)
2843 ioc->FirstWhoInit = facts->WhoInit;
2846 facts->MsgVersion = le16_to_cpu(facts->MsgVersion);
2847 facts->MsgContext = le32_to_cpu(facts->MsgContext);
2848 facts->IOCExceptions = le16_to_cpu(facts->IOCExceptions);
2849 facts->IOCStatus = le16_to_cpu(facts->IOCStatus);
2850 facts->IOCLogInfo = le32_to_cpu(facts->IOCLogInfo);
2851 status = le16_to_cpu(facts->IOCStatus) & MPI_IOCSTATUS_MASK;
2852 /* CHECKME! IOCStatus, IOCLogInfo */
2854 facts->ReplyQueueDepth = le16_to_cpu(facts->ReplyQueueDepth);
2855 facts->RequestFrameSize = le16_to_cpu(facts->RequestFrameSize);
2858 * FC f/w version changed between 1.1 and 1.2
2859 * Old: u16{Major(4),Minor(4),SubMinor(8)}
2860 * New: u32{Major(8),Minor(8),Unit(8),Dev(8)}
2862 if (facts->MsgVersion < 0x0102) {
2864 * Handle old FC f/w style, convert to new...
2866 u16 oldv = le16_to_cpu(facts->Reserved_0101_FWVersion);
2867 facts->FWVersion.Word =
2868 ((oldv<<12) & 0xFF000000) |
2869 ((oldv<<8) & 0x000FFF00);
2871 facts->FWVersion.Word = le32_to_cpu(facts->FWVersion.Word);
2873 facts->ProductID = le16_to_cpu(facts->ProductID);
2874 if ((ioc->facts.ProductID & MPI_FW_HEADER_PID_PROD_MASK)
2875 > MPI_FW_HEADER_PID_PROD_TARGET_SCSI)
2876 ioc->ir_firmware = 1;
2877 facts->CurrentHostMfaHighAddr =
2878 le32_to_cpu(facts->CurrentHostMfaHighAddr);
2879 facts->GlobalCredits = le16_to_cpu(facts->GlobalCredits);
2880 facts->CurrentSenseBufferHighAddr =
2881 le32_to_cpu(facts->CurrentSenseBufferHighAddr);
2882 facts->CurReplyFrameSize =
2883 le16_to_cpu(facts->CurReplyFrameSize);
2884 facts->IOCCapabilities = le32_to_cpu(facts->IOCCapabilities);
2887 * Handle NEW (!) IOCFactsReply fields in MPI-1.01.xx
2888 * Older MPI-1.00.xx struct had 13 dwords, and enlarged
2889 * to 14 in MPI-1.01.0x.
2891 if (facts->MsgLength >= (offsetof(IOCFactsReply_t,FWImageSize) + 7)/4 &&
2892 facts->MsgVersion > 0x0100) {
2893 facts->FWImageSize = le32_to_cpu(facts->FWImageSize);
2896 sz = facts->FWImageSize;
2901 facts->FWImageSize = sz;
2903 if (!facts->RequestFrameSize) {
2904 /* Something is wrong! */
2905 printk(MYIOC_s_ERR_FMT "IOC reported invalid 0 request size!\n",
2910 r = sz = facts->BlockSize;
2911 vv = ((63 / (sz * 4)) + 1) & 0x03;
2912 ioc->NB_for_64_byte_frame = vv;
2918 ioc->NBShiftFactor = shiftFactor;
2919 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT
2920 "NB_for_64_byte_frame=%x NBShiftFactor=%x BlockSize=%x\n",
2921 ioc->name, vv, shiftFactor, r));
2923 if (reason == MPT_HOSTEVENT_IOC_BRINGUP) {
2925 * Set values for this IOC's request & reply frame sizes,
2926 * and request & reply queue depths...
2928 ioc->req_sz = min(MPT_DEFAULT_FRAME_SIZE, facts->RequestFrameSize * 4);
2929 ioc->req_depth = min_t(int, MPT_MAX_REQ_DEPTH, facts->GlobalCredits);
2930 ioc->reply_sz = MPT_REPLY_FRAME_SIZE;
2931 ioc->reply_depth = min_t(int, MPT_DEFAULT_REPLY_DEPTH, facts->ReplyQueueDepth);
2933 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "reply_sz=%3d, reply_depth=%4d\n",
2934 ioc->name, ioc->reply_sz, ioc->reply_depth));
2935 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "req_sz =%3d, req_depth =%4d\n",
2936 ioc->name, ioc->req_sz, ioc->req_depth));
2938 /* Get port facts! */
2939 if ( (r = GetPortFacts(ioc, 0, sleepFlag)) != 0 )
2943 printk(MYIOC_s_ERR_FMT
2944 "Invalid IOC facts reply, msgLength=%d offsetof=%zd!\n",
2945 ioc->name, facts->MsgLength, (offsetof(IOCFactsReply_t,
2946 RequestFrameSize)/sizeof(u32)));
2953 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
2955 * GetPortFacts - Send PortFacts request to MPT adapter.
2956 * @ioc: Pointer to MPT_ADAPTER structure
2957 * @portnum: Port number
2958 * @sleepFlag: Specifies whether the process can sleep
2960 * Returns 0 for success, non-zero for failure.
2963 GetPortFacts(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
2965 PortFacts_t get_pfacts;
2966 PortFactsReply_t *pfacts;
2972 /* IOC *must* NOT be in RESET state! */
2973 if (ioc->last_state == MPI_IOC_STATE_RESET) {
2974 printk(MYIOC_s_ERR_FMT "Can't get PortFacts NOT READY! (%08x)\n",
2975 ioc->name, ioc->last_state );
2979 pfacts = &ioc->pfacts[portnum];
2981 /* Destination (reply area)... */
2982 reply_sz = sizeof(*pfacts);
2983 memset(pfacts, 0, reply_sz);
2985 /* Request area (get_pfacts on the stack right now!) */
2986 req_sz = sizeof(get_pfacts);
2987 memset(&get_pfacts, 0, req_sz);
2989 get_pfacts.Function = MPI_FUNCTION_PORT_FACTS;
2990 get_pfacts.PortNumber = portnum;
2991 /* Assert: All other get_pfacts fields are zero! */
2993 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending get PortFacts(%d) request\n",
2994 ioc->name, portnum));
2996 /* No non-zero fields in the get_pfacts request are greater than
2997 * 1 byte in size, so we can just fire it off as is.
2999 ii = mpt_handshake_req_reply_wait(ioc, req_sz, (u32*)&get_pfacts,
3000 reply_sz, (u16*)pfacts, 5 /*seconds*/, sleepFlag);
3004 /* Did we get a valid reply? */
3006 /* Now byte swap the necessary fields in the response. */
3007 pfacts->MsgContext = le32_to_cpu(pfacts->MsgContext);
3008 pfacts->IOCStatus = le16_to_cpu(pfacts->IOCStatus);
3009 pfacts->IOCLogInfo = le32_to_cpu(pfacts->IOCLogInfo);
3010 pfacts->MaxDevices = le16_to_cpu(pfacts->MaxDevices);
3011 pfacts->PortSCSIID = le16_to_cpu(pfacts->PortSCSIID);
3012 pfacts->ProtocolFlags = le16_to_cpu(pfacts->ProtocolFlags);
3013 pfacts->MaxPostedCmdBuffers = le16_to_cpu(pfacts->MaxPostedCmdBuffers);
3014 pfacts->MaxPersistentIDs = le16_to_cpu(pfacts->MaxPersistentIDs);
3015 pfacts->MaxLanBuckets = le16_to_cpu(pfacts->MaxLanBuckets);
3017 max_id = (ioc->bus_type == SAS) ? pfacts->PortSCSIID :
3019 ioc->devices_per_bus = (max_id > 255) ? 256 : max_id;
3020 ioc->number_of_buses = (ioc->devices_per_bus < 256) ? 1 : max_id/256;
3023 * Place all the devices on channels
3027 if (mpt_channel_mapping) {
3028 ioc->devices_per_bus = 1;
3029 ioc->number_of_buses = (max_id > 255) ? 255 : max_id;
3035 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3037 * SendIocInit - Send IOCInit request to MPT adapter.
3038 * @ioc: Pointer to MPT_ADAPTER structure
3039 * @sleepFlag: Specifies whether the process can sleep
3041 * Send IOCInit followed by PortEnable to bring IOC to OPERATIONAL state.
3043 * Returns 0 for success, non-zero for failure.
3046 SendIocInit(MPT_ADAPTER *ioc, int sleepFlag)
3049 MPIDefaultReply_t init_reply;
3055 memset(&ioc_init, 0, sizeof(ioc_init));
3056 memset(&init_reply, 0, sizeof(init_reply));
3058 ioc_init.WhoInit = MPI_WHOINIT_HOST_DRIVER;
3059 ioc_init.Function = MPI_FUNCTION_IOC_INIT;
3061 /* If we are in a recovery mode and we uploaded the FW image,
3062 * then this pointer is not NULL. Skip the upload a second time.
3063 * Set this flag if cached_fw set for either IOC.
3065 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
3069 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "upload_fw %d facts.Flags=%x\n",
3070 ioc->name, ioc->upload_fw, ioc->facts.Flags));
3072 ioc_init.MaxDevices = (U8)ioc->devices_per_bus;
3073 ioc_init.MaxBuses = (U8)ioc->number_of_buses;
3074 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "facts.MsgVersion=%x\n",
3075 ioc->name, ioc->facts.MsgVersion));
3076 if (ioc->facts.MsgVersion >= MPI_VERSION_01_05) {
3077 // set MsgVersion and HeaderVersion host driver was built with
3078 ioc_init.MsgVersion = cpu_to_le16(MPI_VERSION);
3079 ioc_init.HeaderVersion = cpu_to_le16(MPI_HEADER_VERSION);
3081 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_HOST_PAGE_BUFFER_PERSISTENT) {
3082 ioc_init.HostPageBufferSGE = ioc->facts.HostPageBufferSGE;
3083 } else if(mpt_host_page_alloc(ioc, &ioc_init))
3086 ioc_init.ReplyFrameSize = cpu_to_le16(ioc->reply_sz); /* in BYTES */
3088 if (sizeof(dma_addr_t) == sizeof(u64)) {
3089 /* Save the upper 32-bits of the request
3090 * (reply) and sense buffers.
3092 ioc_init.HostMfaHighAddr = cpu_to_le32((u32)((u64)ioc->alloc_dma >> 32));
3093 ioc_init.SenseBufferHighAddr = cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
3095 /* Force 32-bit addressing */
3096 ioc_init.HostMfaHighAddr = cpu_to_le32(0);
3097 ioc_init.SenseBufferHighAddr = cpu_to_le32(0);
3100 ioc->facts.CurrentHostMfaHighAddr = ioc_init.HostMfaHighAddr;
3101 ioc->facts.CurrentSenseBufferHighAddr = ioc_init.SenseBufferHighAddr;
3102 ioc->facts.MaxDevices = ioc_init.MaxDevices;
3103 ioc->facts.MaxBuses = ioc_init.MaxBuses;
3105 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOCInit (req @ %p)\n",
3106 ioc->name, &ioc_init));
3108 r = mpt_handshake_req_reply_wait(ioc, sizeof(IOCInit_t), (u32*)&ioc_init,
3109 sizeof(MPIDefaultReply_t), (u16*)&init_reply, 10 /*seconds*/, sleepFlag);
3111 printk(MYIOC_s_ERR_FMT "Sending IOCInit failed(%d)!\n",ioc->name, r);
3115 /* No need to byte swap the multibyte fields in the reply
3116 * since we don't even look at its contents.
3119 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending PortEnable (req @ %p)\n",
3120 ioc->name, &ioc_init));
3122 if ((r = SendPortEnable(ioc, 0, sleepFlag)) != 0) {
3123 printk(MYIOC_s_ERR_FMT "Sending PortEnable failed(%d)!\n",ioc->name, r);
3127 /* YIKES! SUPER IMPORTANT!!!
3128 * Poll IocState until _OPERATIONAL while IOC is doing
3129 * LoopInit and TargetDiscovery!
3132 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 60; /* 60 seconds */
3133 state = mpt_GetIocState(ioc, 1);
3134 while (state != MPI_IOC_STATE_OPERATIONAL && --cntdn) {
3135 if (sleepFlag == CAN_SLEEP) {
3142 printk(MYIOC_s_ERR_FMT "Wait IOC_OP state timeout(%d)!\n",
3143 ioc->name, (int)((count+5)/HZ));
3147 state = mpt_GetIocState(ioc, 1);
3150 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wait IOC_OPERATIONAL state (cnt=%d)\n",
3153 ioc->aen_event_read_flag=0;
3157 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3159 * SendPortEnable - Send PortEnable request to MPT adapter port.
3160 * @ioc: Pointer to MPT_ADAPTER structure
3161 * @portnum: Port number to enable
3162 * @sleepFlag: Specifies whether the process can sleep
3164 * Send PortEnable to bring IOC to OPERATIONAL state.
3166 * Returns 0 for success, non-zero for failure.
3169 SendPortEnable(MPT_ADAPTER *ioc, int portnum, int sleepFlag)
3171 PortEnable_t port_enable;
3172 MPIDefaultReply_t reply_buf;
3177 /* Destination... */
3178 reply_sz = sizeof(MPIDefaultReply_t);
3179 memset(&reply_buf, 0, reply_sz);
3181 req_sz = sizeof(PortEnable_t);
3182 memset(&port_enable, 0, req_sz);
3184 port_enable.Function = MPI_FUNCTION_PORT_ENABLE;
3185 port_enable.PortNumber = portnum;
3186 /* port_enable.ChainOffset = 0; */
3187 /* port_enable.MsgFlags = 0; */
3188 /* port_enable.MsgContext = 0; */
3190 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Port(%d)Enable (req @ %p)\n",
3191 ioc->name, portnum, &port_enable));
3193 /* RAID FW may take a long time to enable
3195 if (ioc->ir_firmware || ioc->bus_type == SAS) {
3196 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3197 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3198 300 /*seconds*/, sleepFlag);
3200 rc = mpt_handshake_req_reply_wait(ioc, req_sz,
3201 (u32*)&port_enable, reply_sz, (u16*)&reply_buf,
3202 30 /*seconds*/, sleepFlag);
3208 * mpt_alloc_fw_memory - allocate firmware memory
3209 * @ioc: Pointer to MPT_ADAPTER structure
3210 * @size: total FW bytes
3212 * If memory has already been allocated, the same (cached) value
3215 * Return 0 if successfull, or non-zero for failure
3218 mpt_alloc_fw_memory(MPT_ADAPTER *ioc, int size)
3222 if (ioc->cached_fw) {
3223 rc = 0; /* use already allocated memory */
3226 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw) {
3227 ioc->cached_fw = ioc->alt_ioc->cached_fw; /* use alt_ioc's memory */
3228 ioc->cached_fw_dma = ioc->alt_ioc->cached_fw_dma;
3232 ioc->cached_fw = pci_alloc_consistent(ioc->pcidev, size, &ioc->cached_fw_dma);
3233 if (!ioc->cached_fw) {
3234 printk(MYIOC_s_ERR_FMT "Unable to allocate memory for the cached firmware image!\n",
3238 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "FW Image @ %p[%p], sz=%d[%x] bytes\n",
3239 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, size, size));
3240 ioc->alloc_total += size;
3248 * mpt_free_fw_memory - free firmware memory
3249 * @ioc: Pointer to MPT_ADAPTER structure
3251 * If alt_img is NULL, delete from ioc structure.
3252 * Else, delete a secondary image in same format.
3255 mpt_free_fw_memory(MPT_ADAPTER *ioc)
3259 if (!ioc->cached_fw)
3262 sz = ioc->facts.FWImageSize;
3263 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "free_fw_memory: FW Image @ %p[%p], sz=%d[%x] bytes\n",
3264 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3265 pci_free_consistent(ioc->pcidev, sz, ioc->cached_fw, ioc->cached_fw_dma);
3266 ioc->alloc_total -= sz;
3267 ioc->cached_fw = NULL;
3270 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3272 * mpt_do_upload - Construct and Send FWUpload request to MPT adapter port.
3273 * @ioc: Pointer to MPT_ADAPTER structure
3274 * @sleepFlag: Specifies whether the process can sleep
3276 * Returns 0 for success, >0 for handshake failure
3277 * <0 for fw upload failure.
3279 * Remark: If bound IOC and a successful FWUpload was performed
3280 * on the bound IOC, the second image is discarded
3281 * and memory is free'd. Both channels must upload to prevent
3282 * IOC from running in degraded mode.
3285 mpt_do_upload(MPT_ADAPTER *ioc, int sleepFlag)
3287 u8 reply[sizeof(FWUploadReply_t)];
3288 FWUpload_t *prequest;
3289 FWUploadReply_t *preply;
3290 FWUploadTCSGE_t *ptcsge;
3293 int ii, sz, reply_sz;
3296 /* If the image size is 0, we are done.
3298 if ((sz = ioc->facts.FWImageSize) == 0)
3301 if (mpt_alloc_fw_memory(ioc, ioc->facts.FWImageSize) != 0)
3304 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Image @ %p[%p], sz=%d[%x] bytes\n",
3305 ioc->name, ioc->cached_fw, (void *)(ulong)ioc->cached_fw_dma, sz, sz));
3307 prequest = (sleepFlag == NO_SLEEP) ? kzalloc(ioc->req_sz, GFP_ATOMIC) :
3308 kzalloc(ioc->req_sz, GFP_KERNEL);
3310 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "fw upload failed "
3311 "while allocating memory \n", ioc->name));
3312 mpt_free_fw_memory(ioc);
3316 preply = (FWUploadReply_t *)&reply;
3318 reply_sz = sizeof(reply);
3319 memset(preply, 0, reply_sz);
3321 prequest->ImageType = MPI_FW_UPLOAD_ITYPE_FW_IOC_MEM;
3322 prequest->Function = MPI_FUNCTION_FW_UPLOAD;
3324 ptcsge = (FWUploadTCSGE_t *) &prequest->SGL;
3325 ptcsge->DetailsLength = 12;
3326 ptcsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
3327 ptcsge->ImageSize = cpu_to_le32(sz);
3330 sgeoffset = sizeof(FWUpload_t) - sizeof(SGE_MPI_UNION) + sizeof(FWUploadTCSGE_t);
3332 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ | sz;
3333 mpt_add_sge((char *)ptcsge, flagsLength, ioc->cached_fw_dma);
3335 sgeoffset += sizeof(u32) + sizeof(dma_addr_t);
3336 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": Sending FW Upload (req @ %p) sgeoffset=%d \n",
3337 ioc->name, prequest, sgeoffset));
3338 DBG_DUMP_FW_REQUEST_FRAME(ioc, (u32 *)prequest);
3340 ii = mpt_handshake_req_reply_wait(ioc, sgeoffset, (u32*)prequest,
3341 reply_sz, (u16*)preply, 65 /*seconds*/, sleepFlag);
3343 dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": FW Upload completed rc=%x \n", ioc->name, ii));
3345 cmdStatus = -EFAULT;
3347 /* Handshake transfer was complete and successful.
3348 * Check the Reply Frame.
3350 int status, transfer_sz;
3351 status = le16_to_cpu(preply->IOCStatus);
3352 if (status == MPI_IOCSTATUS_SUCCESS) {
3353 transfer_sz = le32_to_cpu(preply->ActualImageSize);
3354 if (transfer_sz == sz)
3358 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": do_upload cmdStatus=%d \n",
3359 ioc->name, cmdStatus));
3364 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": fw upload failed, freeing image \n",
3366 mpt_free_fw_memory(ioc);
3373 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3375 * mpt_downloadboot - DownloadBoot code
3376 * @ioc: Pointer to MPT_ADAPTER structure
3377 * @pFwHeader: Pointer to firmware header info
3378 * @sleepFlag: Specifies whether the process can sleep
3380 * FwDownloadBoot requires Programmed IO access.
3382 * Returns 0 for success
3383 * -1 FW Image size is 0
3384 * -2 No valid cached_fw Pointer
3385 * <0 for fw upload failure.
3388 mpt_downloadboot(MPT_ADAPTER *ioc, MpiFwHeader_t *pFwHeader, int sleepFlag)
3390 MpiExtImageHeader_t *pExtImage;
3400 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot: fw size 0x%x (%d), FW Ptr %p\n",
3401 ioc->name, pFwHeader->ImageSize, pFwHeader->ImageSize, pFwHeader));
3403 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3404 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3405 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3406 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3407 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3408 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3410 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM));
3413 if (sleepFlag == CAN_SLEEP) {
3419 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3420 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3422 for (count = 0; count < 30; count ++) {
3423 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3424 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3425 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RESET_ADAPTER cleared, count=%d\n",
3430 if (sleepFlag == CAN_SLEEP) {
3437 if ( count == 30 ) {
3438 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot failed! "
3439 "Unable to get MPI_DIAG_DRWE mode, diag0val=%x\n",
3440 ioc->name, diag0val));
3444 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3445 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3446 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3447 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3448 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3449 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3451 /* Set the DiagRwEn and Disable ARM bits */
3452 CHIPREG_WRITE32(&ioc->chip->Diagnostic, (MPI_DIAG_RW_ENABLE | MPI_DIAG_DISABLE_ARM));
3454 fwSize = (pFwHeader->ImageSize + 3)/4;
3455 ptrFw = (u32 *) pFwHeader;
3457 /* Write the LoadStartAddress to the DiagRw Address Register
3458 * using Programmed IO
3460 if (ioc->errata_flag_1064)
3461 pci_enable_io_access(ioc->pcidev);
3463 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->LoadStartAddress);
3464 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "LoadStart addr written 0x%x \n",
3465 ioc->name, pFwHeader->LoadStartAddress));
3467 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write FW Image: 0x%x bytes @ %p\n",
3468 ioc->name, fwSize*4, ptrFw));
3470 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3473 nextImage = pFwHeader->NextImageHeaderOffset;
3475 pExtImage = (MpiExtImageHeader_t *) ((char *)pFwHeader + nextImage);
3477 load_addr = pExtImage->LoadStartAddress;
3479 fwSize = (pExtImage->ImageSize + 3) >> 2;
3480 ptrFw = (u32 *)pExtImage;
3482 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write Ext Image: 0x%x (%d) bytes @ %p load_addr=%x\n",
3483 ioc->name, fwSize*4, fwSize*4, ptrFw, load_addr));
3484 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, load_addr);
3487 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, *ptrFw++);
3489 nextImage = pExtImage->NextImageHeaderOffset;
3492 /* Write the IopResetVectorRegAddr */
3493 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Addr=%x! \n", ioc->name, pFwHeader->IopResetRegAddr));
3494 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, pFwHeader->IopResetRegAddr);
3496 /* Write the IopResetVectorValue */
3497 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Write IopResetVector Value=%x! \n", ioc->name, pFwHeader->IopResetVectorValue));
3498 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, pFwHeader->IopResetVectorValue);
3500 /* Clear the internal flash bad bit - autoincrementing register,
3501 * so must do two writes.
3503 if (ioc->bus_type == SPI) {
3505 * 1030 and 1035 H/W errata, workaround to access
3506 * the ClearFlashBadSignatureBit
3508 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3509 diagRwData = CHIPREG_PIO_READ32(&ioc->pio_chip->DiagRwData);
3510 diagRwData |= 0x40000000;
3511 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwAddress, 0x3F000000);
3512 CHIPREG_PIO_WRITE32(&ioc->pio_chip->DiagRwData, diagRwData);
3514 } else /* if((ioc->bus_type == SAS) || (ioc->bus_type == FC)) */ {
3515 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3516 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val |
3517 MPI_DIAG_CLEAR_FLASH_BAD_SIG);
3520 if (sleepFlag == CAN_SLEEP) {
3527 if (ioc->errata_flag_1064)
3528 pci_disable_io_access(ioc->pcidev);
3530 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3531 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot diag0val=%x, "
3532 "turning off PREVENT_IOC_BOOT, DISABLE_ARM, RW_ENABLE\n",
3533 ioc->name, diag0val));
3534 diag0val &= ~(MPI_DIAG_PREVENT_IOC_BOOT | MPI_DIAG_DISABLE_ARM | MPI_DIAG_RW_ENABLE);
3535 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "downloadboot now diag0val=%x\n",
3536 ioc->name, diag0val));
3537 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3539 /* Write 0xFF to reset the sequencer */
3540 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3542 if (ioc->bus_type == SAS) {
3543 ioc_state = mpt_GetIocState(ioc, 0);
3544 if ( (GetIocFacts(ioc, sleepFlag,
3545 MPT_HOSTEVENT_IOC_BRINGUP)) != 0 ) {
3546 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "GetIocFacts failed: IocState=%x\n",
3547 ioc->name, ioc_state));
3552 for (count=0; count<HZ*20; count++) {
3553 if ((ioc_state = mpt_GetIocState(ioc, 0)) & MPI_IOC_STATE_READY) {
3554 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3555 "downloadboot successful! (count=%d) IocState=%x\n",
3556 ioc->name, count, ioc_state));
3557 if (ioc->bus_type == SAS) {
3560 if ((SendIocInit(ioc, sleepFlag)) != 0) {
3561 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3562 "downloadboot: SendIocInit failed\n",
3566 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3567 "downloadboot: SendIocInit successful\n",
3571 if (sleepFlag == CAN_SLEEP) {
3577 ddlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3578 "downloadboot failed! IocState=%x\n",ioc->name, ioc_state));
3582 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3584 * KickStart - Perform hard reset of MPT adapter.
3585 * @ioc: Pointer to MPT_ADAPTER structure
3586 * @force: Force hard reset
3587 * @sleepFlag: Specifies whether the process can sleep
3589 * This routine places MPT adapter in diagnostic mode via the
3590 * WriteSequence register, and then performs a hard reset of adapter
3591 * via the Diagnostic register.
3593 * Inputs: sleepflag - CAN_SLEEP (non-interrupt thread)
3594 * or NO_SLEEP (interrupt thread, use mdelay)
3595 * force - 1 if doorbell active, board fault state
3596 * board operational, IOC_RECOVERY or
3597 * IOC_BRINGUP and there is an alt_ioc.
3601 * 1 - hard reset, READY
3602 * 0 - no reset due to History bit, READY
3603 * -1 - no reset due to History bit but not READY
3604 * OR reset but failed to come READY
3605 * -2 - no reset, could not enter DIAG mode
3606 * -3 - reset but bad FW bit
3609 KickStart(MPT_ADAPTER *ioc, int force, int sleepFlag)
3611 int hard_reset_done = 0;
3615 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStarting!\n", ioc->name));
3616 if (ioc->bus_type == SPI) {
3617 /* Always issue a Msg Unit Reset first. This will clear some
3618 * SCSI bus hang conditions.
3620 SendIocReset(ioc, MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET, sleepFlag);
3622 if (sleepFlag == CAN_SLEEP) {
3629 hard_reset_done = mpt_diag_reset(ioc, force, sleepFlag);
3630 if (hard_reset_done < 0)
3631 return hard_reset_done;
3633 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset successful!\n",
3636 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 2; /* 2 seconds */
3637 for (cnt=0; cnt<cntdn; cnt++) {
3638 ioc_state = mpt_GetIocState(ioc, 1);
3639 if ((ioc_state == MPI_IOC_STATE_READY) || (ioc_state == MPI_IOC_STATE_OPERATIONAL)) {
3640 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "KickStart successful! (cnt=%d)\n",
3642 return hard_reset_done;
3644 if (sleepFlag == CAN_SLEEP) {
3651 dinitprintk(ioc, printk(MYIOC_s_ERR_FMT "Failed to come READY after reset! IocState=%x\n",
3652 ioc->name, mpt_GetIocState(ioc, 0)));
3656 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3658 * mpt_diag_reset - Perform hard reset of the adapter.
3659 * @ioc: Pointer to MPT_ADAPTER structure
3660 * @ignore: Set if to honor and clear to ignore
3661 * the reset history bit
3662 * @sleepFlag: CAN_SLEEP if called in a non-interrupt thread,
3663 * else set to NO_SLEEP (use mdelay instead)
3665 * This routine places the adapter in diagnostic mode via the
3666 * WriteSequence register and then performs a hard reset of adapter
3667 * via the Diagnostic register. Adapter should be in ready state
3668 * upon successful completion.
3670 * Returns: 1 hard reset successful
3671 * 0 no reset performed because reset history bit set
3672 * -2 enabling diagnostic mode failed
3673 * -3 diagnostic reset failed
3676 mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
3680 int hard_reset_done = 0;
3683 MpiFwHeader_t *cached_fw; /* Pointer to FW */
3685 /* Clear any existing interrupts */
3686 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
3688 if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
3689 drsprintk(ioc, printk(MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
3690 "address=%p\n", ioc->name, __FUNCTION__,
3691 &ioc->chip->Doorbell, &ioc->chip->Reset_1078));
3692 CHIPREG_WRITE32(&ioc->chip->Reset_1078, 0x07);
3693 if (sleepFlag == CAN_SLEEP)
3698 for (count = 0; count < 60; count ++) {
3699 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3700 doorbell &= MPI_IOC_STATE_MASK;
3702 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3703 "looking for READY STATE: doorbell=%x"
3705 ioc->name, doorbell, count));
3706 if (doorbell == MPI_IOC_STATE_READY) {
3711 if (sleepFlag == CAN_SLEEP)
3719 /* Use "Diagnostic reset" method! (only thing available!) */
3720 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3722 if (ioc->debug_level & MPT_DEBUG) {
3724 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3725 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG1: diag0=%08x, diag1=%08x\n",
3726 ioc->name, diag0val, diag1val));
3729 /* Do the reset if we are told to ignore the reset history
3730 * or if the reset history is 0
3732 if (ignore || !(diag0val & MPI_DIAG_RESET_HISTORY)) {
3733 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3734 /* Write magic sequence to WriteSequence register
3735 * Loop until in diagnostic mode
3737 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3738 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3739 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3740 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3741 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3742 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3745 if (sleepFlag == CAN_SLEEP) {
3753 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3754 ioc->name, diag0val);
3759 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3761 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Wrote magic DiagWriteEn sequence (%x)\n",
3762 ioc->name, diag0val));
3765 if (ioc->debug_level & MPT_DEBUG) {
3767 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3768 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG2: diag0=%08x, diag1=%08x\n",
3769 ioc->name, diag0val, diag1val));
3772 * Disable the ARM (Bug fix)
3775 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_DISABLE_ARM);
3779 * Now hit the reset bit in the Diagnostic register
3780 * (THE BIG HAMMER!) (Clears DRWE bit).
3782 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val | MPI_DIAG_RESET_ADAPTER);
3783 hard_reset_done = 1;
3784 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Diagnostic reset performed\n",
3788 * Call each currently registered protocol IOC reset handler
3789 * with pre-reset indication.
3790 * NOTE: If we're doing _IOC_BRINGUP, there can be no
3791 * MptResetHandlers[] registered yet.
3797 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
3798 if (MptResetHandlers[cb_idx]) {
3799 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3800 "Calling IOC pre_reset handler #%d\n",
3801 ioc->name, cb_idx));
3802 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_PRE_RESET);
3804 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
3805 "Calling alt-%s pre_reset handler #%d\n",
3806 ioc->name, ioc->alt_ioc->name, cb_idx));
3807 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_PRE_RESET);
3811 /* FIXME? Examine results here? */
3815 cached_fw = (MpiFwHeader_t *)ioc->cached_fw;
3816 else if (ioc->alt_ioc && ioc->alt_ioc->cached_fw)
3817 cached_fw = (MpiFwHeader_t *)ioc->alt_ioc->cached_fw;
3821 /* If the DownloadBoot operation fails, the
3822 * IOC will be left unusable. This is a fatal error
3823 * case. _diag_reset will return < 0
3825 for (count = 0; count < 30; count ++) {
3826 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3827 if (!(diag0val & MPI_DIAG_RESET_ADAPTER)) {
3831 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "cached_fw: diag0val=%x count=%d\n",
3832 ioc->name, diag0val, count));
3834 if (sleepFlag == CAN_SLEEP) {
3840 if ((count = mpt_downloadboot(ioc, cached_fw, sleepFlag)) < 0) {
3841 printk(MYIOC_s_WARN_FMT
3842 "firmware downloadboot failure (%d)!\n", ioc->name, count);
3846 /* Wait for FW to reload and for board
3847 * to go to the READY state.
3848 * Maximum wait is 60 seconds.
3849 * If fail, no error will check again
3850 * with calling program.
3852 for (count = 0; count < 60; count ++) {
3853 doorbell = CHIPREG_READ32(&ioc->chip->Doorbell);
3854 doorbell &= MPI_IOC_STATE_MASK;
3856 if (doorbell == MPI_IOC_STATE_READY) {
3861 if (sleepFlag == CAN_SLEEP) {
3870 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3871 if (ioc->debug_level & MPT_DEBUG) {
3873 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3874 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG3: diag0=%08x, diag1=%08x\n",
3875 ioc->name, diag0val, diag1val));
3878 /* Clear RESET_HISTORY bit! Place board in the
3879 * diagnostic mode to update the diag register.
3881 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3883 while ((diag0val & MPI_DIAG_DRWE) == 0) {
3884 /* Write magic sequence to WriteSequence register
3885 * Loop until in diagnostic mode
3887 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFF);
3888 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_1ST_KEY_VALUE);
3889 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_2ND_KEY_VALUE);
3890 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_3RD_KEY_VALUE);
3891 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_4TH_KEY_VALUE);
3892 CHIPREG_WRITE32(&ioc->chip->WriteSequence, MPI_WRSEQ_5TH_KEY_VALUE);
3895 if (sleepFlag == CAN_SLEEP) {
3903 printk(MYIOC_s_ERR_FMT "Enable Diagnostic mode FAILED! (%02xh)\n",
3904 ioc->name, diag0val);
3907 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3909 diag0val &= ~MPI_DIAG_RESET_HISTORY;
3910 CHIPREG_WRITE32(&ioc->chip->Diagnostic, diag0val);
3911 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3912 if (diag0val & MPI_DIAG_RESET_HISTORY) {
3913 printk(MYIOC_s_WARN_FMT "ResetHistory bit failed to clear!\n",
3917 /* Disable Diagnostic Mode
3919 CHIPREG_WRITE32(&ioc->chip->WriteSequence, 0xFFFFFFFF);
3921 /* Check FW reload status flags.
3923 diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
3924 if (diag0val & (MPI_DIAG_FLASH_BAD_SIG | MPI_DIAG_RESET_ADAPTER | MPI_DIAG_DISABLE_ARM)) {
3925 printk(MYIOC_s_ERR_FMT "Diagnostic reset FAILED! (%02xh)\n",
3926 ioc->name, diag0val);
3930 if (ioc->debug_level & MPT_DEBUG) {
3932 diag1val = CHIPREG_READ32(&ioc->alt_ioc->chip->Diagnostic);
3933 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "DbG4: diag0=%08x, diag1=%08x\n",
3934 ioc->name, diag0val, diag1val));
3938 * Reset flag that says we've enabled event notification
3940 ioc->facts.EventState = 0;
3943 ioc->alt_ioc->facts.EventState = 0;
3945 return hard_reset_done;
3948 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
3950 * SendIocReset - Send IOCReset request to MPT adapter.
3951 * @ioc: Pointer to MPT_ADAPTER structure
3952 * @reset_type: reset type, expected values are
3953 * %MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET or %MPI_FUNCTION_IO_UNIT_RESET
3954 * @sleepFlag: Specifies whether the process can sleep
3956 * Send IOCReset request to the MPT adapter.
3958 * Returns 0 for success, non-zero for failure.
3961 SendIocReset(MPT_ADAPTER *ioc, u8 reset_type, int sleepFlag)
3967 drsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending IOC reset(0x%02x)!\n",
3968 ioc->name, reset_type));
3969 CHIPREG_WRITE32(&ioc->chip->Doorbell, reset_type<<MPI_DOORBELL_FUNCTION_SHIFT);
3970 if ((r = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
3973 /* FW ACK'd request, wait for READY state
3976 cntdn = ((sleepFlag == CAN_SLEEP) ? HZ : 1000) * 15; /* 15 seconds */
3978 while ((state = mpt_GetIocState(ioc, 1)) != MPI_IOC_STATE_READY) {
3982 if (sleepFlag != CAN_SLEEP)
3985 printk(MYIOC_s_ERR_FMT "Wait IOC_READY state timeout(%d)!\n",
3986 ioc->name, (int)((count+5)/HZ));
3990 if (sleepFlag == CAN_SLEEP) {
3993 mdelay (1); /* 1 msec delay */
3998 * Cleanup all event stuff for this IOC; re-issue EventNotification
3999 * request if needed.
4001 if (ioc->facts.Function)
4002 ioc->facts.EventState = 0;
4007 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4009 * initChainBuffers - Allocate memory for and initialize chain buffers
4010 * @ioc: Pointer to MPT_ADAPTER structure
4012 * Allocates memory for and initializes chain buffers,
4013 * chain buffer control arrays and spinlock.
4016 initChainBuffers(MPT_ADAPTER *ioc)
4019 int sz, ii, num_chain;
4020 int scale, num_sge, numSGE;
4022 /* ReqToChain size must equal the req_depth
4025 if (ioc->ReqToChain == NULL) {
4026 sz = ioc->req_depth * sizeof(int);
4027 mem = kmalloc(sz, GFP_ATOMIC);
4031 ioc->ReqToChain = (int *) mem;
4032 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReqToChain alloc @ %p, sz=%d bytes\n",
4033 ioc->name, mem, sz));
4034 mem = kmalloc(sz, GFP_ATOMIC);
4038 ioc->RequestNB = (int *) mem;
4039 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestNB alloc @ %p, sz=%d bytes\n",
4040 ioc->name, mem, sz));
4042 for (ii = 0; ii < ioc->req_depth; ii++) {
4043 ioc->ReqToChain[ii] = MPT_HOST_NO_CHAIN;
4046 /* ChainToChain size must equal the total number
4047 * of chain buffers to be allocated.
4050 * Calculate the number of chain buffers needed(plus 1) per I/O
4051 * then multiply the maximum number of simultaneous cmds
4053 * num_sge = num sge in request frame + last chain buffer
4054 * scale = num sge per chain buffer if no chain element
4056 scale = ioc->req_sz/(sizeof(dma_addr_t) + sizeof(u32));
4057 if (sizeof(dma_addr_t) == sizeof(u64))
4058 num_sge = scale + (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
4060 num_sge = 1+ scale + (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
4062 if (sizeof(dma_addr_t) == sizeof(u64)) {
4063 numSGE = (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4064 (ioc->req_sz - 60) / (sizeof(dma_addr_t) + sizeof(u32));
4066 numSGE = 1 + (scale - 1) * (ioc->facts.MaxChainDepth-1) + scale +
4067 (ioc->req_sz - 64) / (sizeof(dma_addr_t) + sizeof(u32));
4069 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "num_sge=%d numSGE=%d\n",
4070 ioc->name, num_sge, numSGE));
4072 if ( numSGE > MPT_SCSI_SG_DEPTH )
4073 numSGE = MPT_SCSI_SG_DEPTH;
4076 while (numSGE - num_sge > 0) {
4078 num_sge += (scale - 1);
4082 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Now numSGE=%d num_sge=%d num_chain=%d\n",
4083 ioc->name, numSGE, num_sge, num_chain));
4085 if (ioc->bus_type == SPI)
4086 num_chain *= MPT_SCSI_CAN_QUEUE;
4088 num_chain *= MPT_FC_CAN_QUEUE;
4090 ioc->num_chain = num_chain;
4092 sz = num_chain * sizeof(int);
4093 if (ioc->ChainToChain == NULL) {
4094 mem = kmalloc(sz, GFP_ATOMIC);
4098 ioc->ChainToChain = (int *) mem;
4099 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainToChain alloc @ %p, sz=%d bytes\n",
4100 ioc->name, mem, sz));
4102 mem = (u8 *) ioc->ChainToChain;
4104 memset(mem, 0xFF, sz);
4108 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4110 * PrimeIocFifos - Initialize IOC request and reply FIFOs.
4111 * @ioc: Pointer to MPT_ADAPTER structure
4113 * This routine allocates memory for the MPT reply and request frame
4114 * pools (if necessary), and primes the IOC reply FIFO with
4117 * Returns 0 for success, non-zero for failure.
4120 PrimeIocFifos(MPT_ADAPTER *ioc)
4123 unsigned long flags;
4124 dma_addr_t alloc_dma;
4126 int i, reply_sz, sz, total_size, num_chain;
4128 /* Prime reply FIFO... */
4130 if (ioc->reply_frames == NULL) {
4131 if ( (num_chain = initChainBuffers(ioc)) < 0)
4134 total_size = reply_sz = (ioc->reply_sz * ioc->reply_depth);
4135 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d bytes, ReplyDepth=%d\n",
4136 ioc->name, ioc->reply_sz, ioc->reply_depth));
4137 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffer sz=%d[%x] bytes\n",
4138 ioc->name, reply_sz, reply_sz));
4140 sz = (ioc->req_sz * ioc->req_depth);
4141 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d bytes, RequestDepth=%d\n",
4142 ioc->name, ioc->req_sz, ioc->req_depth));
4143 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffer sz=%d[%x] bytes\n",
4144 ioc->name, sz, sz));
4147 sz = num_chain * ioc->req_sz; /* chain buffer pool size */
4148 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d bytes, ChainDepth=%d\n",
4149 ioc->name, ioc->req_sz, num_chain));
4150 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffer sz=%d[%x] bytes num_chain=%d\n",
4151 ioc->name, sz, sz, num_chain));
4154 mem = pci_alloc_consistent(ioc->pcidev, total_size, &alloc_dma);
4156 printk(MYIOC_s_ERR_FMT "Unable to allocate Reply, Request, Chain Buffers!\n",
4161 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Total alloc @ %p[%p], sz=%d[%x] bytes\n",
4162 ioc->name, mem, (void *)(ulong)alloc_dma, total_size, total_size));
4164 memset(mem, 0, total_size);
4165 ioc->alloc_total += total_size;
4167 ioc->alloc_dma = alloc_dma;
4168 ioc->alloc_sz = total_size;
4169 ioc->reply_frames = (MPT_FRAME_HDR *) mem;
4170 ioc->reply_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4172 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4173 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4175 alloc_dma += reply_sz;
4178 /* Request FIFO - WE manage this! */
4180 ioc->req_frames = (MPT_FRAME_HDR *) mem;
4181 ioc->req_frames_dma = alloc_dma;
4183 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "RequestBuffers @ %p[%p]\n",
4184 ioc->name, mem, (void *)(ulong)alloc_dma));
4186 ioc->req_frames_low_dma = (u32) (alloc_dma & 0xFFFFFFFF);
4188 #if defined(CONFIG_MTRR) && 0
4190 * Enable Write Combining MTRR for IOC's memory region.
4191 * (at least as much as we can; "size and base must be
4192 * multiples of 4 kiB"
4194 ioc->mtrr_reg = mtrr_add(ioc->req_frames_dma,
4196 MTRR_TYPE_WRCOMB, 1);
4197 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MTRR region registered (base:size=%08x:%x)\n",
4198 ioc->name, ioc->req_frames_dma, sz));
4201 for (i = 0; i < ioc->req_depth; i++) {
4202 alloc_dma += ioc->req_sz;
4206 ioc->ChainBuffer = mem;
4207 ioc->ChainBufferDMA = alloc_dma;
4209 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ChainBuffers @ %p(%p)\n",
4210 ioc->name, ioc->ChainBuffer, (void *)(ulong)ioc->ChainBufferDMA));
4212 /* Initialize the free chain Q.
4215 INIT_LIST_HEAD(&ioc->FreeChainQ);
4217 /* Post the chain buffers to the FreeChainQ.
4219 mem = (u8 *)ioc->ChainBuffer;
4220 for (i=0; i < num_chain; i++) {
4221 mf = (MPT_FRAME_HDR *) mem;
4222 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeChainQ);
4226 /* Initialize Request frames linked list
4228 alloc_dma = ioc->req_frames_dma;
4229 mem = (u8 *) ioc->req_frames;
4231 spin_lock_irqsave(&ioc->FreeQlock, flags);
4232 INIT_LIST_HEAD(&ioc->FreeQ);
4233 for (i = 0; i < ioc->req_depth; i++) {
4234 mf = (MPT_FRAME_HDR *) mem;
4236 /* Queue REQUESTs *internally*! */
4237 list_add_tail(&mf->u.frame.linkage.list, &ioc->FreeQ);
4241 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
4243 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4244 ioc->sense_buf_pool =
4245 pci_alloc_consistent(ioc->pcidev, sz, &ioc->sense_buf_pool_dma);
4246 if (ioc->sense_buf_pool == NULL) {
4247 printk(MYIOC_s_ERR_FMT "Unable to allocate Sense Buffers!\n",
4252 ioc->sense_buf_low_dma = (u32) (ioc->sense_buf_pool_dma & 0xFFFFFFFF);
4253 ioc->alloc_total += sz;
4254 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SenseBuffers @ %p[%p]\n",
4255 ioc->name, ioc->sense_buf_pool, (void *)(ulong)ioc->sense_buf_pool_dma));
4259 /* Post Reply frames to FIFO
4261 alloc_dma = ioc->alloc_dma;
4262 dinitprintk(ioc, printk(MYIOC_s_DEBUG_FMT "ReplyBuffers @ %p[%p]\n",
4263 ioc->name, ioc->reply_frames, (void *)(ulong)alloc_dma));
4265 for (i = 0; i < ioc->reply_depth; i++) {
4266 /* Write each address to the IOC! */
4267 CHIPREG_WRITE32(&ioc->chip->ReplyFifo, alloc_dma);
4268 alloc_dma += ioc->reply_sz;
4274 if (ioc->alloc != NULL) {
4276 pci_free_consistent(ioc->pcidev,
4278 ioc->alloc, ioc->alloc_dma);
4279 ioc->reply_frames = NULL;
4280 ioc->req_frames = NULL;
4281 ioc->alloc_total -= sz;
4283 if (ioc->sense_buf_pool != NULL) {
4284 sz = (ioc->req_depth * MPT_SENSE_BUFFER_ALLOC);
4285 pci_free_consistent(ioc->pcidev,
4287 ioc->sense_buf_pool, ioc->sense_buf_pool_dma);
4288 ioc->sense_buf_pool = NULL;
4293 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4295 * mpt_handshake_req_reply_wait - Send MPT request to and receive reply
4296 * from IOC via doorbell handshake method.
4297 * @ioc: Pointer to MPT_ADAPTER structure
4298 * @reqBytes: Size of the request in bytes
4299 * @req: Pointer to MPT request frame
4300 * @replyBytes: Expected size of the reply in bytes
4301 * @u16reply: Pointer to area where reply should be written
4302 * @maxwait: Max wait time for a reply (in seconds)
4303 * @sleepFlag: Specifies whether the process can sleep
4305 * NOTES: It is the callers responsibility to byte-swap fields in the
4306 * request which are greater than 1 byte in size. It is also the
4307 * callers responsibility to byte-swap response fields which are
4308 * greater than 1 byte in size.
4310 * Returns 0 for success, non-zero for failure.
4313 mpt_handshake_req_reply_wait(MPT_ADAPTER *ioc, int reqBytes, u32 *req,
4314 int replyBytes, u16 *u16reply, int maxwait, int sleepFlag)
4316 MPIDefaultReply_t *mptReply;
4321 * Get ready to cache a handshake reply
4323 ioc->hs_reply_idx = 0;
4324 mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4325 mptReply->MsgLength = 0;
4328 * Make sure there are no doorbells (WRITE 0 to IntStatus reg),
4329 * then tell IOC that we want to handshake a request of N words.
4330 * (WRITE u32val to Doorbell reg).
4332 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4333 CHIPREG_WRITE32(&ioc->chip->Doorbell,
4334 ((MPI_FUNCTION_HANDSHAKE<<MPI_DOORBELL_FUNCTION_SHIFT) |
4335 ((reqBytes/4)<<MPI_DOORBELL_ADD_DWORDS_SHIFT)));
4338 * Wait for IOC's doorbell handshake int
4340 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4343 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request start reqBytes=%d, WaitCnt=%d%s\n",
4344 ioc->name, reqBytes, t, failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4346 /* Read doorbell and check for active bit */
4347 if (!(CHIPREG_READ32(&ioc->chip->Doorbell) & MPI_DOORBELL_ACTIVE))
4351 * Clear doorbell int (WRITE 0 to IntStatus reg),
4352 * then wait for IOC to ACKnowledge that it's ready for
4353 * our handshake request.
4355 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4356 if (!failcnt && (t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4361 u8 *req_as_bytes = (u8 *) req;
4364 * Stuff request words via doorbell handshake,
4365 * with ACK from IOC for each.
4367 for (ii = 0; !failcnt && ii < reqBytes/4; ii++) {
4368 u32 word = ((req_as_bytes[(ii*4) + 0] << 0) |
4369 (req_as_bytes[(ii*4) + 1] << 8) |
4370 (req_as_bytes[(ii*4) + 2] << 16) |
4371 (req_as_bytes[(ii*4) + 3] << 24));
4373 CHIPREG_WRITE32(&ioc->chip->Doorbell, word);
4374 if ((t = WaitForDoorbellAck(ioc, 5, sleepFlag)) < 0)
4378 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Handshake request frame (@%p) header\n", ioc->name, req));
4379 DBG_DUMP_REQUEST_FRAME_HDR(ioc, (u32 *)req);
4381 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake request post done, WaitCnt=%d%s\n",
4382 ioc->name, t, failcnt ? " - MISSING DOORBELL ACK!" : ""));
4385 * Wait for completion of doorbell handshake reply from the IOC
4387 if (!failcnt && (t = WaitForDoorbellReply(ioc, maxwait, sleepFlag)) < 0)
4390 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HandShake reply count=%d%s\n",
4391 ioc->name, t, failcnt ? " - MISSING DOORBELL REPLY!" : ""));
4394 * Copy out the cached reply...
4396 for (ii=0; ii < min(replyBytes/2,mptReply->MsgLength*2); ii++)
4397 u16reply[ii] = ioc->hs_reply[ii];
4405 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4407 * WaitForDoorbellAck - Wait for IOC doorbell handshake acknowledge
4408 * @ioc: Pointer to MPT_ADAPTER structure
4409 * @howlong: How long to wait (in seconds)
4410 * @sleepFlag: Specifies whether the process can sleep
4412 * This routine waits (up to ~2 seconds max) for IOC doorbell
4413 * handshake ACKnowledge, indicated by the IOP_DOORBELL_STATUS
4414 * bit in its IntStatus register being clear.
4416 * Returns a negative value on failure, else wait loop count.
4419 WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4425 cntdn = 1000 * howlong;
4427 if (sleepFlag == CAN_SLEEP) {
4430 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4431 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4438 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4439 if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
4446 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell ACK (count=%d)\n",
4451 printk(MYIOC_s_ERR_FMT "Doorbell ACK timeout (count=%d), IntStatus=%x!\n",
4452 ioc->name, count, intstat);
4456 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4458 * WaitForDoorbellInt - Wait for IOC to set its doorbell interrupt bit
4459 * @ioc: Pointer to MPT_ADAPTER structure
4460 * @howlong: How long to wait (in seconds)
4461 * @sleepFlag: Specifies whether the process can sleep
4463 * This routine waits (up to ~2 seconds max) for IOC doorbell interrupt
4464 * (MPI_HIS_DOORBELL_INTERRUPT) to be set in the IntStatus register.
4466 * Returns a negative value on failure, else wait loop count.
4469 WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4475 cntdn = 1000 * howlong;
4476 if (sleepFlag == CAN_SLEEP) {
4478 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4479 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4486 intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
4487 if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
4495 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell INT (cnt=%d) howlong=%d\n",
4496 ioc->name, count, howlong));
4500 printk(MYIOC_s_ERR_FMT "Doorbell INT timeout (count=%d), IntStatus=%x!\n",
4501 ioc->name, count, intstat);
4505 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4507 * WaitForDoorbellReply - Wait for and capture an IOC handshake reply.
4508 * @ioc: Pointer to MPT_ADAPTER structure
4509 * @howlong: How long to wait (in seconds)
4510 * @sleepFlag: Specifies whether the process can sleep
4512 * This routine polls the IOC for a handshake reply, 16 bits at a time.
4513 * Reply is cached to IOC private area large enough to hold a maximum
4514 * of 128 bytes of reply data.
4516 * Returns a negative value on failure, else size of reply in WORDS.
4519 WaitForDoorbellReply(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
4524 u16 *hs_reply = ioc->hs_reply;
4525 volatile MPIDefaultReply_t *mptReply = (MPIDefaultReply_t *) ioc->hs_reply;
4528 hs_reply[0] = hs_reply[1] = hs_reply[7] = 0;
4531 * Get first two u16's so we can look at IOC's intended reply MsgLength
4534 if ((t = WaitForDoorbellInt(ioc, howlong, sleepFlag)) < 0) {
4537 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4538 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4539 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4542 hs_reply[u16cnt++] = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4543 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4547 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitCnt=%d First handshake reply word=%08x%s\n",
4548 ioc->name, t, le32_to_cpu(*(u32 *)hs_reply),
4549 failcnt ? " - MISSING DOORBELL HANDSHAKE!" : ""));
4552 * If no error (and IOC said MsgLength is > 0), piece together
4553 * reply 16 bits at a time.
4555 for (u16cnt=2; !failcnt && u16cnt < (2 * mptReply->MsgLength); u16cnt++) {
4556 if ((t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4558 hword = le16_to_cpu(CHIPREG_READ32(&ioc->chip->Doorbell) & 0x0000FFFF);
4559 /* don't overflow our IOC hs_reply[] buffer! */
4560 if (u16cnt < sizeof(ioc->hs_reply) / sizeof(ioc->hs_reply[0]))
4561 hs_reply[u16cnt] = hword;
4562 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4565 if (!failcnt && (t = WaitForDoorbellInt(ioc, 5, sleepFlag)) < 0)
4567 CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
4570 printk(MYIOC_s_ERR_FMT "Handshake reply failure!\n",
4575 else if (u16cnt != (2 * mptReply->MsgLength)) {
4578 else if ((mptReply->IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_SUCCESS) {
4583 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Got Handshake reply:\n", ioc->name));
4584 DBG_DUMP_REPLY_FRAME(ioc, (u32 *)mptReply);
4586 dhsprintk(ioc, printk(MYIOC_s_DEBUG_FMT "WaitForDoorbell REPLY WaitCnt=%d (sz=%d)\n",
4587 ioc->name, t, u16cnt/2));
4591 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4593 * GetLanConfigPages - Fetch LANConfig pages.
4594 * @ioc: Pointer to MPT_ADAPTER structure
4596 * Return: 0 for success
4597 * -ENOMEM if no memory available
4598 * -EPERM if not allowed due to ISR context
4599 * -EAGAIN if no msg frames currently available
4600 * -EFAULT for non-successful reply or no reply (timeout)
4603 GetLanConfigPages(MPT_ADAPTER *ioc)
4605 ConfigPageHeader_t hdr;
4607 LANPage0_t *ppage0_alloc;
4608 dma_addr_t page0_dma;
4609 LANPage1_t *ppage1_alloc;
4610 dma_addr_t page1_dma;
4615 /* Get LAN Page 0 header */
4616 hdr.PageVersion = 0;
4619 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4620 cfg.cfghdr.hdr = &hdr;
4622 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4627 if ((rc = mpt_config(ioc, &cfg)) != 0)
4630 if (hdr.PageLength > 0) {
4631 data_sz = hdr.PageLength * 4;
4632 ppage0_alloc = (LANPage0_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page0_dma);
4635 memset((u8 *)ppage0_alloc, 0, data_sz);
4636 cfg.physAddr = page0_dma;
4637 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4639 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4641 copy_sz = min_t(int, sizeof(LANPage0_t), data_sz);
4642 memcpy(&ioc->lan_cnfg_page0, ppage0_alloc, copy_sz);
4646 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage0_alloc, page0_dma);
4649 * Normalize endianness of structure data,
4650 * by byte-swapping all > 1 byte fields!
4659 /* Get LAN Page 1 header */
4660 hdr.PageVersion = 0;
4663 hdr.PageType = MPI_CONFIG_PAGETYPE_LAN;
4664 cfg.cfghdr.hdr = &hdr;
4666 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4670 if ((rc = mpt_config(ioc, &cfg)) != 0)
4673 if (hdr.PageLength == 0)
4676 data_sz = hdr.PageLength * 4;
4678 ppage1_alloc = (LANPage1_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page1_dma);
4680 memset((u8 *)ppage1_alloc, 0, data_sz);
4681 cfg.physAddr = page1_dma;
4682 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4684 if ((rc = mpt_config(ioc, &cfg)) == 0) {
4686 copy_sz = min_t(int, sizeof(LANPage1_t), data_sz);
4687 memcpy(&ioc->lan_cnfg_page1, ppage1_alloc, copy_sz);
4690 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage1_alloc, page1_dma);
4693 * Normalize endianness of structure data,
4694 * by byte-swapping all > 1 byte fields!
4702 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4704 * mptbase_sas_persist_operation - Perform operation on SAS Persistent Table
4705 * @ioc: Pointer to MPT_ADAPTER structure
4706 * @persist_opcode: see below
4708 * MPI_SAS_OP_CLEAR_NOT_PRESENT - Free all persist TargetID mappings for
4709 * devices not currently present.
4710 * MPI_SAS_OP_CLEAR_ALL_PERSISTENT - Clear al persist TargetID mappings
4712 * NOTE: Don't use not this function during interrupt time.
4714 * Returns 0 for success, non-zero error
4717 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4719 mptbase_sas_persist_operation(MPT_ADAPTER *ioc, u8 persist_opcode)
4721 SasIoUnitControlRequest_t *sasIoUnitCntrReq;
4722 SasIoUnitControlReply_t *sasIoUnitCntrReply;
4723 MPT_FRAME_HDR *mf = NULL;
4724 MPIHeader_t *mpi_hdr;
4727 /* insure garbage is not sent to fw */
4728 switch(persist_opcode) {
4730 case MPI_SAS_OP_CLEAR_NOT_PRESENT:
4731 case MPI_SAS_OP_CLEAR_ALL_PERSISTENT:
4739 printk("%s: persist_opcode=%x\n",__FUNCTION__, persist_opcode);
4741 /* Get a MF for this command.
4743 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
4744 printk("%s: no msg frames!\n",__FUNCTION__);
4748 mpi_hdr = (MPIHeader_t *) mf;
4749 sasIoUnitCntrReq = (SasIoUnitControlRequest_t *)mf;
4750 memset(sasIoUnitCntrReq,0,sizeof(SasIoUnitControlRequest_t));
4751 sasIoUnitCntrReq->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL;
4752 sasIoUnitCntrReq->MsgContext = mpi_hdr->MsgContext;
4753 sasIoUnitCntrReq->Operation = persist_opcode;
4755 init_timer(&ioc->persist_timer);
4756 ioc->persist_timer.data = (unsigned long) ioc;
4757 ioc->persist_timer.function = mpt_timer_expired;
4758 ioc->persist_timer.expires = jiffies + HZ*10 /* 10 sec */;
4759 ioc->persist_wait_done=0;
4760 add_timer(&ioc->persist_timer);
4761 mpt_put_msg_frame(mpt_base_index, ioc, mf);
4762 wait_event(mpt_waitq, ioc->persist_wait_done);
4764 sasIoUnitCntrReply =
4765 (SasIoUnitControlReply_t *)ioc->persist_reply_frame;
4766 if (le16_to_cpu(sasIoUnitCntrReply->IOCStatus) != MPI_IOCSTATUS_SUCCESS) {
4767 printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n",
4769 sasIoUnitCntrReply->IOCStatus,
4770 sasIoUnitCntrReply->IOCLogInfo);
4774 printk("%s: success\n",__FUNCTION__);
4778 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4781 mptbase_raid_process_event_data(MPT_ADAPTER *ioc,
4782 MpiEventDataRaid_t * pRaidEventData)
4791 volume = pRaidEventData->VolumeID;
4792 reason = pRaidEventData->ReasonCode;
4793 disk = pRaidEventData->PhysDiskNum;
4794 status = le32_to_cpu(pRaidEventData->SettingsStatus);
4795 flags = (status >> 0) & 0xff;
4796 state = (status >> 8) & 0xff;
4798 if (reason == MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED) {
4802 if ((reason >= MPI_EVENT_RAID_RC_PHYSDISK_CREATED &&
4803 reason <= MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED) ||
4804 (reason == MPI_EVENT_RAID_RC_SMART_DATA)) {
4805 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for PhysDisk %d id=%d\n",
4806 ioc->name, disk, volume);
4808 printk(MYIOC_s_INFO_FMT "RAID STATUS CHANGE for VolumeID %d\n",
4813 case MPI_EVENT_RAID_RC_VOLUME_CREATED:
4814 printk(MYIOC_s_INFO_FMT " volume has been created\n",
4818 case MPI_EVENT_RAID_RC_VOLUME_DELETED:
4820 printk(MYIOC_s_INFO_FMT " volume has been deleted\n",
4824 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED:
4825 printk(MYIOC_s_INFO_FMT " volume settings have been changed\n",
4829 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED:
4830 printk(MYIOC_s_INFO_FMT " volume is now %s%s%s%s\n",
4832 state == MPI_RAIDVOL0_STATUS_STATE_OPTIMAL
4834 : state == MPI_RAIDVOL0_STATUS_STATE_DEGRADED
4836 : state == MPI_RAIDVOL0_STATUS_STATE_FAILED
4839 flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED
4841 flags & MPI_RAIDVOL0_STATUS_FLAG_QUIESCED
4842 ? ", quiesced" : "",
4843 flags & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS
4844 ? ", resync in progress" : "" );
4847 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED:
4848 printk(MYIOC_s_INFO_FMT " volume membership of PhysDisk %d has changed\n",
4852 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED:
4853 printk(MYIOC_s_INFO_FMT " PhysDisk has been created\n",
4857 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED:
4858 printk(MYIOC_s_INFO_FMT " PhysDisk has been deleted\n",
4862 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED:
4863 printk(MYIOC_s_INFO_FMT " PhysDisk settings have been changed\n",
4867 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED:
4868 printk(MYIOC_s_INFO_FMT " PhysDisk is now %s%s%s\n",
4870 state == MPI_PHYSDISK0_STATUS_ONLINE
4872 : state == MPI_PHYSDISK0_STATUS_MISSING
4874 : state == MPI_PHYSDISK0_STATUS_NOT_COMPATIBLE
4876 : state == MPI_PHYSDISK0_STATUS_FAILED
4878 : state == MPI_PHYSDISK0_STATUS_INITIALIZING
4880 : state == MPI_PHYSDISK0_STATUS_OFFLINE_REQUESTED
4881 ? "offline requested"
4882 : state == MPI_PHYSDISK0_STATUS_FAILED_REQUESTED
4883 ? "failed requested"
4884 : state == MPI_PHYSDISK0_STATUS_OTHER_OFFLINE
4887 flags & MPI_PHYSDISK0_STATUS_FLAG_OUT_OF_SYNC
4888 ? ", out of sync" : "",
4889 flags & MPI_PHYSDISK0_STATUS_FLAG_QUIESCED
4890 ? ", quiesced" : "" );
4893 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED:
4894 printk(MYIOC_s_INFO_FMT " Domain Validation needed for PhysDisk %d\n",
4898 case MPI_EVENT_RAID_RC_SMART_DATA:
4899 printk(MYIOC_s_INFO_FMT " SMART data received, ASC/ASCQ = %02xh/%02xh\n",
4900 ioc->name, pRaidEventData->ASC, pRaidEventData->ASCQ);
4903 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED:
4904 printk(MYIOC_s_INFO_FMT " replacement of PhysDisk %d has started\n",
4910 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4912 * GetIoUnitPage2 - Retrieve BIOS version and boot order information.
4913 * @ioc: Pointer to MPT_ADAPTER structure
4915 * Returns: 0 for success
4916 * -ENOMEM if no memory available
4917 * -EPERM if not allowed due to ISR context
4918 * -EAGAIN if no msg frames currently available
4919 * -EFAULT for non-successful reply or no reply (timeout)
4922 GetIoUnitPage2(MPT_ADAPTER *ioc)
4924 ConfigPageHeader_t hdr;
4926 IOUnitPage2_t *ppage_alloc;
4927 dma_addr_t page_dma;
4931 /* Get the page header */
4932 hdr.PageVersion = 0;
4935 hdr.PageType = MPI_CONFIG_PAGETYPE_IO_UNIT;
4936 cfg.cfghdr.hdr = &hdr;
4938 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
4943 if ((rc = mpt_config(ioc, &cfg)) != 0)
4946 if (hdr.PageLength == 0)
4949 /* Read the config page */
4950 data_sz = hdr.PageLength * 4;
4952 ppage_alloc = (IOUnitPage2_t *) pci_alloc_consistent(ioc->pcidev, data_sz, &page_dma);
4954 memset((u8 *)ppage_alloc, 0, data_sz);
4955 cfg.physAddr = page_dma;
4956 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
4958 /* If Good, save data */
4959 if ((rc = mpt_config(ioc, &cfg)) == 0)
4960 ioc->biosVersion = le32_to_cpu(ppage_alloc->BiosVersion);
4962 pci_free_consistent(ioc->pcidev, data_sz, (u8 *) ppage_alloc, page_dma);
4968 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
4970 * mpt_GetScsiPortSettings - read SCSI Port Page 0 and 2
4971 * @ioc: Pointer to a Adapter Strucutre
4972 * @portnum: IOC port number
4974 * Return: -EFAULT if read of config page header fails
4976 * If read of SCSI Port Page 0 fails,
4977 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4978 * Adapter settings: async, narrow
4980 * If read of SCSI Port Page 2 fails,
4981 * Adapter settings valid
4982 * NVRAM = MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
4987 * CHECK - what type of locking mechanisms should be used????
4990 mpt_GetScsiPortSettings(MPT_ADAPTER *ioc, int portnum)
4995 ConfigPageHeader_t header;
5001 if (!ioc->spi_data.nvram) {
5004 sz = MPT_MAX_SCSI_DEVICES * sizeof(int);
5005 mem = kmalloc(sz, GFP_ATOMIC);
5009 ioc->spi_data.nvram = (int *) mem;
5011 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SCSI device NVRAM settings @ %p, sz=%d\n",
5012 ioc->name, ioc->spi_data.nvram, sz));
5015 /* Invalidate NVRAM information
5017 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5018 ioc->spi_data.nvram[ii] = MPT_HOST_NVRAM_INVALID;
5021 /* Read SPP0 header, allocate memory, then read page.
5023 header.PageVersion = 0;
5024 header.PageLength = 0;
5025 header.PageNumber = 0;
5026 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5027 cfg.cfghdr.hdr = &header;
5029 cfg.pageAddr = portnum;
5030 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5032 cfg.timeout = 0; /* use default */
5033 if (mpt_config(ioc, &cfg) != 0)
5036 if (header.PageLength > 0) {
5037 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5039 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5040 cfg.physAddr = buf_dma;
5041 if (mpt_config(ioc, &cfg) != 0) {
5042 ioc->spi_data.maxBusWidth = MPT_NARROW;
5043 ioc->spi_data.maxSyncOffset = 0;
5044 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5045 ioc->spi_data.busType = MPT_HOST_BUS_UNKNOWN;
5047 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5048 "Unable to read PortPage0 minSyncFactor=%x\n",
5049 ioc->name, ioc->spi_data.minSyncFactor));
5051 /* Save the Port Page 0 data
5053 SCSIPortPage0_t *pPP0 = (SCSIPortPage0_t *) pbuf;
5054 pPP0->Capabilities = le32_to_cpu(pPP0->Capabilities);
5055 pPP0->PhysicalInterface = le32_to_cpu(pPP0->PhysicalInterface);
5057 if ( (pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_QAS) == 0 ) {
5058 ioc->spi_data.noQas |= MPT_TARGET_NO_NEGO_QAS;
5059 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5060 "noQas due to Capabilities=%x\n",
5061 ioc->name, pPP0->Capabilities));
5063 ioc->spi_data.maxBusWidth = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_WIDE ? 1 : 0;
5064 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MAX_SYNC_OFFSET_MASK;
5066 ioc->spi_data.maxSyncOffset = (u8) (data >> 16);
5067 data = pPP0->Capabilities & MPI_SCSIPORTPAGE0_CAP_MIN_SYNC_PERIOD_MASK;
5068 ioc->spi_data.minSyncFactor = (u8) (data >> 8);
5069 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5070 "PortPage0 minSyncFactor=%x\n",
5071 ioc->name, ioc->spi_data.minSyncFactor));
5073 ioc->spi_data.maxSyncOffset = 0;
5074 ioc->spi_data.minSyncFactor = MPT_ASYNC;
5077 ioc->spi_data.busType = pPP0->PhysicalInterface & MPI_SCSIPORTPAGE0_PHY_SIGNAL_TYPE_MASK;
5079 /* Update the minSyncFactor based on bus type.
5081 if ((ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_HVD) ||
5082 (ioc->spi_data.busType == MPI_SCSIPORTPAGE0_PHY_SIGNAL_SE)) {
5084 if (ioc->spi_data.minSyncFactor < MPT_ULTRA) {
5085 ioc->spi_data.minSyncFactor = MPT_ULTRA;
5086 ddvprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5087 "HVD or SE detected, minSyncFactor=%x\n",
5088 ioc->name, ioc->spi_data.minSyncFactor));
5093 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5098 /* SCSI Port Page 2 - Read the header then the page.
5100 header.PageVersion = 0;
5101 header.PageLength = 0;
5102 header.PageNumber = 2;
5103 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_PORT;
5104 cfg.cfghdr.hdr = &header;
5106 cfg.pageAddr = portnum;
5107 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5109 if (mpt_config(ioc, &cfg) != 0)
5112 if (header.PageLength > 0) {
5113 /* Allocate memory and read SCSI Port Page 2
5115 pbuf = pci_alloc_consistent(ioc->pcidev, header.PageLength * 4, &buf_dma);
5117 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_NVRAM;
5118 cfg.physAddr = buf_dma;
5119 if (mpt_config(ioc, &cfg) != 0) {
5120 /* Nvram data is left with INVALID mark
5123 } else if (ioc->pcidev->vendor == PCI_VENDOR_ID_ATTO) {
5125 /* This is an ATTO adapter, read Page2 accordingly
5127 ATTO_SCSIPortPage2_t *pPP2 = (ATTO_SCSIPortPage2_t *) pbuf;
5128 ATTODeviceInfo_t *pdevice = NULL;
5131 /* Save the Port Page 2 data
5132 * (reformat into a 32bit quantity)
5134 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5135 pdevice = &pPP2->DeviceSettings[ii];
5136 ATTOFlags = le16_to_cpu(pdevice->ATTOFlags);
5139 /* Translate ATTO device flags to LSI format
5141 if (ATTOFlags & ATTOFLAG_DISC)
5142 data |= (MPI_SCSIPORTPAGE2_DEVICE_DISCONNECT_ENABLE);
5143 if (ATTOFlags & ATTOFLAG_ID_ENB)
5144 data |= (MPI_SCSIPORTPAGE2_DEVICE_ID_SCAN_ENABLE);
5145 if (ATTOFlags & ATTOFLAG_LUN_ENB)
5146 data |= (MPI_SCSIPORTPAGE2_DEVICE_LUN_SCAN_ENABLE);
5147 if (ATTOFlags & ATTOFLAG_TAGGED)
5148 data |= (MPI_SCSIPORTPAGE2_DEVICE_TAG_QUEUE_ENABLE);
5149 if (!(ATTOFlags & ATTOFLAG_WIDE_ENB))
5150 data |= (MPI_SCSIPORTPAGE2_DEVICE_WIDE_DISABLE);
5152 data = (data << 16) | (pdevice->Period << 8) | 10;
5153 ioc->spi_data.nvram[ii] = data;
5156 SCSIPortPage2_t *pPP2 = (SCSIPortPage2_t *) pbuf;
5157 MpiDeviceInfo_t *pdevice = NULL;
5160 * Save "Set to Avoid SCSI Bus Resets" flag
5162 ioc->spi_data.bus_reset =
5163 (le32_to_cpu(pPP2->PortFlags) &
5164 MPI_SCSIPORTPAGE2_PORT_FLAGS_AVOID_SCSI_RESET) ?
5167 /* Save the Port Page 2 data
5168 * (reformat into a 32bit quantity)
5170 data = le32_to_cpu(pPP2->PortFlags) & MPI_SCSIPORTPAGE2_PORT_FLAGS_DV_MASK;
5171 ioc->spi_data.PortFlags = data;
5172 for (ii=0; ii < MPT_MAX_SCSI_DEVICES; ii++) {
5173 pdevice = &pPP2->DeviceSettings[ii];
5174 data = (le16_to_cpu(pdevice->DeviceFlags) << 16) |
5175 (pdevice->SyncFactor << 8) | pdevice->Timeout;
5176 ioc->spi_data.nvram[ii] = data;
5180 pci_free_consistent(ioc->pcidev, header.PageLength * 4, pbuf, buf_dma);
5184 /* Update Adapter limits with those from NVRAM
5185 * Comment: Don't need to do this. Target performance
5186 * parameters will never exceed the adapters limits.
5192 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5194 * mpt_readScsiDevicePageHeaders - save version and length of SDP1
5195 * @ioc: Pointer to a Adapter Strucutre
5196 * @portnum: IOC port number
5198 * Return: -EFAULT if read of config page header fails
5202 mpt_readScsiDevicePageHeaders(MPT_ADAPTER *ioc, int portnum)
5205 ConfigPageHeader_t header;
5207 /* Read the SCSI Device Page 1 header
5209 header.PageVersion = 0;
5210 header.PageLength = 0;
5211 header.PageNumber = 1;
5212 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5213 cfg.cfghdr.hdr = &header;
5215 cfg.pageAddr = portnum;
5216 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5219 if (mpt_config(ioc, &cfg) != 0)
5222 ioc->spi_data.sdp1version = cfg.cfghdr.hdr->PageVersion;
5223 ioc->spi_data.sdp1length = cfg.cfghdr.hdr->PageLength;
5225 header.PageVersion = 0;
5226 header.PageLength = 0;
5227 header.PageNumber = 0;
5228 header.PageType = MPI_CONFIG_PAGETYPE_SCSI_DEVICE;
5229 if (mpt_config(ioc, &cfg) != 0)
5232 ioc->spi_data.sdp0version = cfg.cfghdr.hdr->PageVersion;
5233 ioc->spi_data.sdp0length = cfg.cfghdr.hdr->PageLength;
5235 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 0: version %d length %d\n",
5236 ioc->name, ioc->spi_data.sdp0version, ioc->spi_data.sdp0length));
5238 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Headers: 1: version %d length %d\n",
5239 ioc->name, ioc->spi_data.sdp1version, ioc->spi_data.sdp1length));
5244 * mpt_inactive_raid_list_free - This clears this link list.
5245 * @ioc : pointer to per adapter structure
5248 mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
5250 struct inactive_raid_component_info *component_info, *pNext;
5252 if (list_empty(&ioc->raid_data.inactive_list))
5255 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5256 list_for_each_entry_safe(component_info, pNext,
5257 &ioc->raid_data.inactive_list, list) {
5258 list_del(&component_info->list);
5259 kfree(component_info);
5261 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5265 * mpt_inactive_raid_volumes - sets up link list of phy_disk_nums for devices belonging in an inactive volume
5267 * @ioc : pointer to per adapter structure
5268 * @channel : volume channel
5269 * @id : volume target id
5272 mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
5275 ConfigPageHeader_t hdr;
5276 dma_addr_t dma_handle;
5277 pRaidVolumePage0_t buffer = NULL;
5279 RaidPhysDiskPage0_t phys_disk;
5280 struct inactive_raid_component_info *component_info;
5281 int handle_inactive_volumes;
5283 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5284 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5285 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_VOLUME;
5286 cfg.pageAddr = (channel << 8) + id;
5287 cfg.cfghdr.hdr = &hdr;
5288 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5290 if (mpt_config(ioc, &cfg) != 0)
5293 if (!hdr.PageLength)
5296 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5302 cfg.physAddr = dma_handle;
5303 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5305 if (mpt_config(ioc, &cfg) != 0)
5308 if (!buffer->NumPhysDisks)
5311 handle_inactive_volumes =
5312 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_VOLUME_INACTIVE ||
5313 (buffer->VolumeStatus.Flags & MPI_RAIDVOL0_STATUS_FLAG_ENABLED) == 0 ||
5314 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_FAILED ||
5315 buffer->VolumeStatus.State == MPI_RAIDVOL0_STATUS_STATE_MISSING) ? 1 : 0;
5317 if (!handle_inactive_volumes)
5320 mutex_lock(&ioc->raid_data.inactive_list_mutex);
5321 for (i = 0; i < buffer->NumPhysDisks; i++) {
5322 if(mpt_raid_phys_disk_pg0(ioc,
5323 buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
5326 if ((component_info = kmalloc(sizeof (*component_info),
5327 GFP_KERNEL)) == NULL)
5330 component_info->volumeID = id;
5331 component_info->volumeBus = channel;
5332 component_info->d.PhysDiskNum = phys_disk.PhysDiskNum;
5333 component_info->d.PhysDiskBus = phys_disk.PhysDiskBus;
5334 component_info->d.PhysDiskID = phys_disk.PhysDiskID;
5335 component_info->d.PhysDiskIOC = phys_disk.PhysDiskIOC;
5337 list_add_tail(&component_info->list,
5338 &ioc->raid_data.inactive_list);
5340 mutex_unlock(&ioc->raid_data.inactive_list_mutex);
5344 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5349 * mpt_raid_phys_disk_pg0 - returns phys disk page zero
5350 * @ioc: Pointer to a Adapter Structure
5351 * @phys_disk_num: io unit unique phys disk num generated by the ioc
5352 * @phys_disk: requested payload data returned
5356 * -EFAULT if read of config page header fails or data pointer not NULL
5357 * -ENOMEM if pci_alloc failed
5360 mpt_raid_phys_disk_pg0(MPT_ADAPTER *ioc, u8 phys_disk_num, pRaidPhysDiskPage0_t phys_disk)
5363 ConfigPageHeader_t hdr;
5364 dma_addr_t dma_handle;
5365 pRaidPhysDiskPage0_t buffer = NULL;
5368 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5369 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5371 hdr.PageType = MPI_CONFIG_PAGETYPE_RAID_PHYSDISK;
5372 cfg.cfghdr.hdr = &hdr;
5374 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5376 if (mpt_config(ioc, &cfg) != 0) {
5381 if (!hdr.PageLength) {
5386 buffer = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4,
5394 cfg.physAddr = dma_handle;
5395 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5396 cfg.pageAddr = phys_disk_num;
5398 if (mpt_config(ioc, &cfg) != 0) {
5404 memcpy(phys_disk, buffer, sizeof(*buffer));
5405 phys_disk->MaxLBA = le32_to_cpu(buffer->MaxLBA);
5410 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, buffer,
5417 * mpt_findImVolumes - Identify IDs of hidden disks and RAID Volumes
5418 * @ioc: Pointer to a Adapter Strucutre
5419 * @portnum: IOC port number
5423 * -EFAULT if read of config page header fails or data pointer not NULL
5424 * -ENOMEM if pci_alloc failed
5427 mpt_findImVolumes(MPT_ADAPTER *ioc)
5431 dma_addr_t ioc2_dma;
5433 ConfigPageHeader_t header;
5438 if (!ioc->ir_firmware)
5441 /* Free the old page
5443 kfree(ioc->raid_data.pIocPg2);
5444 ioc->raid_data.pIocPg2 = NULL;
5445 mpt_inactive_raid_list_free(ioc);
5447 /* Read IOCP2 header then the page.
5449 header.PageVersion = 0;
5450 header.PageLength = 0;
5451 header.PageNumber = 2;
5452 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5453 cfg.cfghdr.hdr = &header;
5456 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5459 if (mpt_config(ioc, &cfg) != 0)
5462 if (header.PageLength == 0)
5465 iocpage2sz = header.PageLength * 4;
5466 pIoc2 = pci_alloc_consistent(ioc->pcidev, iocpage2sz, &ioc2_dma);
5470 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5471 cfg.physAddr = ioc2_dma;
5472 if (mpt_config(ioc, &cfg) != 0)
5475 mem = kmalloc(iocpage2sz, GFP_KERNEL);
5479 memcpy(mem, (u8 *)pIoc2, iocpage2sz);
5480 ioc->raid_data.pIocPg2 = (IOCPage2_t *) mem;
5482 mpt_read_ioc_pg_3(ioc);
5484 for (i = 0; i < pIoc2->NumActiveVolumes ; i++)
5485 mpt_inactive_raid_volumes(ioc,
5486 pIoc2->RaidVolume[i].VolumeBus,
5487 pIoc2->RaidVolume[i].VolumeID);
5490 pci_free_consistent(ioc->pcidev, iocpage2sz, pIoc2, ioc2_dma);
5496 mpt_read_ioc_pg_3(MPT_ADAPTER *ioc)
5501 ConfigPageHeader_t header;
5502 dma_addr_t ioc3_dma;
5505 /* Free the old page
5507 kfree(ioc->raid_data.pIocPg3);
5508 ioc->raid_data.pIocPg3 = NULL;
5510 /* There is at least one physical disk.
5511 * Read and save IOC Page 3
5513 header.PageVersion = 0;
5514 header.PageLength = 0;
5515 header.PageNumber = 3;
5516 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5517 cfg.cfghdr.hdr = &header;
5520 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5523 if (mpt_config(ioc, &cfg) != 0)
5526 if (header.PageLength == 0)
5529 /* Read Header good, alloc memory
5531 iocpage3sz = header.PageLength * 4;
5532 pIoc3 = pci_alloc_consistent(ioc->pcidev, iocpage3sz, &ioc3_dma);
5536 /* Read the Page and save the data
5537 * into malloc'd memory.
5539 cfg.physAddr = ioc3_dma;
5540 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5541 if (mpt_config(ioc, &cfg) == 0) {
5542 mem = kmalloc(iocpage3sz, GFP_KERNEL);
5544 memcpy(mem, (u8 *)pIoc3, iocpage3sz);
5545 ioc->raid_data.pIocPg3 = (IOCPage3_t *) mem;
5549 pci_free_consistent(ioc->pcidev, iocpage3sz, pIoc3, ioc3_dma);
5555 mpt_read_ioc_pg_4(MPT_ADAPTER *ioc)
5559 ConfigPageHeader_t header;
5560 dma_addr_t ioc4_dma;
5563 /* Read and save IOC Page 4
5565 header.PageVersion = 0;
5566 header.PageLength = 0;
5567 header.PageNumber = 4;
5568 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5569 cfg.cfghdr.hdr = &header;
5572 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5575 if (mpt_config(ioc, &cfg) != 0)
5578 if (header.PageLength == 0)
5581 if ( (pIoc4 = ioc->spi_data.pIocPg4) == NULL ) {
5582 iocpage4sz = (header.PageLength + 4) * 4; /* Allow 4 additional SEP's */
5583 pIoc4 = pci_alloc_consistent(ioc->pcidev, iocpage4sz, &ioc4_dma);
5586 ioc->alloc_total += iocpage4sz;
5588 ioc4_dma = ioc->spi_data.IocPg4_dma;
5589 iocpage4sz = ioc->spi_data.IocPg4Sz;
5592 /* Read the Page into dma memory.
5594 cfg.physAddr = ioc4_dma;
5595 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5596 if (mpt_config(ioc, &cfg) == 0) {
5597 ioc->spi_data.pIocPg4 = (IOCPage4_t *) pIoc4;
5598 ioc->spi_data.IocPg4_dma = ioc4_dma;
5599 ioc->spi_data.IocPg4Sz = iocpage4sz;
5601 pci_free_consistent(ioc->pcidev, iocpage4sz, pIoc4, ioc4_dma);
5602 ioc->spi_data.pIocPg4 = NULL;
5603 ioc->alloc_total -= iocpage4sz;
5608 mpt_read_ioc_pg_1(MPT_ADAPTER *ioc)
5612 ConfigPageHeader_t header;
5613 dma_addr_t ioc1_dma;
5617 /* Check the Coalescing Timeout in IOC Page 1
5619 header.PageVersion = 0;
5620 header.PageLength = 0;
5621 header.PageNumber = 1;
5622 header.PageType = MPI_CONFIG_PAGETYPE_IOC;
5623 cfg.cfghdr.hdr = &header;
5626 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5629 if (mpt_config(ioc, &cfg) != 0)
5632 if (header.PageLength == 0)
5635 /* Read Header good, alloc memory
5637 iocpage1sz = header.PageLength * 4;
5638 pIoc1 = pci_alloc_consistent(ioc->pcidev, iocpage1sz, &ioc1_dma);
5642 /* Read the Page and check coalescing timeout
5644 cfg.physAddr = ioc1_dma;
5645 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5646 if (mpt_config(ioc, &cfg) == 0) {
5648 tmp = le32_to_cpu(pIoc1->Flags) & MPI_IOCPAGE1_REPLY_COALESCING;
5649 if (tmp == MPI_IOCPAGE1_REPLY_COALESCING) {
5650 tmp = le32_to_cpu(pIoc1->CoalescingTimeout);
5652 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Coalescing Enabled Timeout = %d\n",
5655 if (tmp > MPT_COALESCING_TIMEOUT) {
5656 pIoc1->CoalescingTimeout = cpu_to_le32(MPT_COALESCING_TIMEOUT);
5658 /* Write NVRAM and current
5661 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_CURRENT;
5662 if (mpt_config(ioc, &cfg) == 0) {
5663 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Reset Current Coalescing Timeout to = %d\n",
5664 ioc->name, MPT_COALESCING_TIMEOUT));
5666 cfg.action = MPI_CONFIG_ACTION_PAGE_WRITE_NVRAM;
5667 if (mpt_config(ioc, &cfg) == 0) {
5668 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5669 "Reset NVRAM Coalescing Timeout to = %d\n",
5670 ioc->name, MPT_COALESCING_TIMEOUT));
5672 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5673 "Reset NVRAM Coalescing Timeout Failed\n",
5678 dprintk(ioc, printk(MYIOC_s_WARN_FMT
5679 "Reset of Current Coalescing Timeout Failed!\n",
5685 dprintk(ioc, printk(MYIOC_s_WARN_FMT "Coalescing Disabled\n", ioc->name));
5689 pci_free_consistent(ioc->pcidev, iocpage1sz, pIoc1, ioc1_dma);
5695 mpt_get_manufacturing_pg_0(MPT_ADAPTER *ioc)
5698 ConfigPageHeader_t hdr;
5700 ManufacturingPage0_t *pbuf = NULL;
5702 memset(&cfg, 0 , sizeof(CONFIGPARMS));
5703 memset(&hdr, 0 , sizeof(ConfigPageHeader_t));
5705 hdr.PageType = MPI_CONFIG_PAGETYPE_MANUFACTURING;
5706 cfg.cfghdr.hdr = &hdr;
5708 cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER;
5711 if (mpt_config(ioc, &cfg) != 0)
5714 if (!cfg.cfghdr.hdr->PageLength)
5717 cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT;
5718 pbuf = pci_alloc_consistent(ioc->pcidev, hdr.PageLength * 4, &buf_dma);
5722 cfg.physAddr = buf_dma;
5724 if (mpt_config(ioc, &cfg) != 0)
5727 memcpy(ioc->board_name, pbuf->BoardName, sizeof(ioc->board_name));
5728 memcpy(ioc->board_assembly, pbuf->BoardAssembly, sizeof(ioc->board_assembly));
5729 memcpy(ioc->board_tracer, pbuf->BoardTracerNumber, sizeof(ioc->board_tracer));
5734 pci_free_consistent(ioc->pcidev, hdr.PageLength * 4, pbuf, buf_dma);
5737 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5739 * SendEventNotification - Send EventNotification (on or off) request to adapter
5740 * @ioc: Pointer to MPT_ADAPTER structure
5741 * @EvSwitch: Event switch flags
5744 SendEventNotification(MPT_ADAPTER *ioc, u8 EvSwitch)
5746 EventNotification_t *evnp;
5748 evnp = (EventNotification_t *) mpt_get_msg_frame(mpt_base_index, ioc);
5750 devtverboseprintk(ioc, printk(MYIOC_s_WARN_FMT "Unable to allocate event request frame!\n",
5754 memset(evnp, 0, sizeof(*evnp));
5756 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventNotification (%d) request %p\n", ioc->name, EvSwitch, evnp));
5758 evnp->Function = MPI_FUNCTION_EVENT_NOTIFICATION;
5759 evnp->ChainOffset = 0;
5761 evnp->Switch = EvSwitch;
5763 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)evnp);
5768 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5770 * SendEventAck - Send EventAck request to MPT adapter.
5771 * @ioc: Pointer to MPT_ADAPTER structure
5772 * @evnp: Pointer to original EventNotification request
5775 SendEventAck(MPT_ADAPTER *ioc, EventNotificationReply_t *evnp)
5779 if ((pAck = (EventAck_t *) mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5780 dfailprintk(ioc, printk(MYIOC_s_WARN_FMT "%s, no msg frames!!\n",
5781 ioc->name,__FUNCTION__));
5785 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending EventAck\n", ioc->name));
5787 pAck->Function = MPI_FUNCTION_EVENT_ACK;
5788 pAck->ChainOffset = 0;
5789 pAck->Reserved[0] = pAck->Reserved[1] = 0;
5791 pAck->Reserved1[0] = pAck->Reserved1[1] = pAck->Reserved1[2] = 0;
5792 pAck->Event = evnp->Event;
5793 pAck->EventContext = evnp->EventContext;
5795 mpt_put_msg_frame(mpt_base_index, ioc, (MPT_FRAME_HDR *)pAck);
5800 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5802 * mpt_config - Generic function to issue config message
5803 * @ioc: Pointer to an adapter structure
5804 * @pCfg: Pointer to a configuration structure. Struct contains
5805 * action, page address, direction, physical address
5806 * and pointer to a configuration page header
5807 * Page header is updated.
5809 * Returns 0 for success
5810 * -EPERM if not allowed due to ISR context
5811 * -EAGAIN if no msg frames currently available
5812 * -EFAULT for non-successful reply or no reply (timeout)
5815 mpt_config(MPT_ADAPTER *ioc, CONFIGPARMS *pCfg)
5818 ConfigExtendedPageHeader_t *pExtHdr = NULL;
5820 unsigned long flags;
5825 /* Prevent calling wait_event() (below), if caller happens
5826 * to be in ISR context, because that is fatal!
5828 in_isr = in_interrupt();
5830 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "Config request not allowed in ISR context!\n",
5835 /* Get and Populate a free Frame
5837 if ((mf = mpt_get_msg_frame(mpt_base_index, ioc)) == NULL) {
5838 dcprintk(ioc, printk(MYIOC_s_WARN_FMT "mpt_config: no msg frames!\n",
5842 pReq = (Config_t *)mf;
5843 pReq->Action = pCfg->action;
5845 pReq->ChainOffset = 0;
5846 pReq->Function = MPI_FUNCTION_CONFIG;
5848 /* Assume page type is not extended and clear "reserved" fields. */
5849 pReq->ExtPageLength = 0;
5850 pReq->ExtPageType = 0;
5853 for (ii=0; ii < 8; ii++)
5854 pReq->Reserved2[ii] = 0;
5856 pReq->Header.PageVersion = pCfg->cfghdr.hdr->PageVersion;
5857 pReq->Header.PageLength = pCfg->cfghdr.hdr->PageLength;
5858 pReq->Header.PageNumber = pCfg->cfghdr.hdr->PageNumber;
5859 pReq->Header.PageType = (pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK);
5861 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5862 pExtHdr = (ConfigExtendedPageHeader_t *)pCfg->cfghdr.ehdr;
5863 pReq->ExtPageLength = cpu_to_le16(pExtHdr->ExtPageLength);
5864 pReq->ExtPageType = pExtHdr->ExtPageType;
5865 pReq->Header.PageType = MPI_CONFIG_PAGETYPE_EXTENDED;
5867 /* Page Length must be treated as a reserved field for the extended header. */
5868 pReq->Header.PageLength = 0;
5871 pReq->PageAddress = cpu_to_le32(pCfg->pageAddr);
5873 /* Add a SGE to the config request.
5876 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
5878 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
5880 if ((pCfg->cfghdr.hdr->PageType & MPI_CONFIG_PAGETYPE_MASK) == MPI_CONFIG_PAGETYPE_EXTENDED) {
5881 flagsLength |= pExtHdr->ExtPageLength * 4;
5883 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5884 ioc->name, pReq->ExtPageType, pReq->Header.PageNumber, pReq->Action));
5887 flagsLength |= pCfg->cfghdr.hdr->PageLength * 4;
5889 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Sending Config request type %d, page %d and action %d\n",
5890 ioc->name, pReq->Header.PageType, pReq->Header.PageNumber, pReq->Action));
5893 mpt_add_sge((char *)&pReq->PageBufferSGE, flagsLength, pCfg->physAddr);
5895 /* Append pCfg pointer to end of mf
5897 *((void **) (((u8 *) mf) + (ioc->req_sz - sizeof(void *)))) = (void *) pCfg;
5899 /* Initalize the timer
5901 init_timer(&pCfg->timer);
5902 pCfg->timer.data = (unsigned long) ioc;
5903 pCfg->timer.function = mpt_timer_expired;
5904 pCfg->wait_done = 0;
5906 /* Set the timer; ensure 10 second minimum */
5907 if (pCfg->timeout < 10)
5908 pCfg->timer.expires = jiffies + HZ*10;
5910 pCfg->timer.expires = jiffies + HZ*pCfg->timeout;
5912 /* Add to end of Q, set timer and then issue this command */
5913 spin_lock_irqsave(&ioc->FreeQlock, flags);
5914 list_add_tail(&pCfg->linkage, &ioc->configQ);
5915 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5917 add_timer(&pCfg->timer);
5918 mpt_put_msg_frame(mpt_base_index, ioc, mf);
5919 wait_event(mpt_waitq, pCfg->wait_done);
5921 /* mf has been freed - do not access */
5928 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5930 * mpt_timer_expired - Callback for timer process.
5931 * Used only internal config functionality.
5932 * @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
5935 mpt_timer_expired(unsigned long data)
5937 MPT_ADAPTER *ioc = (MPT_ADAPTER *) data;
5939 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired! \n", ioc->name));
5941 /* Perform a FW reload */
5942 if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
5943 printk(MYIOC_s_WARN_FMT "Firmware Reload FAILED!\n", ioc->name);
5945 /* No more processing.
5946 * Hard reset clean-up will wake up
5947 * process and free all resources.
5949 dcprintk(ioc, printk(MYIOC_s_DEBUG_FMT "mpt_timer_expired complete!\n", ioc->name));
5954 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
5956 * mpt_ioc_reset - Base cleanup for hard reset
5957 * @ioc: Pointer to the adapter structure
5958 * @reset_phase: Indicates pre- or post-reset functionality
5960 * Remark: Frees resources with internally generated commands.
5963 mpt_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
5966 unsigned long flags;
5968 dprintk(ioc, printk(MYIOC_s_DEBUG_FMT
5969 ": IOC %s_reset routed to MPT base driver!\n",
5970 ioc->name, reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
5971 reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
5973 if (reset_phase == MPT_IOC_SETUP_RESET) {
5975 } else if (reset_phase == MPT_IOC_PRE_RESET) {
5976 /* If the internal config Q is not empty -
5977 * delete timer. MF resources will be freed when
5978 * the FIFO's are primed.
5980 spin_lock_irqsave(&ioc->FreeQlock, flags);
5981 list_for_each_entry(pCfg, &ioc->configQ, linkage)
5982 del_timer(&pCfg->timer);
5983 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
5988 /* Search the configQ for internal commands.
5989 * Flush the Q, and wake up all suspended threads.
5991 spin_lock_irqsave(&ioc->FreeQlock, flags);
5992 list_for_each_entry_safe(pCfg, pNext, &ioc->configQ, linkage) {
5993 list_del(&pCfg->linkage);
5995 pCfg->status = MPT_CONFIG_ERROR;
5996 pCfg->wait_done = 1;
5997 wake_up(&mpt_waitq);
5999 spin_unlock_irqrestore(&ioc->FreeQlock, flags);
6002 return 1; /* currently means nothing really */
6006 #ifdef CONFIG_PROC_FS /* { */
6007 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6009 * procfs (%MPT_PROCFS_MPTBASEDIR/...) support stuff...
6011 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6013 * procmpt_create - Create %MPT_PROCFS_MPTBASEDIR entries.
6015 * Returns 0 for success, non-zero for failure.
6018 procmpt_create(void)
6020 struct proc_dir_entry *ent;
6022 mpt_proc_root_dir = proc_mkdir(MPT_PROCFS_MPTBASEDIR, NULL);
6023 if (mpt_proc_root_dir == NULL)
6026 ent = create_proc_entry("summary", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6028 ent->read_proc = procmpt_summary_read;
6030 ent = create_proc_entry("version", S_IFREG|S_IRUGO, mpt_proc_root_dir);
6032 ent->read_proc = procmpt_version_read;
6037 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6039 * procmpt_destroy - Tear down %MPT_PROCFS_MPTBASEDIR entries.
6041 * Returns 0 for success, non-zero for failure.
6044 procmpt_destroy(void)
6046 remove_proc_entry("version", mpt_proc_root_dir);
6047 remove_proc_entry("summary", mpt_proc_root_dir);
6048 remove_proc_entry(MPT_PROCFS_MPTBASEDIR, NULL);
6051 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6053 * procmpt_summary_read - Handle read request of a summary file
6054 * @buf: Pointer to area to write information
6055 * @start: Pointer to start pointer
6056 * @offset: Offset to start writing
6057 * @request: Amount of read data requested
6058 * @eof: Pointer to EOF integer
6061 * Handles read request from /proc/mpt/summary or /proc/mpt/iocN/summary.
6062 * Returns number of characters written to process performing the read.
6065 procmpt_summary_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6075 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6079 list_for_each_entry(ioc, &ioc_list, list) {
6082 mpt_print_ioc_summary(ioc, out, &more, 0, 1);
6085 if ((out-buf) >= request)
6092 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6095 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6097 * procmpt_version_read - Handle read request from /proc/mpt/version.
6098 * @buf: Pointer to area to write information
6099 * @start: Pointer to start pointer
6100 * @offset: Offset to start writing
6101 * @request: Amount of read data requested
6102 * @eof: Pointer to EOF integer
6105 * Returns number of characters written to process performing the read.
6108 procmpt_version_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6111 int scsi, fc, sas, lan, ctl, targ, dmp;
6115 len = sprintf(buf, "%s-%s\n", "mptlinux", MPT_LINUX_VERSION_COMMON);
6116 len += sprintf(buf+len, " Fusion MPT base driver\n");
6118 scsi = fc = sas = lan = ctl = targ = dmp = 0;
6119 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6121 if (MptCallbacks[cb_idx]) {
6122 switch (MptDriverClass[cb_idx]) {
6124 if (!scsi++) drvname = "SPI host";
6127 if (!fc++) drvname = "FC host";
6130 if (!sas++) drvname = "SAS host";
6133 if (!lan++) drvname = "LAN";
6136 if (!targ++) drvname = "SCSI target";
6139 if (!ctl++) drvname = "ioctl";
6144 len += sprintf(buf+len, " Fusion MPT %s driver\n", drvname);
6148 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6151 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6153 * procmpt_iocinfo_read - Handle read request from /proc/mpt/iocN/info.
6154 * @buf: Pointer to area to write information
6155 * @start: Pointer to start pointer
6156 * @offset: Offset to start writing
6157 * @request: Amount of read data requested
6158 * @eof: Pointer to EOF integer
6161 * Returns number of characters written to process performing the read.
6164 procmpt_iocinfo_read(char *buf, char **start, off_t offset, int request, int *eof, void *data)
6166 MPT_ADAPTER *ioc = data;
6172 mpt_get_fw_exp_ver(expVer, ioc);
6174 len = sprintf(buf, "%s:", ioc->name);
6175 if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)
6176 len += sprintf(buf+len, " (f/w download boot flag set)");
6177 // if (ioc->facts.IOCExceptions & MPI_IOCFACTS_EXCEPT_CONFIG_CHECKSUM_FAIL)
6178 // len += sprintf(buf+len, " CONFIG_CHECKSUM_FAIL!");
6180 len += sprintf(buf+len, "\n ProductID = 0x%04x (%s)\n",
6181 ioc->facts.ProductID,
6183 len += sprintf(buf+len, " FWVersion = 0x%08x%s", ioc->facts.FWVersion.Word, expVer);
6184 if (ioc->facts.FWImageSize)
6185 len += sprintf(buf+len, " (fw_size=%d)", ioc->facts.FWImageSize);
6186 len += sprintf(buf+len, "\n MsgVersion = 0x%04x\n", ioc->facts.MsgVersion);
6187 len += sprintf(buf+len, " FirstWhoInit = 0x%02x\n", ioc->FirstWhoInit);
6188 len += sprintf(buf+len, " EventState = 0x%02x\n", ioc->facts.EventState);
6190 len += sprintf(buf+len, " CurrentHostMfaHighAddr = 0x%08x\n",
6191 ioc->facts.CurrentHostMfaHighAddr);
6192 len += sprintf(buf+len, " CurrentSenseBufferHighAddr = 0x%08x\n",
6193 ioc->facts.CurrentSenseBufferHighAddr);
6195 len += sprintf(buf+len, " MaxChainDepth = 0x%02x frames\n", ioc->facts.MaxChainDepth);
6196 len += sprintf(buf+len, " MinBlockSize = 0x%02x bytes\n", 4*ioc->facts.BlockSize);
6198 len += sprintf(buf+len, " RequestFrames @ 0x%p (Dma @ 0x%p)\n",
6199 (void *)ioc->req_frames, (void *)(ulong)ioc->req_frames_dma);
6201 * Rounding UP to nearest 4-kB boundary here...
6203 sz = (ioc->req_sz * ioc->req_depth) + 128;
6204 sz = ((sz + 0x1000UL - 1UL) / 0x1000) * 0x1000;
6205 len += sprintf(buf+len, " {CurReqSz=%d} x {CurReqDepth=%d} = %d bytes ^= 0x%x\n",
6206 ioc->req_sz, ioc->req_depth, ioc->req_sz*ioc->req_depth, sz);
6207 len += sprintf(buf+len, " {MaxReqSz=%d} {MaxReqDepth=%d}\n",
6208 4*ioc->facts.RequestFrameSize,
6209 ioc->facts.GlobalCredits);
6211 len += sprintf(buf+len, " Frames @ 0x%p (Dma @ 0x%p)\n",
6212 (void *)ioc->alloc, (void *)(ulong)ioc->alloc_dma);
6213 sz = (ioc->reply_sz * ioc->reply_depth) + 128;
6214 len += sprintf(buf+len, " {CurRepSz=%d} x {CurRepDepth=%d} = %d bytes ^= 0x%x\n",
6215 ioc->reply_sz, ioc->reply_depth, ioc->reply_sz*ioc->reply_depth, sz);
6216 len += sprintf(buf+len, " {MaxRepSz=%d} {MaxRepDepth=%d}\n",
6217 ioc->facts.CurReplyFrameSize,
6218 ioc->facts.ReplyQueueDepth);
6220 len += sprintf(buf+len, " MaxDevices = %d\n",
6221 (ioc->facts.MaxDevices==0) ? 255 : ioc->facts.MaxDevices);
6222 len += sprintf(buf+len, " MaxBuses = %d\n", ioc->facts.MaxBuses);
6225 for (p=0; p < ioc->facts.NumberOfPorts; p++) {
6226 len += sprintf(buf+len, " PortNumber = %d (of %d)\n",
6228 ioc->facts.NumberOfPorts);
6229 if (ioc->bus_type == FC) {
6230 if (ioc->pfacts[p].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) {
6231 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6232 len += sprintf(buf+len, " LanAddr = %02X:%02X:%02X:%02X:%02X:%02X\n",
6233 a[5], a[4], a[3], a[2], a[1], a[0]);
6235 len += sprintf(buf+len, " WWN = %08X%08X:%08X%08X\n",
6236 ioc->fc_port_page0[p].WWNN.High,
6237 ioc->fc_port_page0[p].WWNN.Low,
6238 ioc->fc_port_page0[p].WWPN.High,
6239 ioc->fc_port_page0[p].WWPN.Low);
6243 MPT_PROC_READ_RETURN(buf,start,offset,request,eof,len);
6246 #endif /* CONFIG_PROC_FS } */
6248 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6250 mpt_get_fw_exp_ver(char *buf, MPT_ADAPTER *ioc)
6253 if ((ioc->facts.FWVersion.Word >> 24) == 0x0E) {
6254 sprintf(buf, " (Exp %02d%02d)",
6255 (ioc->facts.FWVersion.Word >> 16) & 0x00FF, /* Month */
6256 (ioc->facts.FWVersion.Word >> 8) & 0x1F); /* Day */
6259 if ((ioc->facts.FWVersion.Word >> 8) & 0x80)
6260 strcat(buf, " [MDBG]");
6264 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6266 * mpt_print_ioc_summary - Write ASCII summary of IOC to a buffer.
6267 * @ioc: Pointer to MPT_ADAPTER structure
6268 * @buffer: Pointer to buffer where IOC summary info should be written
6269 * @size: Pointer to number of bytes we wrote (set by this routine)
6270 * @len: Offset at which to start writing in buffer
6271 * @showlan: Display LAN stuff?
6273 * This routine writes (english readable) ASCII text, which represents
6274 * a summary of IOC information, to a buffer.
6277 mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int showlan)
6282 mpt_get_fw_exp_ver(expVer, ioc);
6285 * Shorter summary of attached ioc's...
6287 y = sprintf(buffer+len, "%s: %s, %s%08xh%s, Ports=%d, MaxQ=%d",
6290 MPT_FW_REV_MAGIC_ID_STRING, /* "FwRev=" or somesuch */
6291 ioc->facts.FWVersion.Word,
6293 ioc->facts.NumberOfPorts,
6296 if (showlan && (ioc->pfacts[0].ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN)) {
6297 u8 *a = (u8*)&ioc->lan_cnfg_page1.HardwareAddressLow;
6298 y += sprintf(buffer+len+y, ", LanAddr=%02X:%02X:%02X:%02X:%02X:%02X",
6299 a[5], a[4], a[3], a[2], a[1], a[0]);
6302 y += sprintf(buffer+len+y, ", IRQ=%d", ioc->pci_irq);
6305 y += sprintf(buffer+len+y, " (disabled)");
6307 y += sprintf(buffer+len+y, "\n");
6312 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6316 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6318 * mpt_HardResetHandler - Generic reset handler
6319 * @ioc: Pointer to MPT_ADAPTER structure
6320 * @sleepFlag: Indicates if sleep or schedule must be called.
6322 * Issues SCSI Task Management call based on input arg values.
6323 * If TaskMgmt fails, returns associated SCSI request.
6325 * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
6326 * or a non-interrupt thread. In the former, must not call schedule().
6328 * Note: A return of -1 is a FATAL error case, as it means a
6329 * FW reload/initialization failed.
6331 * Returns 0 for SUCCESS or -1 if FAILED.
6334 mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)
6337 unsigned long flags;
6339 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler Entered!\n", ioc->name));
6341 printk(MYIOC_s_INFO_FMT "HardResetHandler Entered!\n", ioc->name);
6342 printk("MF count 0x%x !\n", ioc->mfcnt);
6345 /* Reset the adapter. Prevent more than 1 call to
6346 * mpt_do_ioc_recovery at any instant in time.
6348 spin_lock_irqsave(&ioc->diagLock, flags);
6349 if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){
6350 spin_unlock_irqrestore(&ioc->diagLock, flags);
6353 ioc->diagPending = 1;
6355 spin_unlock_irqrestore(&ioc->diagLock, flags);
6357 /* FIXME: If do_ioc_recovery fails, repeat....
6360 /* The SCSI driver needs to adjust timeouts on all current
6361 * commands prior to the diagnostic reset being issued.
6362 * Prevents timeouts occurring during a diagnostic reset...very bad.
6363 * For all other protocol drivers, this is a no-op.
6369 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6370 if (MptResetHandlers[cb_idx]) {
6371 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling IOC reset_setup handler #%d\n",
6372 ioc->name, cb_idx));
6373 r += mpt_signal_reset(cb_idx, ioc, MPT_IOC_SETUP_RESET);
6375 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling alt-%s setup reset handler #%d\n",
6376 ioc->name, ioc->alt_ioc->name, cb_idx));
6377 r += mpt_signal_reset(cb_idx, ioc->alt_ioc, MPT_IOC_SETUP_RESET);
6383 if ((rc = mpt_do_ioc_recovery(ioc, MPT_HOSTEVENT_IOC_RECOVER, sleepFlag)) != 0) {
6384 printk(MYIOC_s_WARN_FMT "Cannot recover rc = %d!\n", ioc->name, rc);
6388 ioc->alt_ioc->reload_fw = 0;
6390 spin_lock_irqsave(&ioc->diagLock, flags);
6391 ioc->diagPending = 0;
6393 ioc->alt_ioc->diagPending = 0;
6394 spin_unlock_irqrestore(&ioc->diagLock, flags);
6396 dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "HardResetHandler rc = %d!\n", ioc->name, rc));
6401 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6403 EventDescriptionStr(u8 event, u32 evData0, char *evStr)
6408 case MPI_EVENT_NONE:
6411 case MPI_EVENT_LOG_DATA:
6414 case MPI_EVENT_STATE_CHANGE:
6415 ds = "State Change";
6417 case MPI_EVENT_UNIT_ATTENTION:
6418 ds = "Unit Attention";
6420 case MPI_EVENT_IOC_BUS_RESET:
6421 ds = "IOC Bus Reset";
6423 case MPI_EVENT_EXT_BUS_RESET:
6424 ds = "External Bus Reset";
6426 case MPI_EVENT_RESCAN:
6427 ds = "Bus Rescan Event";
6429 case MPI_EVENT_LINK_STATUS_CHANGE:
6430 if (evData0 == MPI_EVENT_LINK_STATUS_FAILURE)
6431 ds = "Link Status(FAILURE) Change";
6433 ds = "Link Status(ACTIVE) Change";
6435 case MPI_EVENT_LOOP_STATE_CHANGE:
6436 if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LIP)
6437 ds = "Loop State(LIP) Change";
6438 else if (evData0 == MPI_EVENT_LOOP_STATE_CHANGE_LPE)
6439 ds = "Loop State(LPE) Change"; /* ??? */
6441 ds = "Loop State(LPB) Change"; /* ??? */
6443 case MPI_EVENT_LOGOUT:
6446 case MPI_EVENT_EVENT_CHANGE:
6452 case MPI_EVENT_INTEGRATED_RAID:
6454 u8 ReasonCode = (u8)(evData0 >> 16);
6455 switch (ReasonCode) {
6456 case MPI_EVENT_RAID_RC_VOLUME_CREATED :
6457 ds = "Integrated Raid: Volume Created";
6459 case MPI_EVENT_RAID_RC_VOLUME_DELETED :
6460 ds = "Integrated Raid: Volume Deleted";
6462 case MPI_EVENT_RAID_RC_VOLUME_SETTINGS_CHANGED :
6463 ds = "Integrated Raid: Volume Settings Changed";
6465 case MPI_EVENT_RAID_RC_VOLUME_STATUS_CHANGED :
6466 ds = "Integrated Raid: Volume Status Changed";
6468 case MPI_EVENT_RAID_RC_VOLUME_PHYSDISK_CHANGED :
6469 ds = "Integrated Raid: Volume Physdisk Changed";
6471 case MPI_EVENT_RAID_RC_PHYSDISK_CREATED :
6472 ds = "Integrated Raid: Physdisk Created";
6474 case MPI_EVENT_RAID_RC_PHYSDISK_DELETED :
6475 ds = "Integrated Raid: Physdisk Deleted";
6477 case MPI_EVENT_RAID_RC_PHYSDISK_SETTINGS_CHANGED :
6478 ds = "Integrated Raid: Physdisk Settings Changed";
6480 case MPI_EVENT_RAID_RC_PHYSDISK_STATUS_CHANGED :
6481 ds = "Integrated Raid: Physdisk Status Changed";
6483 case MPI_EVENT_RAID_RC_DOMAIN_VAL_NEEDED :
6484 ds = "Integrated Raid: Domain Validation Needed";
6486 case MPI_EVENT_RAID_RC_SMART_DATA :
6487 ds = "Integrated Raid; Smart Data";
6489 case MPI_EVENT_RAID_RC_REPLACE_ACTION_STARTED :
6490 ds = "Integrated Raid: Replace Action Started";
6493 ds = "Integrated Raid";
6498 case MPI_EVENT_SCSI_DEVICE_STATUS_CHANGE:
6499 ds = "SCSI Device Status Change";
6501 case MPI_EVENT_SAS_DEVICE_STATUS_CHANGE:
6503 u8 id = (u8)(evData0);
6504 u8 channel = (u8)(evData0 >> 8);
6505 u8 ReasonCode = (u8)(evData0 >> 16);
6506 switch (ReasonCode) {
6507 case MPI_EVENT_SAS_DEV_STAT_RC_ADDED:
6508 snprintf(evStr, EVENT_DESCR_STR_SZ,
6509 "SAS Device Status Change: Added: "
6510 "id=%d channel=%d", id, channel);
6512 case MPI_EVENT_SAS_DEV_STAT_RC_NOT_RESPONDING:
6513 snprintf(evStr, EVENT_DESCR_STR_SZ,
6514 "SAS Device Status Change: Deleted: "
6515 "id=%d channel=%d", id, channel);
6517 case MPI_EVENT_SAS_DEV_STAT_RC_SMART_DATA:
6518 snprintf(evStr, EVENT_DESCR_STR_SZ,
6519 "SAS Device Status Change: SMART Data: "
6520 "id=%d channel=%d", id, channel);
6522 case MPI_EVENT_SAS_DEV_STAT_RC_NO_PERSIST_ADDED:
6523 snprintf(evStr, EVENT_DESCR_STR_SZ,
6524 "SAS Device Status Change: No Persistancy: "
6525 "id=%d channel=%d", id, channel);
6527 case MPI_EVENT_SAS_DEV_STAT_RC_UNSUPPORTED:
6528 snprintf(evStr, EVENT_DESCR_STR_SZ,
6529 "SAS Device Status Change: Unsupported Device "
6530 "Discovered : id=%d channel=%d", id, channel);
6532 case MPI_EVENT_SAS_DEV_STAT_RC_INTERNAL_DEVICE_RESET:
6533 snprintf(evStr, EVENT_DESCR_STR_SZ,
6534 "SAS Device Status Change: Internal Device "
6535 "Reset : id=%d channel=%d", id, channel);
6537 case MPI_EVENT_SAS_DEV_STAT_RC_TASK_ABORT_INTERNAL:
6538 snprintf(evStr, EVENT_DESCR_STR_SZ,
6539 "SAS Device Status Change: Internal Task "
6540 "Abort : id=%d channel=%d", id, channel);
6542 case MPI_EVENT_SAS_DEV_STAT_RC_ABORT_TASK_SET_INTERNAL:
6543 snprintf(evStr, EVENT_DESCR_STR_SZ,
6544 "SAS Device Status Change: Internal Abort "
6545 "Task Set : id=%d channel=%d", id, channel);
6547 case MPI_EVENT_SAS_DEV_STAT_RC_CLEAR_TASK_SET_INTERNAL:
6548 snprintf(evStr, EVENT_DESCR_STR_SZ,
6549 "SAS Device Status Change: Internal Clear "
6550 "Task Set : id=%d channel=%d", id, channel);
6552 case MPI_EVENT_SAS_DEV_STAT_RC_QUERY_TASK_INTERNAL:
6553 snprintf(evStr, EVENT_DESCR_STR_SZ,
6554 "SAS Device Status Change: Internal Query "
6555 "Task : id=%d channel=%d", id, channel);
6558 snprintf(evStr, EVENT_DESCR_STR_SZ,
6559 "SAS Device Status Change: Unknown: "
6560 "id=%d channel=%d", id, channel);
6565 case MPI_EVENT_ON_BUS_TIMER_EXPIRED:
6566 ds = "Bus Timer Expired";
6568 case MPI_EVENT_QUEUE_FULL:
6570 u16 curr_depth = (u16)(evData0 >> 16);
6571 u8 channel = (u8)(evData0 >> 8);
6572 u8 id = (u8)(evData0);
6574 snprintf(evStr, EVENT_DESCR_STR_SZ,
6575 "Queue Full: channel=%d id=%d depth=%d",
6576 channel, id, curr_depth);
6579 case MPI_EVENT_SAS_SES:
6580 ds = "SAS SES Event";
6582 case MPI_EVENT_PERSISTENT_TABLE_FULL:
6583 ds = "Persistent Table Full";
6585 case MPI_EVENT_SAS_PHY_LINK_STATUS:
6587 u8 LinkRates = (u8)(evData0 >> 8);
6588 u8 PhyNumber = (u8)(evData0);
6589 LinkRates = (LinkRates & MPI_EVENT_SAS_PLS_LR_CURRENT_MASK) >>
6590 MPI_EVENT_SAS_PLS_LR_CURRENT_SHIFT;
6591 switch (LinkRates) {
6592 case MPI_EVENT_SAS_PLS_LR_RATE_UNKNOWN:
6593 snprintf(evStr, EVENT_DESCR_STR_SZ,
6594 "SAS PHY Link Status: Phy=%d:"
6595 " Rate Unknown",PhyNumber);
6597 case MPI_EVENT_SAS_PLS_LR_RATE_PHY_DISABLED:
6598 snprintf(evStr, EVENT_DESCR_STR_SZ,
6599 "SAS PHY Link Status: Phy=%d:"
6600 " Phy Disabled",PhyNumber);
6602 case MPI_EVENT_SAS_PLS_LR_RATE_FAILED_SPEED_NEGOTIATION:
6603 snprintf(evStr, EVENT_DESCR_STR_SZ,
6604 "SAS PHY Link Status: Phy=%d:"
6605 " Failed Speed Nego",PhyNumber);
6607 case MPI_EVENT_SAS_PLS_LR_RATE_SATA_OOB_COMPLETE:
6608 snprintf(evStr, EVENT_DESCR_STR_SZ,
6609 "SAS PHY Link Status: Phy=%d:"
6610 " Sata OOB Completed",PhyNumber);
6612 case MPI_EVENT_SAS_PLS_LR_RATE_1_5:
6613 snprintf(evStr, EVENT_DESCR_STR_SZ,
6614 "SAS PHY Link Status: Phy=%d:"
6615 " Rate 1.5 Gbps",PhyNumber);
6617 case MPI_EVENT_SAS_PLS_LR_RATE_3_0:
6618 snprintf(evStr, EVENT_DESCR_STR_SZ,
6619 "SAS PHY Link Status: Phy=%d:"
6620 " Rate 3.0 Gpbs",PhyNumber);
6623 snprintf(evStr, EVENT_DESCR_STR_SZ,
6624 "SAS PHY Link Status: Phy=%d", PhyNumber);
6629 case MPI_EVENT_SAS_DISCOVERY_ERROR:
6630 ds = "SAS Discovery Error";
6632 case MPI_EVENT_IR_RESYNC_UPDATE:
6634 u8 resync_complete = (u8)(evData0 >> 16);
6635 snprintf(evStr, EVENT_DESCR_STR_SZ,
6636 "IR Resync Update: Complete = %d:",resync_complete);
6641 u8 ReasonCode = (u8)(evData0 >> 16);
6642 switch (ReasonCode) {
6643 case MPI_EVENT_IR2_RC_LD_STATE_CHANGED:
6644 ds = "IR2: LD State Changed";
6646 case MPI_EVENT_IR2_RC_PD_STATE_CHANGED:
6647 ds = "IR2: PD State Changed";
6649 case MPI_EVENT_IR2_RC_BAD_BLOCK_TABLE_FULL:
6650 ds = "IR2: Bad Block Table Full";
6652 case MPI_EVENT_IR2_RC_PD_INSERTED:
6653 ds = "IR2: PD Inserted";
6655 case MPI_EVENT_IR2_RC_PD_REMOVED:
6656 ds = "IR2: PD Removed";
6658 case MPI_EVENT_IR2_RC_FOREIGN_CFG_DETECTED:
6659 ds = "IR2: Foreign CFG Detected";
6661 case MPI_EVENT_IR2_RC_REBUILD_MEDIUM_ERROR:
6662 ds = "IR2: Rebuild Medium Error";
6670 case MPI_EVENT_SAS_DISCOVERY:
6673 ds = "SAS Discovery: Start";
6675 ds = "SAS Discovery: Stop";
6678 case MPI_EVENT_LOG_ENTRY_ADDED:
6679 ds = "SAS Log Entry Added";
6682 case MPI_EVENT_SAS_BROADCAST_PRIMITIVE:
6684 u8 phy_num = (u8)(evData0);
6685 u8 port_num = (u8)(evData0 >> 8);
6686 u8 port_width = (u8)(evData0 >> 16);
6687 u8 primative = (u8)(evData0 >> 24);
6688 snprintf(evStr, EVENT_DESCR_STR_SZ,
6689 "SAS Broadcase Primative: phy=%d port=%d "
6690 "width=%d primative=0x%02x",
6691 phy_num, port_num, port_width, primative);
6695 case MPI_EVENT_SAS_INIT_DEVICE_STATUS_CHANGE:
6697 u8 reason = (u8)(evData0);
6698 u8 port_num = (u8)(evData0 >> 8);
6699 u16 handle = le16_to_cpu(evData0 >> 16);
6701 snprintf(evStr, EVENT_DESCR_STR_SZ,
6702 "SAS Initiator Device Status Change: reason=0x%02x "
6703 "port=%d handle=0x%04x",
6704 reason, port_num, handle);
6708 case MPI_EVENT_SAS_INIT_TABLE_OVERFLOW:
6710 u8 max_init = (u8)(evData0);
6711 u8 current_init = (u8)(evData0 >> 8);
6713 snprintf(evStr, EVENT_DESCR_STR_SZ,
6714 "SAS Initiator Device Table Overflow: max initiators=%02d "
6715 "current initators=%02d",
6716 max_init, current_init);
6719 case MPI_EVENT_SAS_SMP_ERROR:
6721 u8 status = (u8)(evData0);
6722 u8 port_num = (u8)(evData0 >> 8);
6723 u8 result = (u8)(evData0 >> 16);
6725 if (status == MPI_EVENT_SAS_SMP_FUNCTION_RESULT_VALID)
6726 snprintf(evStr, EVENT_DESCR_STR_SZ,
6727 "SAS SMP Error: port=%d result=0x%02x",
6729 else if (status == MPI_EVENT_SAS_SMP_CRC_ERROR)
6730 snprintf(evStr, EVENT_DESCR_STR_SZ,
6731 "SAS SMP Error: port=%d : CRC Error",
6733 else if (status == MPI_EVENT_SAS_SMP_TIMEOUT)
6734 snprintf(evStr, EVENT_DESCR_STR_SZ,
6735 "SAS SMP Error: port=%d : Timeout",
6737 else if (status == MPI_EVENT_SAS_SMP_NO_DESTINATION)
6738 snprintf(evStr, EVENT_DESCR_STR_SZ,
6739 "SAS SMP Error: port=%d : No Destination",
6741 else if (status == MPI_EVENT_SAS_SMP_BAD_DESTINATION)
6742 snprintf(evStr, EVENT_DESCR_STR_SZ,
6743 "SAS SMP Error: port=%d : Bad Destination",
6746 snprintf(evStr, EVENT_DESCR_STR_SZ,
6747 "SAS SMP Error: port=%d : status=0x%02x",
6753 * MPT base "custom" events may be added here...
6760 strncpy(evStr, ds, EVENT_DESCR_STR_SZ);
6763 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6765 * ProcessEventNotification - Route EventNotificationReply to all event handlers
6766 * @ioc: Pointer to MPT_ADAPTER structure
6767 * @pEventReply: Pointer to EventNotification reply frame
6768 * @evHandlers: Pointer to integer, number of event handlers
6770 * Routes a received EventNotificationReply to all currently registered
6772 * Returns sum of event handlers return values.
6775 ProcessEventNotification(MPT_ADAPTER *ioc, EventNotificationReply_t *pEventReply, int *evHandlers)
6784 char evStr[EVENT_DESCR_STR_SZ];
6788 * Do platform normalization of values
6790 event = le32_to_cpu(pEventReply->Event) & 0xFF;
6791 // evCtx = le32_to_cpu(pEventReply->EventContext);
6792 evDataLen = le16_to_cpu(pEventReply->EventDataLength);
6794 evData0 = le32_to_cpu(pEventReply->Data[0]);
6797 EventDescriptionStr(event, evData0, evStr);
6798 devtprintk(ioc, printk(MYIOC_s_DEBUG_FMT "MPT event:(%02Xh) : %s\n",
6803 #ifdef CONFIG_FUSION_LOGGING
6804 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6805 ": Event data:\n", ioc->name));
6806 for (ii = 0; ii < evDataLen; ii++)
6807 devtverboseprintk(ioc, printk(" %08x",
6808 le32_to_cpu(pEventReply->Data[ii])));
6809 devtverboseprintk(ioc, printk("\n"));
6813 * Do general / base driver event processing
6816 case MPI_EVENT_EVENT_CHANGE: /* 0A */
6818 u8 evState = evData0 & 0xFF;
6820 /* CHECKME! What if evState unexpectedly says OFF (0)? */
6822 /* Update EventState field in cached IocFacts */
6823 if (ioc->facts.Function) {
6824 ioc->facts.EventState = evState;
6828 case MPI_EVENT_INTEGRATED_RAID:
6829 mptbase_raid_process_event_data(ioc,
6830 (MpiEventDataRaid_t *)pEventReply->Data);
6837 * Should this event be logged? Events are written sequentially.
6838 * When buffer is full, start again at the top.
6840 if (ioc->events && (ioc->eventTypes & ( 1 << event))) {
6843 idx = ioc->eventContext % MPTCTL_EVENT_LOG_SIZE;
6845 ioc->events[idx].event = event;
6846 ioc->events[idx].eventContext = ioc->eventContext;
6848 for (ii = 0; ii < 2; ii++) {
6850 ioc->events[idx].data[ii] = le32_to_cpu(pEventReply->Data[ii]);
6852 ioc->events[idx].data[ii] = 0;
6855 ioc->eventContext++;
6860 * Call each currently registered protocol event handler.
6862 for (cb_idx = MPT_MAX_PROTOCOL_DRIVERS-1; cb_idx; cb_idx--) {
6863 if (MptEvHandlers[cb_idx]) {
6864 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Routing Event to event handler #%d\n",
6865 ioc->name, cb_idx));
6866 r += (*(MptEvHandlers[cb_idx]))(ioc, pEventReply);
6870 /* FIXME? Examine results here? */
6873 * If needed, send (a single) EventAck.
6875 if (pEventReply->AckRequired == MPI_EVENT_NOTIFICATION_ACK_REQUIRED) {
6876 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT
6877 "EventAck required\n",ioc->name));
6878 if ((ii = SendEventAck(ioc, pEventReply)) != 0) {
6879 devtverboseprintk(ioc, printk(MYIOC_s_DEBUG_FMT "SendEventAck returned %d\n",
6884 *evHandlers = handlers;
6888 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6890 * mpt_fc_log_info - Log information returned from Fibre Channel IOC.
6891 * @ioc: Pointer to MPT_ADAPTER structure
6892 * @log_info: U32 LogInfo reply word from the IOC
6894 * Refer to lsi/mpi_log_fc.h.
6897 mpt_fc_log_info(MPT_ADAPTER *ioc, u32 log_info)
6899 char *desc = "unknown";
6901 switch (log_info & 0xFF000000) {
6902 case MPI_IOCLOGINFO_FC_INIT_BASE:
6903 desc = "FCP Initiator";
6905 case MPI_IOCLOGINFO_FC_TARGET_BASE:
6906 desc = "FCP Target";
6908 case MPI_IOCLOGINFO_FC_LAN_BASE:
6911 case MPI_IOCLOGINFO_FC_MSG_BASE:
6912 desc = "MPI Message Layer";
6914 case MPI_IOCLOGINFO_FC_LINK_BASE:
6917 case MPI_IOCLOGINFO_FC_CTX_BASE:
6918 desc = "Context Manager";
6920 case MPI_IOCLOGINFO_FC_INVALID_FIELD_BYTE_OFFSET:
6921 desc = "Invalid Field Offset";
6923 case MPI_IOCLOGINFO_FC_STATE_CHANGE:
6924 desc = "State Change Info";
6928 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): SubClass={%s}, Value=(0x%06x)\n",
6929 ioc->name, log_info, desc, (log_info & 0xFFFFFF));
6932 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
6934 * mpt_spi_log_info - Log information returned from SCSI Parallel IOC.
6935 * @ioc: Pointer to MPT_ADAPTER structure
6936 * @mr: Pointer to MPT reply frame
6937 * @log_info: U32 LogInfo word from the IOC
6939 * Refer to lsi/sp_log.h.
6942 mpt_spi_log_info(MPT_ADAPTER *ioc, u32 log_info)
6944 u32 info = log_info & 0x00FF0000;
6945 char *desc = "unknown";
6949 desc = "bug! MID not found";
6950 if (ioc->reload_fw == 0)
6955 desc = "Parity Error";
6959 desc = "ASYNC Outbound Overrun";
6963 desc = "SYNC Offset Error";
6971 desc = "Msg In Overflow";
6979 desc = "Outbound DMA Overrun";
6983 desc = "Task Management";
6987 desc = "Device Problem";
6991 desc = "Invalid Phase Change";
6995 desc = "Untagged Table Size";
7000 printk(MYIOC_s_INFO_FMT "LogInfo(0x%08x): F/W: %s\n", ioc->name, log_info, desc);
7003 /* strings for sas loginfo */
7004 static char *originator_str[] = {
7009 static char *iop_code_str[] = {
7011 "Invalid SAS Address", /* 01h */
7013 "Invalid Page", /* 03h */
7014 "Diag Message Error", /* 04h */
7015 "Task Terminated", /* 05h */
7016 "Enclosure Management", /* 06h */
7017 "Target Mode" /* 07h */
7019 static char *pl_code_str[] = {
7021 "Open Failure", /* 01h */
7022 "Invalid Scatter Gather List", /* 02h */
7023 "Wrong Relative Offset or Frame Length", /* 03h */
7024 "Frame Transfer Error", /* 04h */
7025 "Transmit Frame Connected Low", /* 05h */
7026 "SATA Non-NCQ RW Error Bit Set", /* 06h */
7027 "SATA Read Log Receive Data Error", /* 07h */
7028 "SATA NCQ Fail All Commands After Error", /* 08h */
7029 "SATA Error in Receive Set Device Bit FIS", /* 09h */
7030 "Receive Frame Invalid Message", /* 0Ah */
7031 "Receive Context Message Valid Error", /* 0Bh */
7032 "Receive Frame Current Frame Error", /* 0Ch */
7033 "SATA Link Down", /* 0Dh */
7034 "Discovery SATA Init W IOS", /* 0Eh */
7035 "Config Invalid Page", /* 0Fh */
7036 "Discovery SATA Init Timeout", /* 10h */
7039 "IO Not Yet Executed", /* 13h */
7040 "IO Executed", /* 14h */
7041 "Persistent Reservation Out Not Affiliation "
7043 "Open Transmit DMA Abort", /* 16h */
7044 "IO Device Missing Delay Retry", /* 17h */
7045 "IO Cancelled Due to Recieve Error", /* 18h */
7053 "Enclosure Management" /* 20h */
7055 static char *ir_code_str[] = {
7056 "Raid Action Error", /* 00h */
7066 static char *raid_sub_code_str[] = {
7068 "Volume Creation Failed: Data Passed too "
7070 "Volume Creation Failed: Duplicate Volumes "
7071 "Attempted", /* 02h */
7072 "Volume Creation Failed: Max Number "
7073 "Supported Volumes Exceeded", /* 03h */
7074 "Volume Creation Failed: DMA Error", /* 04h */
7075 "Volume Creation Failed: Invalid Volume Type", /* 05h */
7076 "Volume Creation Failed: Error Reading "
7077 "MFG Page 4", /* 06h */
7078 "Volume Creation Failed: Creating Internal "
7079 "Structures", /* 07h */
7088 "Activation failed: Already Active Volume", /* 10h */
7089 "Activation failed: Unsupported Volume Type", /* 11h */
7090 "Activation failed: Too Many Active Volumes", /* 12h */
7091 "Activation failed: Volume ID in Use", /* 13h */
7092 "Activation failed: Reported Failure", /* 14h */
7093 "Activation failed: Importing a Volume", /* 15h */
7104 "Phys Disk failed: Too Many Phys Disks", /* 20h */
7105 "Phys Disk failed: Data Passed too Large", /* 21h */
7106 "Phys Disk failed: DMA Error", /* 22h */
7107 "Phys Disk failed: Invalid <channel:id>", /* 23h */
7108 "Phys Disk failed: Creating Phys Disk Config "
7121 "Compatibility Error: IR Disabled", /* 30h */
7122 "Compatibility Error: Inquiry Comand Failed", /* 31h */
7123 "Compatibility Error: Device not Direct Access "
7124 "Device ", /* 32h */
7125 "Compatibility Error: Removable Device Found", /* 33h */
7126 "Compatibility Error: Device SCSI Version not "
7127 "2 or Higher", /* 34h */
7128 "Compatibility Error: SATA Device, 48 BIT LBA "
7129 "not Supported", /* 35h */
7130 "Compatibility Error: Device doesn't have "
7131 "512 Byte Block Sizes", /* 36h */
7132 "Compatibility Error: Volume Type Check Failed", /* 37h */
7133 "Compatibility Error: Volume Type is "
7134 "Unsupported by FW", /* 38h */
7135 "Compatibility Error: Disk Drive too Small for "
7136 "use in Volume", /* 39h */
7137 "Compatibility Error: Phys Disk for Create "
7138 "Volume not Found", /* 3Ah */
7139 "Compatibility Error: Too Many or too Few "
7140 "Disks for Volume Type", /* 3Bh */
7141 "Compatibility Error: Disk stripe Sizes "
7142 "Must be 64KB", /* 3Ch */
7143 "Compatibility Error: IME Size Limited to < 2TB", /* 3Dh */
7146 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7148 * mpt_sas_log_info - Log information returned from SAS IOC.
7149 * @ioc: Pointer to MPT_ADAPTER structure
7150 * @log_info: U32 LogInfo reply word from the IOC
7152 * Refer to lsi/mpi_log_sas.h.
7155 mpt_sas_log_info(MPT_ADAPTER *ioc, u32 log_info)
7157 union loginfo_type {
7166 union loginfo_type sas_loginfo;
7167 char *originator_desc = NULL;
7168 char *code_desc = NULL;
7169 char *sub_code_desc = NULL;
7171 sas_loginfo.loginfo = log_info;
7172 if ((sas_loginfo.dw.bus_type != 3 /*SAS*/) &&
7173 (sas_loginfo.dw.originator < sizeof(originator_str)/sizeof(char*)))
7176 originator_desc = originator_str[sas_loginfo.dw.originator];
7178 switch (sas_loginfo.dw.originator) {
7181 if (sas_loginfo.dw.code <
7182 sizeof(iop_code_str)/sizeof(char*))
7183 code_desc = iop_code_str[sas_loginfo.dw.code];
7186 if (sas_loginfo.dw.code <
7187 sizeof(pl_code_str)/sizeof(char*))
7188 code_desc = pl_code_str[sas_loginfo.dw.code];
7191 if (sas_loginfo.dw.code >=
7192 sizeof(ir_code_str)/sizeof(char*))
7194 code_desc = ir_code_str[sas_loginfo.dw.code];
7195 if (sas_loginfo.dw.subcode >=
7196 sizeof(raid_sub_code_str)/sizeof(char*))
7198 if (sas_loginfo.dw.code == 0)
7200 raid_sub_code_str[sas_loginfo.dw.subcode];
7206 if (sub_code_desc != NULL)
7207 printk(MYIOC_s_INFO_FMT
7208 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7210 ioc->name, log_info, originator_desc, code_desc,
7212 else if (code_desc != NULL)
7213 printk(MYIOC_s_INFO_FMT
7214 "LogInfo(0x%08x): Originator={%s}, Code={%s},"
7215 " SubCode(0x%04x)\n",
7216 ioc->name, log_info, originator_desc, code_desc,
7217 sas_loginfo.dw.subcode);
7219 printk(MYIOC_s_INFO_FMT
7220 "LogInfo(0x%08x): Originator={%s}, Code=(0x%02x),"
7221 " SubCode(0x%04x)\n",
7222 ioc->name, log_info, originator_desc,
7223 sas_loginfo.dw.code, sas_loginfo.dw.subcode);
7226 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7228 * mpt_iocstatus_info_config - IOCSTATUS information for config pages
7229 * @ioc: Pointer to MPT_ADAPTER structure
7230 * @ioc_status: U32 IOCStatus word from IOC
7231 * @mf: Pointer to MPT request frame
7233 * Refer to lsi/mpi.h.
7236 mpt_iocstatus_info_config(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7238 Config_t *pReq = (Config_t *)mf;
7239 char extend_desc[EVENT_DESCR_STR_SZ];
7244 if (pReq->Header.PageType == MPI_CONFIG_PAGETYPE_EXTENDED)
7245 page_type = pReq->ExtPageType;
7247 page_type = pReq->Header.PageType;
7250 * ignore invalid page messages for GET_NEXT_HANDLE
7252 form = le32_to_cpu(pReq->PageAddress);
7253 if (ioc_status == MPI_IOCSTATUS_CONFIG_INVALID_PAGE) {
7254 if (page_type == MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE ||
7255 page_type == MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER ||
7256 page_type == MPI_CONFIG_EXTPAGETYPE_ENCLOSURE) {
7257 if ((form >> MPI_SAS_DEVICE_PGAD_FORM_SHIFT) ==
7258 MPI_SAS_DEVICE_PGAD_FORM_GET_NEXT_HANDLE)
7261 if (page_type == MPI_CONFIG_PAGETYPE_FC_DEVICE)
7262 if ((form & MPI_FC_DEVICE_PGAD_FORM_MASK) ==
7263 MPI_FC_DEVICE_PGAD_FORM_NEXT_DID)
7267 snprintf(extend_desc, EVENT_DESCR_STR_SZ,
7268 "type=%02Xh, page=%02Xh, action=%02Xh, form=%08Xh",
7269 page_type, pReq->Header.PageNumber, pReq->Action, form);
7271 switch (ioc_status) {
7273 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7274 desc = "Config Page Invalid Action";
7277 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7278 desc = "Config Page Invalid Type";
7281 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7282 desc = "Config Page Invalid Page";
7285 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7286 desc = "Config Page Invalid Data";
7289 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7290 desc = "Config Page No Defaults";
7293 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7294 desc = "Config Page Can't Commit";
7301 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s: %s\n",
7302 ioc->name, ioc_status, desc, extend_desc));
7306 * mpt_iocstatus_info - IOCSTATUS information returned from IOC.
7307 * @ioc: Pointer to MPT_ADAPTER structure
7308 * @ioc_status: U32 IOCStatus word from IOC
7309 * @mf: Pointer to MPT request frame
7311 * Refer to lsi/mpi.h.
7314 mpt_iocstatus_info(MPT_ADAPTER *ioc, u32 ioc_status, MPT_FRAME_HDR *mf)
7316 u32 status = ioc_status & MPI_IOCSTATUS_MASK;
7321 /****************************************************************************/
7322 /* Common IOCStatus values for all replies */
7323 /****************************************************************************/
7325 case MPI_IOCSTATUS_INVALID_FUNCTION: /* 0x0001 */
7326 desc = "Invalid Function";
7329 case MPI_IOCSTATUS_BUSY: /* 0x0002 */
7333 case MPI_IOCSTATUS_INVALID_SGL: /* 0x0003 */
7334 desc = "Invalid SGL";
7337 case MPI_IOCSTATUS_INTERNAL_ERROR: /* 0x0004 */
7338 desc = "Internal Error";
7341 case MPI_IOCSTATUS_RESERVED: /* 0x0005 */
7345 case MPI_IOCSTATUS_INSUFFICIENT_RESOURCES: /* 0x0006 */
7346 desc = "Insufficient Resources";
7349 case MPI_IOCSTATUS_INVALID_FIELD: /* 0x0007 */
7350 desc = "Invalid Field";
7353 case MPI_IOCSTATUS_INVALID_STATE: /* 0x0008 */
7354 desc = "Invalid State";
7357 /****************************************************************************/
7358 /* Config IOCStatus values */
7359 /****************************************************************************/
7361 case MPI_IOCSTATUS_CONFIG_INVALID_ACTION: /* 0x0020 */
7362 case MPI_IOCSTATUS_CONFIG_INVALID_TYPE: /* 0x0021 */
7363 case MPI_IOCSTATUS_CONFIG_INVALID_PAGE: /* 0x0022 */
7364 case MPI_IOCSTATUS_CONFIG_INVALID_DATA: /* 0x0023 */
7365 case MPI_IOCSTATUS_CONFIG_NO_DEFAULTS: /* 0x0024 */
7366 case MPI_IOCSTATUS_CONFIG_CANT_COMMIT: /* 0x0025 */
7367 mpt_iocstatus_info_config(ioc, status, mf);
7370 /****************************************************************************/
7371 /* SCSIIO Reply (SPI, FCP, SAS) initiator values */
7373 /* Look at mptscsih_iocstatus_info_scsiio in mptscsih.c */
7375 /****************************************************************************/
7377 case MPI_IOCSTATUS_SCSI_RECOVERED_ERROR: /* 0x0040 */
7378 case MPI_IOCSTATUS_SCSI_DATA_UNDERRUN: /* 0x0045 */
7379 case MPI_IOCSTATUS_SCSI_INVALID_BUS: /* 0x0041 */
7380 case MPI_IOCSTATUS_SCSI_INVALID_TARGETID: /* 0x0042 */
7381 case MPI_IOCSTATUS_SCSI_DEVICE_NOT_THERE: /* 0x0043 */
7382 case MPI_IOCSTATUS_SCSI_DATA_OVERRUN: /* 0x0044 */
7383 case MPI_IOCSTATUS_SCSI_IO_DATA_ERROR: /* 0x0046 */
7384 case MPI_IOCSTATUS_SCSI_PROTOCOL_ERROR: /* 0x0047 */
7385 case MPI_IOCSTATUS_SCSI_TASK_TERMINATED: /* 0x0048 */
7386 case MPI_IOCSTATUS_SCSI_RESIDUAL_MISMATCH: /* 0x0049 */
7387 case MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED: /* 0x004A */
7388 case MPI_IOCSTATUS_SCSI_IOC_TERMINATED: /* 0x004B */
7389 case MPI_IOCSTATUS_SCSI_EXT_TERMINATED: /* 0x004C */
7392 /****************************************************************************/
7393 /* SCSI Target values */
7394 /****************************************************************************/
7396 case MPI_IOCSTATUS_TARGET_PRIORITY_IO: /* 0x0060 */
7397 desc = "Target: Priority IO";
7400 case MPI_IOCSTATUS_TARGET_INVALID_PORT: /* 0x0061 */
7401 desc = "Target: Invalid Port";
7404 case MPI_IOCSTATUS_TARGET_INVALID_IO_INDEX: /* 0x0062 */
7405 desc = "Target Invalid IO Index:";
7408 case MPI_IOCSTATUS_TARGET_ABORTED: /* 0x0063 */
7409 desc = "Target: Aborted";
7412 case MPI_IOCSTATUS_TARGET_NO_CONN_RETRYABLE: /* 0x0064 */
7413 desc = "Target: No Conn Retryable";
7416 case MPI_IOCSTATUS_TARGET_NO_CONNECTION: /* 0x0065 */
7417 desc = "Target: No Connection";
7420 case MPI_IOCSTATUS_TARGET_XFER_COUNT_MISMATCH: /* 0x006A */
7421 desc = "Target: Transfer Count Mismatch";
7424 case MPI_IOCSTATUS_TARGET_STS_DATA_NOT_SENT: /* 0x006B */
7425 desc = "Target: STS Data not Sent";
7428 case MPI_IOCSTATUS_TARGET_DATA_OFFSET_ERROR: /* 0x006D */
7429 desc = "Target: Data Offset Error";
7432 case MPI_IOCSTATUS_TARGET_TOO_MUCH_WRITE_DATA: /* 0x006E */
7433 desc = "Target: Too Much Write Data";
7436 case MPI_IOCSTATUS_TARGET_IU_TOO_SHORT: /* 0x006F */
7437 desc = "Target: IU Too Short";
7440 case MPI_IOCSTATUS_TARGET_ACK_NAK_TIMEOUT: /* 0x0070 */
7441 desc = "Target: ACK NAK Timeout";
7444 case MPI_IOCSTATUS_TARGET_NAK_RECEIVED: /* 0x0071 */
7445 desc = "Target: Nak Received";
7448 /****************************************************************************/
7449 /* Fibre Channel Direct Access values */
7450 /****************************************************************************/
7452 case MPI_IOCSTATUS_FC_ABORTED: /* 0x0066 */
7453 desc = "FC: Aborted";
7456 case MPI_IOCSTATUS_FC_RX_ID_INVALID: /* 0x0067 */
7457 desc = "FC: RX ID Invalid";
7460 case MPI_IOCSTATUS_FC_DID_INVALID: /* 0x0068 */
7461 desc = "FC: DID Invalid";
7464 case MPI_IOCSTATUS_FC_NODE_LOGGED_OUT: /* 0x0069 */
7465 desc = "FC: Node Logged Out";
7468 case MPI_IOCSTATUS_FC_EXCHANGE_CANCELED: /* 0x006C */
7469 desc = "FC: Exchange Canceled";
7472 /****************************************************************************/
7474 /****************************************************************************/
7476 case MPI_IOCSTATUS_LAN_DEVICE_NOT_FOUND: /* 0x0080 */
7477 desc = "LAN: Device not Found";
7480 case MPI_IOCSTATUS_LAN_DEVICE_FAILURE: /* 0x0081 */
7481 desc = "LAN: Device Failure";
7484 case MPI_IOCSTATUS_LAN_TRANSMIT_ERROR: /* 0x0082 */
7485 desc = "LAN: Transmit Error";
7488 case MPI_IOCSTATUS_LAN_TRANSMIT_ABORTED: /* 0x0083 */
7489 desc = "LAN: Transmit Aborted";
7492 case MPI_IOCSTATUS_LAN_RECEIVE_ERROR: /* 0x0084 */
7493 desc = "LAN: Receive Error";
7496 case MPI_IOCSTATUS_LAN_RECEIVE_ABORTED: /* 0x0085 */
7497 desc = "LAN: Receive Aborted";
7500 case MPI_IOCSTATUS_LAN_PARTIAL_PACKET: /* 0x0086 */
7501 desc = "LAN: Partial Packet";
7504 case MPI_IOCSTATUS_LAN_CANCELED: /* 0x0087 */
7505 desc = "LAN: Canceled";
7508 /****************************************************************************/
7509 /* Serial Attached SCSI values */
7510 /****************************************************************************/
7512 case MPI_IOCSTATUS_SAS_SMP_REQUEST_FAILED: /* 0x0090 */
7513 desc = "SAS: SMP Request Failed";
7516 case MPI_IOCSTATUS_SAS_SMP_DATA_OVERRUN: /* 0x0090 */
7517 desc = "SAS: SMP Data Overrun";
7528 dreplyprintk(ioc, printk(MYIOC_s_DEBUG_FMT "IOCStatus(0x%04X): %s\n",
7529 ioc->name, status, desc));
7532 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7533 EXPORT_SYMBOL(mpt_attach);
7534 EXPORT_SYMBOL(mpt_detach);
7536 EXPORT_SYMBOL(mpt_resume);
7537 EXPORT_SYMBOL(mpt_suspend);
7539 EXPORT_SYMBOL(ioc_list);
7540 EXPORT_SYMBOL(mpt_register);
7541 EXPORT_SYMBOL(mpt_deregister);
7542 EXPORT_SYMBOL(mpt_event_register);
7543 EXPORT_SYMBOL(mpt_event_deregister);
7544 EXPORT_SYMBOL(mpt_reset_register);
7545 EXPORT_SYMBOL(mpt_reset_deregister);
7546 EXPORT_SYMBOL(mpt_device_driver_register);
7547 EXPORT_SYMBOL(mpt_device_driver_deregister);
7548 EXPORT_SYMBOL(mpt_get_msg_frame);
7549 EXPORT_SYMBOL(mpt_put_msg_frame);
7550 EXPORT_SYMBOL(mpt_put_msg_frame_hi_pri);
7551 EXPORT_SYMBOL(mpt_free_msg_frame);
7552 EXPORT_SYMBOL(mpt_add_sge);
7553 EXPORT_SYMBOL(mpt_send_handshake_request);
7554 EXPORT_SYMBOL(mpt_verify_adapter);
7555 EXPORT_SYMBOL(mpt_GetIocState);
7556 EXPORT_SYMBOL(mpt_print_ioc_summary);
7557 EXPORT_SYMBOL(mpt_HardResetHandler);
7558 EXPORT_SYMBOL(mpt_config);
7559 EXPORT_SYMBOL(mpt_findImVolumes);
7560 EXPORT_SYMBOL(mpt_alloc_fw_memory);
7561 EXPORT_SYMBOL(mpt_free_fw_memory);
7562 EXPORT_SYMBOL(mptbase_sas_persist_operation);
7563 EXPORT_SYMBOL(mpt_raid_phys_disk_pg0);
7565 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7567 * fusion_init - Fusion MPT base driver initialization routine.
7569 * Returns 0 for success, non-zero for failure.
7576 show_mptmod_ver(my_NAME, my_VERSION);
7577 printk(KERN_INFO COPYRIGHT "\n");
7579 for (cb_idx = 0; cb_idx < MPT_MAX_PROTOCOL_DRIVERS; cb_idx++) {
7580 MptCallbacks[cb_idx] = NULL;
7581 MptDriverClass[cb_idx] = MPTUNKNOWN_DRIVER;
7582 MptEvHandlers[cb_idx] = NULL;
7583 MptResetHandlers[cb_idx] = NULL;
7586 /* Register ourselves (mptbase) in order to facilitate
7587 * EventNotification handling.
7589 mpt_base_index = mpt_register(mpt_base_reply, MPTBASE_DRIVER);
7591 /* Register for hard reset handling callbacks.
7593 mpt_reset_register(mpt_base_index, mpt_ioc_reset);
7595 #ifdef CONFIG_PROC_FS
7596 (void) procmpt_create();
7601 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
7603 * fusion_exit - Perform driver unload cleanup.
7605 * This routine frees all resources associated with each MPT adapter
7606 * and removes all %MPT_PROCFS_MPTBASEDIR entries.
7612 mpt_reset_deregister(mpt_base_index);
7614 #ifdef CONFIG_PROC_FS
7619 module_init(fusion_init);
7620 module_exit(fusion_exit);